13 Commits
8 changed files with 355 additions and 71 deletions

No files matched your search

+92 -1
View File
@@ -1,3 +1,94 @@
#!/usr/bin/eval bash #!/usr/bin/eval bash
# nothing to do PROTON_TARGET="/Users/hb/mnt/nas/backups/div"
PROTON_TARGET_FILE="proton_mail_pass.$EXT"
PROTON_ROOT="/Users/hb/Downloads"
PROTON_BACKUP_DIR="Proton_Backup"
PROTON_BACKUP="$PROTON_ROOT/$PROTON_BACKUP_DIR"
PROTON_MAIL_EXPORT="$PROTON_ROOT/proton-mail-export-cli"
PROTON_PASS_EXPORT="$PROTON_ROOT/Proton Pass_export"
check_proton() {
if [ ! -d "$PROTON_MAIL_EXPORT" ]; then
mail_log $ERROR "$ERR there is no Proton Mail export."
return 1
fi
# tr ist nötig, weil bei macOS führene blanks entfernt werden müssen
if [ "$(ls "$PROTON_PASS_EXPORT"*|wc -l|tr -d ' ')" != "1" ]; then
mail_log $ERROR "$ERR there is no Proton Pass export."
return 1
fi
if [ ! -d "$PROTON_TARGET" ]; then
mail_log $ERROR "$ERR could not find targe dir $PROTON_TARGET!"
return 1
fi
if [ -f "$PROTON_TARGET/$PROTON_TARGET_FILE" ]; then
log $DEBUG "$DBG > rm -f \"$PROTON_TARGET/$PROTON_TARGET_FILE\""
rm -f "$PROTON_TARGET/$PROTON_TARGET_FILE" >>$LOG_FILE 2>&1
fi
}
delete_proton_backup_dir() {
log $DEBUG "$DBG delete_proton_backup_dir()"
if [ -d "$PROTON_BACKUP" ]; then
log $DEBUG "$DBG > rm -rf \"$PROTON_BACKUP\""
rm -rf "$PROTON_BACKUP" >>$LOG_FILE 2>&1 && return 0
fi
return 1
}
create_proton_backup_dir() {
log $DEBUG "$DBG create_proton_backup_dir()"
delete_proton_backup_dir
log $DEBUG "$DBG > mkdir -p \"$PROTON_BACKUP\""
mkdir -p "$PROTON_BACKUP" >>$LOG_FILE 2>&1 && return 0
return 1
}
move_proton_exports() {
log $DEBUG "$DBG move_proton_exports()"
log $DEBUG "$DBG > mv \"$PROTON_MAIL_EXPORT\" \"$PROTON_BACKUP\""
mv "$PROTON_MAIL_EXPORT" "$PROTON_BACKUP" >>$LOG_FILE 2>&1
if [ $? -ne 0 ]; then return 1; fi
log $DEBUG "$DBG > mv \"$PROTON_PASS_EXPORT\"* \"$PROTON_BACKUP\""
mv "$PROTON_PASS_EXPORT"* "$PROTON_BACKUP" >>$LOG_FILE 2>&1
if [ $? -ne 0 ]; then return 1; fi
}
do_proton_backup() {
log $DEBUG "$DBG do_proton_backup()"
mail_log $INFO "$INF checking environment"
check_proton
is_error $? && return 1
mail_log $INFO "$INF create $PROTON_BACKUP"
create_proton_backup_dir
is_error $? && return 1
mail_log $INFO "$INF move Proton exports to source directory"
move_proton_exports
is_error $? && return 1
mail_log $INFO "$INF backing up Proton exports to $PROTON_TARGET/$PROTON_TARGET_FILE"
backup_directory "$PROTON_ROOT" "$PROTON_TARGET/$PROTON_TARGET_FILE" "$PROTON_BACKUP_DIR"
is_error $? && return 1
}
proton_backup() {
mail_log $INFO ">>>>>>>>>> Proton backup $VER at $HOST_NAME <<<<<<<<<<"
do_proton_backup
mail_log $INFO "$INF deleting $PROTON_BACKUP"
delete_proton_backup_dir
is_error $?
mail_log $DEBUG "$DBG rm -f \"$PROTON_PASS_EXPORT\"*"
mail_log $DEBUG "$(rm -f "$PROTON_PASS_EXPORT"* 2>&1)"
mail_log $INFO ">>>>>>>>>> end of Proton backup"
send_mail_log "Proton Backup"
}
Executable
+41
View File
@@ -0,0 +1,41 @@
#!/bin/bash
#
# check if container services are running
UNITS="/var/containers/systemd"
FAILED=""
check_service() {
local service=$1
systemctl is-active --user --machine=container@ $service >/dev/null
if [ $? -ne 0 ]; then
FAILED="$FAILED $service"
fi
}
check() {
local type=$1
for i in $UNITS/$type/*.socket; do
check_service $(basename $i)
done
for i in $UNITS/$type/*.container; do
check_service $(basename $i .container).service
done
}
check user
check system
if [ -z "$FAILED" ]; then
echo "OK All services are running"
exit 0
else
echo "#" >&2
echo "# ERROR some services are not running:" >&2
echo "#" >&2
echo "# $FAILED" >&2
echo "#" >&2
exit 1
fi
+1 -1
View File
@@ -3,4 +3,4 @@
HERE=$(dirname "$0") HERE=$(dirname "$0")
# local start # local start
sudo sh -c "nohup $HERE/main.sh -d </dev/null &" sudo sh -c "nohup $HERE/main.sh --dx </dev/null &"
+5 -3
View File
@@ -3,15 +3,15 @@
USER_CONTAINERS= USER_CONTAINERS=
ROOT_CONTAINERS="pihole" ROOT_CONTAINERS="pihole"
BACKUP_TARGET=/var/docker/tmp BACKUP_TARGET=/var/containers/tmp
NAS_TARGET="$NAS_ROOT/daily/$HOST_NAME/backup.$DAY" NAS_TARGET="$NAS_ROOT/daily/$HOST_NAME/backup.$DAY"
backup_daily1() { backup_daily1() {
BACKUP_SOURCE="/var" BACKUP_SOURCE="/var"
BACKUP_EXCLUDE_DIRS=(docker) BACKUP_EXCLUDE_DIRS=(containers)
} }
backup_daily2() { backup_daily2() {
BACKUP_SOURCE="/var/docker" BACKUP_SOURCE="/var/containers"
BACKUP_EXCLUDE_DIRS=(tmp) BACKUP_EXCLUDE_DIRS=(tmp)
} }
@@ -27,5 +27,7 @@ after_backup() {
let rc=rc+$? let rc=rc+$?
copy_to_nas "$BACKUP_TARGET" "$NAS_TARGET" copy_to_nas "$BACKUP_TARGET" "$NAS_TARGET"
let rc=rc+$? let rc=rc+$?
#check_services
#let rc=rc+$?
return $rc return $rc
} }
+24 -6
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# Mail via GMX-Relay versenden (Docker-Image "hb42/smtp") # Mail via GMX-Relay versenden (Podman-Image "smtp-relay")
# #
# Klappt nur direkt im Container, daher ggf. via ssh aufrufen (Annahme: remote user == local user) # Klappt nur direkt im Container, daher ggf. via ssh aufrufen (Annahme: remote user == local user)
# #
@@ -12,10 +12,15 @@
# > mail.sh hb242@pm.me "log whatever" ../log/some.log # > mail.sh hb242@pm.me "log whatever" ../log/some.log
# #
DOCKER=/usr/bin/docker PODMAN=/usr/bin/podman
MAILCONTAINER=smtp #
# -i ist entscheident, damit die restliche Kommandozeile sauber ausgewertet wird
# das ersetzt den expliziten Aufruf mit "sh -c "..." "
SUDO="sudo -u container -i"
MAILCONTAINER=smtp-relay
MAILSERVER_IP=10.4.2.30 MAILSERVER_IP=10.4.2.30
SSH="" REMOTE=""
which ip >/dev/null 2>&1 which ip >/dev/null 2>&1
if [ $? -eq 0 ]; then if [ $? -eq 0 ]; then
@@ -27,7 +32,7 @@ else
fi fi
if [ "$myip" != "$MAILSERVER_IP" ]; then if [ "$myip" != "$MAILSERVER_IP" ]; then
SSH="ssh $MAILSERVER_IP" REMOTE=yes
fi fi
TO=$1 TO=$1
@@ -41,11 +46,24 @@ if [ -z "$TO" ] || [ -z "$SUBJECT" ]; then
exit exit
fi fi
PODMANCMD="$SUDO $PODMAN"
if [ ! -z "$REMOTE" ]; then
PODMANCMD="ssh $MAILSERVER_IP $PODMANCMD"
fi
# der Mail-Container sollte laufen, falls nicht, dann ist wahrscheinlich der Backup
# noch nicht durch => 30 Minuten warten
$PODMANCMD ps | grep $MAILCONTAINER >/dev/null
if [ $? -ne 0 ]; then
sleep 30m
fi
# Mail body aus Datei oder STDIN holen # Mail body aus Datei oder STDIN holen
CONTENT=$(cat ${1:--}) CONTENT=$(cat ${1:--})
MAILCMD="$PODMANCMD exec -i $MAILCONTAINER /usr/sbin/sendmail -i -t"
# construct mail header + content and pipe to sendmail # construct mail header + content and pipe to sendmail
cat <<EOMB | $SSH $DOCKER exec -i $MAILCONTAINER /usr/sbin/sendmail -i -t cat <<EOMB | $MAILCMD
FROM: hb42@gmx.de FROM: hb42@gmx.de
TO: ${TO} TO: ${TO}
DATE: $(date -R) DATE: $(date -R)
+150 -50
View File
@@ -12,7 +12,7 @@ LOG_KEEP_DAYS=14
RESTORE_PATH="$NAS_MOUNT_POINT/Server/restore" RESTORE_PATH="$NAS_MOUNT_POINT/Server/restore"
BACKUP_MASTER_CHECK="/var/docker/vol/proxy" BACKUP_MASTER_CHECK="/var/containers/vol/caddy"
NAS_HOSTNAME=synology NAS_HOSTNAME=synology
NAS_IP=10.4.2.20 NAS_IP=10.4.2.20
@@ -22,13 +22,18 @@ PASSPHRASE=L1rfCXu8PHMQsGL0HJWwzQYpCT7f5VboislOTHMaEV
EXT=tgz.gpg EXT=tgz.gpg
LIST_EXT=list 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_USER="/usr/bin/systemctl --user --machine=container@"
SYSTEMCTL="/usr/bin/systemctl" SYSTEMCTL="/usr/bin/systemctl"
CONTAINER_EXEC_USER=" sudo -u container podman exec" PODMAN=" sudo -u container -i podman"
CONTAINER_EXEC_USER=" $PODMAN exec"
CONTAINER_SVC_UPDATE_USER=" $PODMAN auto-update"
CONTAINER_EXEC="podman exec" CONTAINER_EXEC="podman exec"
tagP1=".backup#"
tagP2=".tag"
LOG_RECIPIENT=hb242@pm.me LOG_RECIPIENT=hb242@pm.me
INFO=INFO INFO=INFO
WARN=WARN WARN=WARN
@@ -98,20 +103,20 @@ prune_logs() {
# ----- db dump ----- # ----- db dump -----
dump_mariadb() { #dump_mariadb() {
return 0 # 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"
#
log $DEBUG "$DBG > \$DOCKER exec mysql /usr/bin/mariadb --silent --user=xxx --password=xxx -e \"show databases\" -B" # log $DEBUG "$DBG > \$DOCKER exec mysql /usr/bin/mariadb --silent --user=xxx --password=xxx -e \"show databases\" -B"
for db in $($DOCKER exec mysql /usr/bin/mariadb --silent $mysqlconnect -e "show databases" -B 2>>$LOG_FILE | grep -v information_schema 2>>$LOG_FILE | grep -v performance_schema 2>>$LOG_FILE | sed -e 's/\r//' 2>>$LOG_FILE); do # for db in $($DOCKER exec mysql /usr/bin/mariadb --silent $mysqlconnect -e "show databases" -B 2>>$LOG_FILE | grep -v information_schema 2>>$LOG_FILE | grep -v performance_schema 2>>$LOG_FILE | sed -e 's/\r//' 2>>$LOG_FILE); do
log $DEBUG "$DBG > \$DOCKER exec mysql /usr/bin/mariadb-dump --hex-blob --user=xxx --password=xxx --databases $db" # log $DEBUG "$DBG > \$DOCKER exec mysql /usr/bin/mariadb-dump --hex-blob --user=xxx --password=xxx --databases $db"
$DOCKER exec mysql /usr/bin/mariadb-dump --hex-blob $mysqlconnect --databases $db >$dump_dir/$db.sql 2>>$LOG_FILE # $DOCKER exec mysql /usr/bin/mariadb-dump --hex-blob $mysqlconnect --databases $db >$dump_dir/$db.sql 2>>$LOG_FILE
is_error $? false && return 1 # is_error $? false && return 1
done # done
return 0 # return 0
} #}
dump_postgresql() { dump_postgresql() {
local pg_container=$1 local pg_container=$1
@@ -147,18 +152,31 @@ check_root() {
exit 100 exit 100
fi fi
} }
# Ausführung auf macOS begrenzen
#
check_mac() {
if [[ "$(uname)" != "Darwin" ]]; then
log $ERROR "$ERR script works only on MAC."
echo "****"
echo "***** script works only on MAC! *****"
echo "****"
exit 110
fi
}
start_containers() { start_containers() {
local let rc=0 local let rc=0
log $DEBUG "$DBG start_containers()" log $DEBUG "$DBG start_containers()"
if [ -f /var/docker/run/docker-compose.yml ]; then # if [ -f /var/docker/run/docker-compose.yml ]; then
log $DEBUG "$DBG > \$DOCKER up -d" # log $DEBUG "$DBG > \$DOCKER up -d"
$DOCKER up -d >>$LOG_FILE 2>&1 # $DOCKER up -d >>$LOG_FILE 2>&1
let rc=rc+$? # let rc=rc+$?
fi # fi
if [ -d /var/containers ]; then if [ -d /var/containers ]; then
do_start_stop_containers start do_start_stop_containers start
let rc=rc+$? let rc=rc+$?
# warten bis alle wieder da sind
sleep 2m
fi fi
return $rc return $rc
} }
@@ -166,11 +184,11 @@ start_containers() {
stop_containers() { stop_containers() {
local let rc=0 local let rc=0
log $DEBUG "$DBG stop_containers()" log $DEBUG "$DBG stop_containers()"
if [ -f /var/docker/run/docker-compose.yml ]; then # 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
let rc=rc+$? # let rc=rc+$?
fi # fi
if [ -d /var/containers ]; then if [ -d /var/containers ]; then
do_start_stop_containers stop do_start_stop_containers stop
let rc=rc+$? let rc=rc+$?
@@ -195,6 +213,44 @@ do_start_stop_containers() {
return $rc return $rc
} }
# podman auto-update nach dem Backup starten
#
# Die fn schreibt sehr viel ins Log, damit der Update ggf. nachvollzogen werden kann,
# wenn etwas daneben geht.
#
update_services() {
log $DEBUG "$DBG update_services()"
mail_log $INFO "$INF update services"
local old_img=$($PODMAN ps --filter "label=io.containers.autoupdate=registry" --format "table {{.ImageID}} {{.Names}} {{.Image}}" --sort names)
echo "$old_img" >>$LOG_FILE 2>&1
local plan=$($CONTAINER_SVC_UPDATE_USER --dry-run --format "{{.Image}} {{.Updated}}" 2>&1 | grep pending | sed 's/^\(.*\) pending/\1/')
for i in $plan; do
mail_log $INFO "$INF pending: $i"
done
local upd=$($CONTAINER_SVC_UPDATE_USER --format "table {{.Image}} {{.Updated}}" 2>&1 | tee -a $LOG_FILE | grep true | sed 's/^\(.*\) true/\1/')
check_pipe_rc ${PIPESTATUS[@]}
local rc=$?
for i in $upd; do
mail_log $INFO "$INF updated: $i"
done
# warten bis alle wieder da sind (wg. ps)
sleep 2m >>$LOG_FILE 2>&1
local new_img=$($PODMAN ps --filter "label=io.containers.autoupdate=registry" --format "table {{.ImageID}} {{.Names}} {{.Image}}" --sort names)
echo "$new_img" >>$LOG_FILE 2>&1
# diff output bring zu wenig
#log $DEBUG "$DBG diff before after"
#local diff_img=$(diff <(echo "$old_img") <(echo "$new_img"))
#echo "$diff_img" >> $LOG_FILE
return $rc
}
check_services() {
log $DEBUG "$DBG check_services()"
mail_log $INFO "$INF check services"
$HERE/check.sh >>$LOG_FILE 2>&1
return $?
}
# Zugriffsrechte für Logs und Backups setzen # Zugriffsrechte für Logs und Backups setzen
# #
fix_acls() { fix_acls() {
@@ -389,7 +445,29 @@ backup_all_dirs() {
for dir in $(iterate_dirs_in "$root" "$@"); do for dir in $(iterate_dirs_in "$root" "$@"); do
tar_file="$target/$prefix-$dir.$EXT" tar_file="$target/$prefix-$dir.$EXT"
backup_dir "$root" "$tar_file" "$dir" backup_directory "$root" "$tar_file" "$dir"
if [ $? -ne 0 ]; then return 1; fi
done
return 0
}
# Einzelnes Verzeichnis sichern und Backup prüfen
#
# $1 - Pfad zum Verzeichnis, das gesichert werden soll
# $2 - Zielpfad und -name für das Archiv
# $2 - zu sicherndes Verzeichnis
#
# returns 0 for success, 1 otherwise
#
backup_directory() {
log $DEBUG "$DBG backup_directory( $@ )"
local root=$1
local tar_file=$2
local dir=$3
tar_dir "$root" "$tar_file" "$dir"
if [ $? -ne 0 ]; then return 1; fi if [ $? -ne 0 ]; then return 1; fi
create_list "$tar_file" "$dir" create_list "$tar_file" "$dir"
@@ -397,25 +475,28 @@ backup_all_dirs() {
test_integrity "$tar_file" test_integrity "$tar_file"
if [ $? -ne 0 ]; then return 1; fi if [ $? -ne 0 ]; then return 1; fi
done
return 0
} }
# Einzelnes Verzeichnis sichern. # Einzelnes Verzeichnis sichern.
# #
# $1 - Pfad um Verzeichnis, das gesichert werden soll # $1 - Pfad zum Verzeichnis, das gesichert werden soll
# $2 - Zielpfad und -name für das Archiv # $2 - Zielpfad und -name für das Archiv
# $2 - zu sicherndes Verzeichnis # $2 - zu sicherndes Verzeichnis
# #
# returns 0 for success, 1 otherwise # returns 0 for success, 1 otherwise
# #
backup_dir() { tar_dir() {
log $DEBUG "$DBG backup_dir( $@ )" log $DEBUG "$DBG tar_dir( $@ )"
local root=$1 local root=$1
local archive=$2 local archive=$2
local dir=$3 local dir=$3
log $DEBUG "$DBG > tar -c -z --numeric-owner --one-file-system --exclude \"@eaDir\" -C \"$root\" \"$dir\" | gpg --batch -c --passphrase xxxx -o \"$archive\"" local sort=--sort=name
tar -c -z --numeric-owner --one-file-system --exclude "@eaDir" -C "$root" "$dir" 2>>$LOG_FILE | gpg --batch -c --passphrase $PASSPHRASE -o "$archive" 2>>$LOG_FILE if [[ "$(uname)" == "Darwin" ]]; then
sort=""
fi
log $DEBUG "$DBG > tar -c -z --numeric-owner --one-file-system $sort --exclude \"@eaDir\" -C \"$root\" \"$dir\" | gpg --batch -c --passphrase xxxx -o \"$archive\""
tar -c -z --numeric-owner --one-file-system $sort --exclude "@eaDir" -C "$root" "$dir" 2>>$LOG_FILE | gpg --batch -c --passphrase $PASSPHRASE -o "$archive" 2>>$LOG_FILE
check_pipe_rc ${PIPESTATUS[@]} check_pipe_rc ${PIPESTATUS[@]}
return $? return $?
} }
@@ -474,11 +555,11 @@ set_log_info() {
mail_log $INFO ">>> " mail_log $INFO ">>> "
} }
backup_daily() { cron_backup_daily() {
# "master"-Server startet Backup auf NAS # "master"-Server startet Backup auf NAS
if [ -d $BACKUP_MASTER_CHECK ]; then if [ -d $BACKUP_MASTER_CHECK ]; then
log $DEBUG "$DBG starting daily backup on $NAS_HOSTNAME" log $DEBUG "$DBG starting daily backup on $NAS_HOSTNAME"
run_script_remote $NAS_IP "$NAS_SCRIPT -d" run_script_remote $NAS_IP "$NAS_SCRIPT --dx"
# alte Logs löschen (nur auf einem Server ausführen) # alte Logs löschen (nur auf einem Server ausführen)
prune_logs prune_logs
@@ -491,6 +572,10 @@ backup_daily() {
nohup $THIS_SCRIPT -w >>$LOG_FILE 2>&1 </dev/null & nohup $THIS_SCRIPT -w >>$LOG_FILE 2>&1 </dev/null &
fi fi
backup_daily
}
backup_daily() {
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
@@ -621,7 +706,7 @@ list_archives() {
local target=$1 local target=$1
local targ=${NAS_ROOT//\//\\\/} # slashes escapen local targ=${NAS_ROOT//\//\\\/} # slashes escapen
log $DEBUG "$DBG > find \"$NAS_ROOT\" -type f -name \"*.$EXT\" | sed -E \"s/^$targ//\"" 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 find "$NAS_ROOT" -type f -name "*.$EXT" 2>>$LOG_FILE | sed -E "s/^$targ//" 2>>$LOG_FILE | sort
check_pipe_rc ${PIPESTATUS[@]} check_pipe_rc ${PIPESTATUS[@]}
return $? return $?
} }
@@ -713,8 +798,8 @@ mount_usb_device() {
fi fi
} }
# Check if auto mounted device is exfat and return mount point # Check if auto mounted device is exfat or vfat and return mount point
# (fn for consitence with linux fn) # (fn for consistence with linux fn)
# #
# $1 - device name # $1 - device name
# returns mount point # returns mount point
@@ -724,7 +809,7 @@ mount_usb_device_syno() {
local device=$1 local device=$1
log $DEBUG "$DBG > $SYNO_USB -info $device | grep -i \"file system\" | sed -E \"s/.*:\s*(.*)\s*/\1/\"" log $DEBUG "$DBG > $SYNO_USB -info $device | grep -i \"file system\" | sed -E \"s/.*:\s*(.*)\s*/\1/\""
local fs=$($SYNO_USB -info $device 2>>$LOG_FILE | grep -i "file system" 2>>$LOG_FILE | sed -E "s/.*:\s*(.*)\s*/\1/" 2>>$LOG_FILE) local fs=$($SYNO_USB -info $device 2>>$LOG_FILE | grep -i "file system" 2>>$LOG_FILE | sed -E "s/.*:\s*(.*)\s*/\1/" 2>>$LOG_FILE)
if [ "$fs" != "exfat" ]; then if [ "$fs" != "exfat" && "$fs" != "vfat" ]; then
mail_log $ERROR "$ERR device $device not exfat formatted." mail_log $ERROR "$ERR device $device not exfat formatted."
return 1 return 1
fi fi
@@ -735,6 +820,7 @@ mount_usb_device_syno() {
mail_log $ERROR "$ERR mount point \"$mount_point\" does not exist." mail_log $ERROR "$ERR mount point \"$mount_point\" does not exist."
return 1 return 1
fi fi
mount_point=$(check_syno_mount_point $mount_point)
echo $mount_point echo $mount_point
return 0 return 0
} }
@@ -799,6 +885,28 @@ umount_usb_device_linux() {
return $? return $?
} }
# Mit GUID-Partitontable meldet Synology die falsche Partition (/volumeUSB1/usbshare1-1)
# zusätzlich auf ggf. vorhandener 2. Partition (*1-2) suchen
#
# $1 - mount point
#
check_syno_mount_point() {
log $DEBUG "$DBG check_syno_mount_point( $@ )"
local mount_point=$1
log $DEBUG "$DBG > ls $mount_point/${tagP1}*${tagP2} | wc -l"
if [ "$(ls $mount_point/${tagP1}*${tagP2} 2>>$LOG_FILE | wc -l 2>>$LOG_FILE)" != "1" ]; then
log $DEBUG "No tag at mount point \"$mount_point\". Checking next partiton."
mount_point=$(echo $mount_point | sed -E "s/(.*1)-1/\1-2/")
if [ "$(ls $mount_point/${tagP1}*${tagP2} 2>>$LOG_FILE | wc -l 2>>$LOG_FILE)" != "1" ]; then
mail_log $ERROR "$ERR no tag found on device at $mount_point."
return 1
fi
fi
echo $mount_point
}
# USB-HDD suchen und Backup-Typ ermitteln # USB-HDD suchen und Backup-Typ ermitteln
# #
# Der Typ wird über eine Datei auf der USB-HDD festgelegt: # Der Typ wird über eine Datei auf der USB-HDD festgelegt:
@@ -809,19 +917,11 @@ umount_usb_device_linux() {
check_backup_device() { check_backup_device() {
log $DEBUG "$DBG check_backup_drive( $@ )" log $DEBUG "$DBG check_backup_drive( $@ )"
local mount_point=$1 local mount_point=$1
local tagP1=".backup#"
local tagP2=".tag"
log $DEBUG "$DBG > ls $mount_point/${tagP1}*${tagP2} | wc -l"
if [ "$(ls $mount_point/${tagP1}*${tagP2} 2>>$LOG_FILE | wc -l 2>>$LOG_FILE)" != "1" ]; then
mail_log $ERROR "$ERR no tag found on device at $mount_point."
return 1
fi
log $DEBUG "$DBG > ls $mount_point/${tagP1}*${tagP2} | sed -E \"s/.*$tagP1(.*)$tagP2/\1/\"" log $DEBUG "$DBG > ls $mount_point/${tagP1}*${tagP2} | sed -E \"s/.*$tagP1(.*)$tagP2/\1/\""
local tag=$(ls $mount_point/${tagP1}*${tagP2} 2>>$LOG_FILE | sed -E "s/.*$tagP1(.*)$tagP2/\1/" 2>>$LOG_FILE) local tag=$(ls $mount_point/${tagP1}*${tagP2} 2>>$LOG_FILE | sed -E "s/.*$tagP1(.*)$tagP2/\1/" 2>>$LOG_FILE)
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
mail_log $ERROR "$ERR no tag found on device at $mount_point." mail_log $ERROR "$ERR no valid tag found on device at $mount_point."
return 1 return 1
fi fi
echo $tag echo $tag
+29 -2
View File
@@ -3,14 +3,28 @@
# entrypoint for all actions # entrypoint for all actions
# #
# 2.111 05.05.2025 - Fix DB-Dump # 2.3.1. 16.08.2025 - 30 min delay for mail.sh
# 2.3.0 12.08.2025 - new function for backup & encryption of Proton exports
# 2.2.4 30.07.2025 - inc delay (again) for container startup-check (2m)
# 2.2.3 24.06.2025 - Export-Disk kann exfat- oder vfat-formatiert sein,
# Export-Disk mit mehreren Partitonen erkennen
# 2.2.2 19.06.2025 - inc delay for container startup check, fix error in log output
# 2.2.1 16.06.2025 - delay container startup check
# 2.2.0 16.05.2025 - fixes for auto-update, podman migration done
# 2.1.17 11.05.2025 - bugfixes, sort tar archive, split daily/cron daily
# 2.1.16 10.05.2025 - fix mail.sh, log results of auto-update
# 2.1.15 09.05.2025 - podman auto-update
# 2.1.14 09.05.2025 - Fix mail.sh, homeserver.target, cleared all docker references
# 2.1.13 08.05.2025 - check if services are running after backup
# 2.1.12 08.05.2025 - mail.sh an neuen Container angepasst
# 2.1.11 05.05.2025 - Fix DB-Dump
# 2.1.10 05.05.2025 - Postgres-Dump auf podman umgestellt # 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.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.8 30.04.2025 - systemctl start/stop eingebaut
# 2.1.7 29.04.2025 - 1. Schritt zur Umstellung auf podman # 2.1.7 29.04.2025 - 1. Schritt zur Umstellung auf podman
# 2.1.6 29.04.2025 - weekly backup Sa->SO # 2.1.6 29.04.2025 - weekly backup Sa->SO
VER="2.1.10" VER="2.3.1"
HERE=$(dirname "$0") HERE=$(dirname "$0")
THIS_SCRIPT=$0 THIS_SCRIPT=$0
@@ -26,6 +40,7 @@ show_help() {
echo " show contents of archive (path from $NAS_ROOT)" echo " show contents of archive (path from $NAS_ROOT)"
echo ' -r, --restore <archive> <file(s)> ' echo ' -r, --restore <archive> <file(s)> '
echo " restore files from archive to $RESTORE_PATH" echo " restore files from archive to $RESTORE_PATH"
echo " -p, --proton backup and encrypt Proton exports (MacBook only)"
echo " -h, -?. --help show this help" echo " -h, -?. --help show this help"
echo " " echo " "
echo " -d, -w, -e must be run as superuser." echo " -d, -w, -e must be run as superuser."
@@ -64,6 +79,12 @@ while :; do
show_help # Display a usage synopsis. show_help # Display a usage synopsis.
exit 0 exit 0
;; ;;
--dx)
MAIL_LOG_FILE="${log_file_name}.auto.log"
check_root
cron_backup_daily
break
;;
-d|--daily) -d|--daily)
MAIL_LOG_FILE="${log_file_name}.auto.log" MAIL_LOG_FILE="${log_file_name}.auto.log"
check_root check_root
@@ -115,6 +136,12 @@ while :; do
do_restore $@ do_restore $@
break break
;; ;;
-p|--proton)
MAIL_LOG_FILE="${log_file_name}.proton.log"
check_mac
proton_backup
break
;;
--) # End of all options. --) # End of all options.
shift shift
break break
+13 -8
View File
@@ -1,24 +1,25 @@
#!/usr/bin/env bash #!/usr/bin/env bash
USER_CONTAINERS="homeassistant-pod codeserver jellyfin pgadmin nextcloud-pod calibre nexus git-pod caddy.socket caddy" USER_CONTAINERS="homeserver.target"
ROOT_CONTAINERS= ROOT_CONTAINERS=
DOCKER_ROOT=/var/docker #DOCKER_ROOT=/var/docker
BACKUP_TARGET=$DOCKER_ROOT/tmp CONTAINERS_ROOT=/var/containers
BACKUP_TARGET=$CONTAINERS_ROOT/tmp
NAS_TARGET="$NAS_ROOT/daily/$HOST_NAME/backup.$DAY" NAS_TARGET="$NAS_ROOT/daily/$HOST_NAME/backup.$DAY"
backup_daily1() { backup_daily1() {
BACKUP_SOURCE="/var" BACKUP_SOURCE="/var"
BACKUP_EXCLUDE_DIRS=(docker) BACKUP_EXCLUDE_DIRS=(containers)
} }
backup_daily2() { backup_daily2() {
BACKUP_SOURCE="/var/docker" BACKUP_SOURCE="/var/containers"
BACKUP_EXCLUDE_DIRS=(vol tmp) BACKUP_EXCLUDE_DIRS=(vol tmp)
} }
backup_daily3() { backup_daily3() {
BACKUP_SOURCE="/var/docker/vol" BACKUP_SOURCE="/var/containers/vol"
BACKUP_EXCLUDE_DIRS=() BACKUP_EXCLUDE_DIRS=()
} }
@@ -27,9 +28,9 @@ before_backup() {
let local rc=0 let local rc=0
#dump_mariadb $DOCKER_ROOT/dump/mysql #dump_mariadb $DOCKER_ROOT/dump/mysql
#let rc=rc+$? #let rc=rc+$?
dump_postgresql ncd_pg $DOCKER_ROOT/dump/nextcloud dump_postgresql ncd_pg $CONTAINERS_ROOT/dump/nextcloud
let rc=rc+$? let rc=rc+$?
dump_postgresql gitea_pg $DOCKER_ROOT/dump/gitea dump_postgresql gitea_pg $CONTAINERS_ROOT/dump/gitea
let rc=rc+$? let rc=rc+$?
if [ $rc -gt 0 ]; then if [ $rc -gt 0 ]; then
return 1 return 1
@@ -44,5 +45,9 @@ after_backup() {
let rc=rc+$? let rc=rc+$?
copy_to_nas "$BACKUP_TARGET" "$NAS_TARGET" copy_to_nas "$BACKUP_TARGET" "$NAS_TARGET"
let rc=rc+$? let rc=rc+$?
update_services
let rc=rc+$?
check_services
let rc=rc+$?
return $rc return $rc
} }