Update external-backup.sh
This commit is contained in:
parent
dc9985bed3
commit
4bbff4ba6f
1 changed files with 57 additions and 66 deletions
|
@ -1,16 +1,16 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
#
|
#
|
||||||
# Script zieht per rsync Backups und rotiert Backup-Verzeichnisse
|
# Script rotiert Backup-Verzeichnisse und zieht per rsync Backups
|
||||||
|
# http://www.heinlein-support.de
|
||||||
#
|
#
|
||||||
# https://www.heinlein-support.de/howto/backups-und-snapshots-von-linux-servern-mit-rsync-und-ssh
|
# https://www.heinlein-support.de/howto/backups-und-snapshots-von-linux-servern-mit-rsync-und-ssh
|
||||||
#
|
#
|
||||||
# Zusammengeführt und angepasst durch Tobias Strobel (2021)
|
# Zusammengeführt und angepasst durch Tobias Strobel (2021)
|
||||||
#
|
#
|
||||||
|
|
||||||
RDIFFEXIT="$(mktemp)"
|
LOGFILE="$(mktemp)"
|
||||||
GOTIFYURL="https://push.strobeto.de/message?token=Anks7VaBnyf7jCB"
|
GOTIFYURL="https://push.strobeto.de/message?token=Anks7VaBnyf7jCB"
|
||||||
HCBACKUPURL="https://hc.strobeto.de/ping/375f20ea-aaa7-4b34-b279-bafc3ff55fed"
|
HCURL="https://hc.strobeto.de/ping/615c0b9b-077d-46b4-913b-b70d911dab27"
|
||||||
HCROTATEURL="https://hc.strobeto.de/ping/f169adf0-a1b3-4823-8fb6-f3a63546bb42"
|
|
||||||
|
|
||||||
SERVER="$(hostname)"
|
SERVER="$(hostname)"
|
||||||
|
|
||||||
|
@ -39,26 +39,23 @@ clearLED () {
|
||||||
|
|
||||||
finishUp () {
|
finishUp () {
|
||||||
# Clean up tempfiles
|
# Clean up tempfiles
|
||||||
rm "$RDIFFEXIT"
|
rm "$LOGFILE"
|
||||||
|
# Just to be sure
|
||||||
sync -f $DATA_PATH
|
sync -f $DATA_PATH
|
||||||
}
|
}
|
||||||
|
|
||||||
healthchecksStart () {
|
healthchecksStart () {
|
||||||
# $1 Healthchecks URL
|
curl -fsS -m 10 --retry 5 -o /dev/null "$HCURL"/start
|
||||||
curl -fsS -m 10 --retry 5 -o /dev/null "$1"/start
|
|
||||||
}
|
}
|
||||||
|
|
||||||
healthchecksFinish () {
|
healthchecksFinish () {
|
||||||
# $1 Healthchecks URL
|
# $1 Status Code
|
||||||
# $2 Status Code
|
curl -fsS -m 10 --retry 5 -o /dev/null --data-binary "@$LOGFILE" "$HCURL"/"$1"
|
||||||
# $3 Logs
|
|
||||||
curl -fsS -m 10 --retry 5 --data-raw "$3" "$1"/"$2"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
notify () {
|
notify () {
|
||||||
# $1 Action
|
# $1 Action
|
||||||
# $2 Last command succeeded
|
# $2 Status code
|
||||||
# $3 Custom Title
|
# $3 Custom Title
|
||||||
# $4 Custom Message
|
# $4 Custom Message
|
||||||
# $5 Custom Priority
|
# $5 Custom Priority
|
||||||
|
@ -67,39 +64,21 @@ notify () {
|
||||||
NOTIFY_PRIORITY=1
|
NOTIFY_PRIORITY=1
|
||||||
case "$1" in
|
case "$1" in
|
||||||
|
|
||||||
rotate-start)
|
start)
|
||||||
NOTIFY_TITLE+="Rotation started"
|
|
||||||
NOTIFY_MESSAGE="Rotation on external hdd started"
|
|
||||||
;;
|
|
||||||
|
|
||||||
rotate-end)
|
|
||||||
if [ "$2" -eq 0 ]; then
|
|
||||||
NOTIFY_TITLE+="Rotation finished"
|
|
||||||
NOTIFY_MESSAGE="Rotation on external hdd finished"
|
|
||||||
NOTIFY_PRIORITY=5
|
|
||||||
else
|
|
||||||
NOTIFY_TITLE+="Rotation has ERRORS"
|
|
||||||
NOTIFY_MESSAGE="Exit code $STATUSCODE. See logs attached to healthchecks for more information."
|
|
||||||
NOTIFY_PRIORITY=8
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
|
|
||||||
backup-start)
|
|
||||||
NOTIFY_TITLE+="Backup started"
|
NOTIFY_TITLE+="Backup started"
|
||||||
NOTIFY_MESSAGE="Backup to external hdd started"
|
NOTIFY_MESSAGE="Backup to external hdd started"
|
||||||
;;
|
;;
|
||||||
|
|
||||||
backup-end)
|
finish)
|
||||||
if [ "$2" -eq 0 ]; then
|
NOTIFY_TITLE+="Backup finished"
|
||||||
NOTIFY_TITLE+="Backup finished"
|
NOTIFY_MESSAGE="Backup to external hdd finished"
|
||||||
NOTIFY_MESSAGE="Backup to external hdd finished"
|
NOTIFY_PRIORITY=5
|
||||||
NOTIFY_PRIORITY=5
|
|
||||||
else
|
|
||||||
NOTIFY_TITLE+="Backup has ERRORS"
|
|
||||||
NOTIFY_MESSAGE="Exit code $STATUSCODE. See logs attached to healthchecks for more information."
|
|
||||||
NOTIFY_PRIORITY=8
|
|
||||||
fi
|
|
||||||
;;
|
;;
|
||||||
|
error)
|
||||||
|
NOTIFY_TITLE+="Backup has ERRORS"
|
||||||
|
NOTIFY_MESSAGE="Exit code $STATUSCODE. See logs attached to healthchecks for more information."
|
||||||
|
NOTIFY_PRIORITY=8
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
NOTIFY_TITLE+="$3"
|
NOTIFY_TITLE+="$3"
|
||||||
NOTIFY_MESSAGE="$4"
|
NOTIFY_MESSAGE="$4"
|
||||||
|
@ -107,7 +86,7 @@ notify () {
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
curl "$GOTIFYURL" -F "title=$NOTIFY_TITLE" -F "message=$NOTIFY_MESSAGE" -F "priority=$NOTIFY_PRIORITY"
|
curl -fsS -m 10 --retry 5 -o /dev/null "$GOTIFYURL" -F "title=$NOTIFY_TITLE" -F "message=$NOTIFY_MESSAGE" -F "priority=$NOTIFY_PRIORITY"
|
||||||
}
|
}
|
||||||
|
|
||||||
checkFreeSpace () {
|
checkFreeSpace () {
|
||||||
|
@ -118,7 +97,8 @@ INODEISFREE=$(df -i /$DATA_PATH | tail -n1 | sed -e "$GETPERCENTAGE")
|
||||||
|
|
||||||
if [ "$KBISFREE" -ge $HDMINFREE ] || [ "$INODEISFREE" -ge $HDMINFREE ] ; then
|
if [ "$KBISFREE" -ge $HDMINFREE ] || [ "$INODEISFREE" -ge $HDMINFREE ] ; then
|
||||||
echo "Fatal: Not enough space left for rotating backups!"
|
echo "Fatal: Not enough space left for rotating backups!"
|
||||||
logger "Fatal: Not enough space left for rotating backups!"
|
healthchecksFinish fail
|
||||||
|
notify custom "NOT_ENOUGH_SPACE_LEFT" "FATAL" "Not enough space left for rotating backups!"
|
||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
@ -126,7 +106,8 @@ fi
|
||||||
basicChecks () {
|
basicChecks () {
|
||||||
if ! [ -d $DATA_PATH ] ; then
|
if ! [ -d $DATA_PATH ] ; then
|
||||||
echo "Fatal: Data path does not exist: $DATA_PATH"
|
echo "Fatal: Data path does not exist: $DATA_PATH"
|
||||||
logger "Fatal: Data path does not exist: $DATA_PATH"
|
healthchecksFinish fail
|
||||||
|
notify custom "DATA_PATH_NON_EXISTENT" "FATAL" "Data path does not exist: $DATA_PATH"
|
||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -134,14 +115,12 @@ basicChecks () {
|
||||||
|
|
||||||
# Ggf. Verzeichnis anlegen
|
# Ggf. Verzeichnis anlegen
|
||||||
if ! [ -d $DATA_PATH/"$SERVER"/daily.0 ] ; then
|
if ! [ -d $DATA_PATH/"$SERVER"/daily.0 ] ; then
|
||||||
mkdir -p $DATA_PATH/"$SERVER"/daily.0
|
mkdir -p $DATA_PATH/"$SERVER"/daily.0
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
rotate () {
|
rotate () {
|
||||||
echo "Rotating snapshots of $SERVER..."
|
echo "Rotating snapshots of $SERVER..."
|
||||||
healthchecksStart $HCROTATEURL
|
|
||||||
notify rotate-start
|
|
||||||
|
|
||||||
# Das hoechste Snapshot abloeschen
|
# Das hoechste Snapshot abloeschen
|
||||||
if [ -d $DATA_PATH/"$SERVER"/daily.7 ] ; then
|
if [ -d $DATA_PATH/"$SERVER"/daily.7 ] ; then
|
||||||
|
@ -149,9 +128,9 @@ rotate () {
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Alle anderen Snapshots eine Nummer nach oben verschieben
|
# Alle anderen Snapshots eine Nummer nach oben verschieben
|
||||||
for OLD in 6 5 4 3 2 1 ; do
|
for OLD in 12 11 10 9 8 7 6 5 4 3 2 1 ; do
|
||||||
if [ -d $DATA_PATH/"$SERVER"/daily.$OLD ] ; then
|
if [ -d $DATA_PATH/"$SERVER"/daily.$OLD ] ; then
|
||||||
NEW=$($OLD + 1)
|
NEW=$(( OLD + 1 ))
|
||||||
# Datum sichern
|
# Datum sichern
|
||||||
touch $DATA_PATH/.timestamp -r $DATA_PATH/"$SERVER"/daily.$OLD
|
touch $DATA_PATH/.timestamp -r $DATA_PATH/"$SERVER"/daily.$OLD
|
||||||
mv $DATA_PATH/"$SERVER"/daily.$OLD $DATA_PATH/"$SERVER"/daily."$NEW"
|
mv $DATA_PATH/"$SERVER"/daily.$OLD $DATA_PATH/"$SERVER"/daily."$NEW"
|
||||||
|
@ -162,50 +141,62 @@ rotate () {
|
||||||
|
|
||||||
# Snapshot von Level-0 per hardlink-Kopie nach Level-1 kopieren
|
# Snapshot von Level-0 per hardlink-Kopie nach Level-1 kopieren
|
||||||
if [ -d $DATA_PATH/"$SERVER"/daily.0 ] ; then
|
if [ -d $DATA_PATH/"$SERVER"/daily.0 ] ; then
|
||||||
ROTATELOG=$(cp -al $DATA_PATH/"$SERVER"/daily.0 $DATA_PATH/"$SERVER"/daily.1; echo $? > "$RDIFFEXIT")
|
cp -al $DATA_PATH/"$SERVER"/daily.0 $DATA_PATH/"$SERVER"/daily.1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
STATUSCODE=$(cat "$RDIFFEXIT")
|
STATUSCODE=$?
|
||||||
|
|
||||||
|
if [ "$STATUSCODE" -ne 0 ] ; then
|
||||||
|
echo "Fatal: rotation finished on $SERVER with errors!"
|
||||||
|
healthchecksFinish "$STATUSCODE"
|
||||||
|
notify error "$STATUSCODE"
|
||||||
|
exit "$STATUSCODE"
|
||||||
|
fi
|
||||||
|
|
||||||
echo "Finished rotating backups of $SERVER..."
|
echo "Finished rotating backups of $SERVER..."
|
||||||
healthchecksFinish $HCROTATEURL "$STATUSCODE" "$ROTATELOG"
|
healthchecksFinish "$STATUSCODE"
|
||||||
notify rotate-end "$STATUSCODE"
|
notify error "$STATUSCODE"
|
||||||
}
|
}
|
||||||
|
|
||||||
backup () {
|
backup () {
|
||||||
# Los geht`s: rsync zieht ein Vollbackup
|
|
||||||
echo "Starting rsync backup from $SERVER..."
|
echo "Starting rsync backup from $SERVER..."
|
||||||
healthchecksStart $HCBACKUPURL
|
|
||||||
notify backup-start
|
|
||||||
|
|
||||||
BACKUPLOG=$(rsync -avz --numeric-ids -e ssh --delete --delete-excluded \
|
rsync -aAXHh --stats --numeric-ids --noatime --delete --delete-excluded \
|
||||||
--include={"/mnt/storage/nc_data","/mnt/storage/media","/mnt/storage/backup"} \
|
--include={"/mnt/storage","/mnt/storage/nc_data**","/mnt/storage/media**","/mnt/storage/backup**"} \
|
||||||
--exclude={"/dev/*","/proc/*","/sys/*","/tmp/*","/run/*","/mnt/*","/media/*","/lost+found","/.snapshots"} \
|
--exclude={"/dev/*","/proc/*","/sys/*","/tmp/*","/run/*","/mnt/*","/media/*","/lost+found","/.snapshots"} \
|
||||||
$SRC_PATH $DATA_PATH/"$SERVER"/daily.0 \
|
$SRC_PATH $DATA_PATH/"$SERVER"/daily.0
|
||||||
; echo $? > "$RDIFFEXIT")
|
|
||||||
|
|
||||||
STATUSCODE=$(cat "$RDIFFEXIT")
|
STATUSCODE=$?
|
||||||
|
|
||||||
# Rückgabewert prüfen.
|
# Rückgabewert prüfen.
|
||||||
# 0 = fehlerfrei,
|
# 0 = fehlerfrei,
|
||||||
# 24 ist harmlos; tritt auf, wenn während der Laufzeit
|
# 24 ist harmlos; tritt auf, wenn während der Laufzeit
|
||||||
# von rsync noch (/tmp?) Dateien verändert oder gelöscht wurden.
|
# von rsync noch (/tmp?) Dateien verändert oder gelöscht wurden.
|
||||||
# Alles andere ist fatal -- siehe man (1) rsync
|
# Alles andere ist fatal -- siehe man (1) rsync
|
||||||
if ! [ "$STATUSCODE" = 24 ] || ! [ "$STATUSCODE" = 0 ] ; then
|
if [ "$STATUSCODE" -ne 24 ] && [ "$STATUSCODE" -ne 0 ] ; then
|
||||||
echo "Fatal: rsync finished $SERVER with errors!"
|
echo "Fatal: rsync finished on $SERVER with errors!"
|
||||||
|
healthchecksFinish "$STATUSCODE"
|
||||||
|
notify error "$STATUSCODE"
|
||||||
|
exit "$STATUSCODE"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Verzeichnis anfassen, um Backup-Datum zu speichern
|
# Verzeichnis anfassen, um Backup-Datum zu speichern
|
||||||
touch $DATA_PATH/"$SERVER"/daily.0
|
touch $DATA_PATH/"$SERVER"/daily.0
|
||||||
|
|
||||||
echo "Finished rsync backup from $SERVER..."
|
echo "Finished rsync backup from $SERVER..."
|
||||||
healthchecksFinish $HCBACKUPURL "$STATUSCODE" "$BACKUPLOG"
|
|
||||||
notify backup-end "$STATUSCODE"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Write output to logfile
|
||||||
|
exec > >(tee -i "${LOGFILE}")
|
||||||
|
exec 2>&1
|
||||||
|
|
||||||
|
healthchecksStart
|
||||||
|
notify start
|
||||||
setLED
|
setLED
|
||||||
basicChecks
|
basicChecks
|
||||||
backup
|
backup
|
||||||
rotate
|
rotate
|
||||||
|
healthchecksFinish
|
||||||
|
notify finish 0
|
||||||
finishUp
|
finishUp
|
||||||
clearLED
|
clearLED
|
Loading…
Reference in a new issue