Add helios/external-backups.sh
This commit is contained in:
parent
d29058a02d
commit
dc9985bed3
1 changed files with 211 additions and 0 deletions
211
helios/external-backup.sh
Normal file
211
helios/external-backup.sh
Normal file
|
@ -0,0 +1,211 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Script zieht per rsync Backups und rotiert Backup-Verzeichnisse
|
||||
#
|
||||
# https://www.heinlein-support.de/howto/backups-und-snapshots-von-linux-servern-mit-rsync-und-ssh
|
||||
#
|
||||
# Zusammengeführt und angepasst durch Tobias Strobel (2021)
|
||||
#
|
||||
|
||||
RDIFFEXIT="$(mktemp)"
|
||||
GOTIFYURL="https://push.strobeto.de/message?token=Anks7VaBnyf7jCB"
|
||||
HCBACKUPURL="https://hc.strobeto.de/ping/375f20ea-aaa7-4b34-b279-bafc3ff55fed"
|
||||
HCROTATEURL="https://hc.strobeto.de/ping/f169adf0-a1b3-4823-8fb6-f3a63546bb42"
|
||||
|
||||
SERVER="$(hostname)"
|
||||
|
||||
# ### Konfiguration
|
||||
# Sollen wir pruefen, ob noch ein gewisser Prozentsatz
|
||||
# an Plattenplatz und Inodes frei ist?
|
||||
HDMINFREE=90
|
||||
|
||||
# Welcher Pfad soll gesichert werden?
|
||||
SRC_PATH=/
|
||||
|
||||
# Unter welchem Pfad wird gesichert?
|
||||
DATA_PATH=/mnt/backupone
|
||||
|
||||
setLED () {
|
||||
# Set LED status
|
||||
echo heartbeat > "/sys/class/leds/helios64:blue:usb3/trigger"
|
||||
echo 1 > "/sys/class/leds/helios64:blue:usb3/brightness"
|
||||
}
|
||||
|
||||
clearLED () {
|
||||
# Clear LED status
|
||||
echo usbport > "/sys/class/leds/helios64:blue:usb3/trigger"
|
||||
echo 0 > "/sys/class/leds/helios64:blue:usb3/brightness"
|
||||
}
|
||||
|
||||
finishUp () {
|
||||
# Clean up tempfiles
|
||||
rm "$RDIFFEXIT"
|
||||
|
||||
sync -f $DATA_PATH
|
||||
}
|
||||
|
||||
healthchecksStart () {
|
||||
# $1 Healthchecks URL
|
||||
curl -fsS -m 10 --retry 5 -o /dev/null "$1"/start
|
||||
}
|
||||
|
||||
healthchecksFinish () {
|
||||
# $1 Healthchecks URL
|
||||
# $2 Status Code
|
||||
# $3 Logs
|
||||
curl -fsS -m 10 --retry 5 --data-raw "$3" "$1"/"$2"
|
||||
}
|
||||
|
||||
notify () {
|
||||
# $1 Action
|
||||
# $2 Last command succeeded
|
||||
# $3 Custom Title
|
||||
# $4 Custom Message
|
||||
# $5 Custom Priority
|
||||
NOTIFY_TITLE="[$SERVER] "
|
||||
NOTIFY_MESSAGE=""
|
||||
NOTIFY_PRIORITY=1
|
||||
case "$1" in
|
||||
|
||||
rotate-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_MESSAGE="Backup to external hdd started"
|
||||
;;
|
||||
|
||||
backup-end)
|
||||
if [ "$2" -eq 0 ]; then
|
||||
NOTIFY_TITLE+="Backup finished"
|
||||
NOTIFY_MESSAGE="Backup to external hdd finished"
|
||||
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
|
||||
;;
|
||||
*)
|
||||
NOTIFY_TITLE+="$3"
|
||||
NOTIFY_MESSAGE="$4"
|
||||
NOTIFY_PRIORITY="$5"
|
||||
;;
|
||||
esac
|
||||
|
||||
curl "$GOTIFYURL" -F "title=$NOTIFY_TITLE" -F "message=$NOTIFY_MESSAGE" -F "priority=$NOTIFY_PRIORITY"
|
||||
}
|
||||
|
||||
checkFreeSpace () {
|
||||
# Pruefe auf freien Plattenplatz
|
||||
GETPERCENTAGE='s/.* \([0-9]\{1,3\}\)%.*/\1/'
|
||||
KBISFREE=$(df /$DATA_PATH | tail -n1 | sed -e "$GETPERCENTAGE")
|
||||
INODEISFREE=$(df -i /$DATA_PATH | tail -n1 | sed -e "$GETPERCENTAGE")
|
||||
|
||||
if [ "$KBISFREE" -ge $HDMINFREE ] || [ "$INODEISFREE" -ge $HDMINFREE ] ; then
|
||||
echo "Fatal: Not enough space left for rotating backups!"
|
||||
logger "Fatal: Not enough space left for rotating backups!"
|
||||
exit
|
||||
fi
|
||||
}
|
||||
|
||||
basicChecks () {
|
||||
if ! [ -d $DATA_PATH ] ; then
|
||||
echo "Fatal: Data path does not exist: $DATA_PATH"
|
||||
logger "Fatal: Data path does not exist: $DATA_PATH"
|
||||
exit
|
||||
fi
|
||||
|
||||
checkFreeSpace
|
||||
|
||||
# Ggf. Verzeichnis anlegen
|
||||
if ! [ -d $DATA_PATH/"$SERVER"/daily.0 ] ; then
|
||||
mkdir -p $DATA_PATH/"$SERVER"/daily.0
|
||||
fi
|
||||
}
|
||||
|
||||
rotate () {
|
||||
echo "Rotating snapshots of $SERVER..."
|
||||
healthchecksStart $HCROTATEURL
|
||||
notify rotate-start
|
||||
|
||||
# Das hoechste Snapshot abloeschen
|
||||
if [ -d $DATA_PATH/"$SERVER"/daily.7 ] ; then
|
||||
rm -rf $DATA_PATH/"$SERVER"/daily.7
|
||||
fi
|
||||
|
||||
# Alle anderen Snapshots eine Nummer nach oben verschieben
|
||||
for OLD in 6 5 4 3 2 1 ; do
|
||||
if [ -d $DATA_PATH/"$SERVER"/daily.$OLD ] ; then
|
||||
NEW=$($OLD + 1)
|
||||
# Datum sichern
|
||||
touch $DATA_PATH/.timestamp -r $DATA_PATH/"$SERVER"/daily.$OLD
|
||||
mv $DATA_PATH/"$SERVER"/daily.$OLD $DATA_PATH/"$SERVER"/daily."$NEW"
|
||||
# Datum zurueckspielen
|
||||
touch $DATA_PATH/"$SERVER"/daily."$NEW" -r $DATA_PATH/.timestamp
|
||||
fi
|
||||
done
|
||||
|
||||
# Snapshot von Level-0 per hardlink-Kopie nach Level-1 kopieren
|
||||
if [ -d $DATA_PATH/"$SERVER"/daily.0 ] ; then
|
||||
ROTATELOG=$(cp -al $DATA_PATH/"$SERVER"/daily.0 $DATA_PATH/"$SERVER"/daily.1; echo $? > "$RDIFFEXIT")
|
||||
fi
|
||||
|
||||
STATUSCODE=$(cat "$RDIFFEXIT")
|
||||
|
||||
echo "Finished rotating backups of $SERVER..."
|
||||
healthchecksFinish $HCROTATEURL "$STATUSCODE" "$ROTATELOG"
|
||||
notify rotate-end "$STATUSCODE"
|
||||
}
|
||||
|
||||
backup () {
|
||||
# Los geht`s: rsync zieht ein Vollbackup
|
||||
echo "Starting rsync backup from $SERVER..."
|
||||
healthchecksStart $HCBACKUPURL
|
||||
notify backup-start
|
||||
|
||||
BACKUPLOG=$(rsync -avz --numeric-ids -e ssh --delete --delete-excluded \
|
||||
--include={"/mnt/storage/nc_data","/mnt/storage/media","/mnt/storage/backup"} \
|
||||
--exclude={"/dev/*","/proc/*","/sys/*","/tmp/*","/run/*","/mnt/*","/media/*","/lost+found","/.snapshots"} \
|
||||
$SRC_PATH $DATA_PATH/"$SERVER"/daily.0 \
|
||||
; echo $? > "$RDIFFEXIT")
|
||||
|
||||
STATUSCODE=$(cat "$RDIFFEXIT")
|
||||
|
||||
# Rückgabewert prüfen.
|
||||
# 0 = fehlerfrei,
|
||||
# 24 ist harmlos; tritt auf, wenn während der Laufzeit
|
||||
# von rsync noch (/tmp?) Dateien verändert oder gelöscht wurden.
|
||||
# Alles andere ist fatal -- siehe man (1) rsync
|
||||
if ! [ "$STATUSCODE" = 24 ] || ! [ "$STATUSCODE" = 0 ] ; then
|
||||
echo "Fatal: rsync finished $SERVER with errors!"
|
||||
fi
|
||||
|
||||
# Verzeichnis anfassen, um Backup-Datum zu speichern
|
||||
touch $DATA_PATH/"$SERVER"/daily.0
|
||||
|
||||
echo "Finished rsync backup from $SERVER..."
|
||||
healthchecksFinish $HCBACKUPURL "$STATUSCODE" "$BACKUPLOG"
|
||||
notify backup-end "$STATUSCODE"
|
||||
}
|
||||
|
||||
setLED
|
||||
basicChecks
|
||||
backup
|
||||
rotate
|
||||
finishUp
|
||||
clearLED
|
Loading…
Reference in a new issue