Created
August 29, 2020 10:30
-
-
Save novoid/21dd371d4489fe550c0168ddbb4039f1 to your computer and use it in GitHub Desktop.
Backup shell script using rsnapshot (rsync)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
## My one and only backup script for the future :-) | |
## Uses rsnapshot. | |
## | |
## Please do read this blog article about that script: https://Karl-Voit.at/2020/08/29/vkbackup/ | |
## | |
## --------------------------------------------------- | |
## | |
## Initial setup: | |
## 1. install and setup http://rsnapshot.org/ | |
## 2. install and setup https://github.com/novoid/appendorgheading | |
## 3. install and setup notify-send (I'm using Debian, so it's "sudo apt install notify-send") | |
## 4. install and setup grml-crypt from https://grml.org/ (makes LUKS much easier to use) | |
## 5. replace "user" with your user name. | |
## 6. adapt the complete configuration setting below with BACKUPNAME, UUID, REFILE_ORGFILE, REFILE_HEADING | |
## 7. adapt all paths to tools and log files and such: "hostname", ... | |
## 8. create and check mountpoints | |
## 9. create and check LUKS target partitions: grml-crypt from https://grml.org/ is awesome! | |
## 10. add the executable flag to this script: chmod +x vkbackup | |
## 11. this shell script has minimal error detection: so please make sure you understand the script and | |
## test it with test data before you use it in a real-life scenario. | |
## 12. make a test-run and test restore ;-) | |
## | |
## --------------------------------------------------- | |
## | |
## Adding a new backup disk: | |
## 1. Find out UUID of LUKS device and add to script | |
## 2. Define unique BACKUPNAME, an refile-target org mode file name and heading titla (not ID) and add to script | |
## 3. Adapt /home/user/archive/backup/hostname/rsnapshot_${BACKUPNAME}.conf | |
## 4. Adapt /home/user/archive/backup/hostname/rsnapshot_exclude_file_${BACKUPNAME}.txt | |
## | |
## --------------------------------------------------- | |
## | |
## Run a backup: | |
## 1. Plug in physical HDD (which is LUKS encypted) | |
## 2. start "vkbackup" as root | |
## 3. enter LUKS passphrase | |
## 4. <wait for end of backup run> (pay attention to the desktop notification) | |
## 5. if no error appeared, umount was successful and HDD can be unplugged | |
## | |
## Creates log output in: /home/user/log/vkbackup-hostname-${BACKUPNAME}.log | |
## | |
## --------------------------------------------------- | |
## | |
## Manually mounting: (using grml-crypt; if you don't use grml-crypt, you have to look up all the steps yourself) | |
## 1. grml-crypt start /dev/disk/by-uuid/${UUID} "${MOUNTPOINT}" | |
## | |
## --------------------------------------------------- | |
## | |
## Manually umounting: (using grml-crypt; if you don't use grml-crypt, you have to look up all the steps yourself) | |
## 1. grml-crypt stop ${MOUNTPOINT} | |
## | |
set -o nounset | |
set -o errexit | |
if [ -b /dev/disk/by-uuid/12345678cc-8103-4900-abcde-987654321 ]; then | |
BACKUPNAME="1TBbackup" ## shortname of the backup (better omit spaces and special characters) | |
UUID="12345678cc-8103-4900-abcde-987654321" ## UUID of the backup disk volume | |
REFILE_ORGFILE="misc.org" ## Org mode file to re-file to | |
REFILE_HEADING="Backup: 1TBbackup (Off-site-backup)" ## Org mode heading title to re-file to | |
elif [ -b /dev/disk/by-uuid/ababababab-1234-4b39-8233-9182737465 ]; then | |
BACKUPNAME="4TBbackup" | |
UUID="ababababab-1234-4b39-8233-9182737465" | |
REFILE_ORGFILE="misc.org" | |
REFILE_HEADING="Backup: My 4T Bbackup" | |
## TEMPLATE: | |
# elif [ -b /dev/disk/by-uuid/ ]; then | |
# BACKUPNAME="" | |
# UUID="" | |
# REFILE_ORGFILE="misc.org" | |
# REFILE_HEADING="" | |
else | |
echo "ERROR: No known UUID for backup found." | |
echo "Check script: ${0}" | |
exit 2 | |
fi | |
## ======================================================================= ## | |
## ======================================================================= ## | |
## ======================================================================= ## | |
LOGFILE="/home/user/log/vkbackup-${BACKUPNAME}.log" | |
MOUNTPOINT="/mnt/backup" | |
STARTTIME_IN_ORG_TIMESTAMP="<$(date '+%Y-%m-%d %a %H:%M')>" | |
NOW_IN_ISO_TIMESTAMP=$(/bin/date +%Y-%m-%dT%H.%M.%S) | |
NOW_IN_ISO_DATESTAMP=$(/bin/date +%Y-%m-%d) | |
## Mounting LUKS backup disk: (and asking for passphrase) | |
mkdir -p "${MOUNTPOINT}" | |
mount | grep "${MOUNTPOINT}" || grml-crypt start /dev/disk/by-uuid/${UUID} "${MOUNTPOINT}" || exit 1 | |
## Before-backup statistics: | |
script_start=$(date +%s) | |
echo "================================================================================" | |
echo | |
echo "begin: $(date)" | |
df -h | egrep 'Filesystem|luks|crypt|sda1|backup' | |
echo | |
df_before=$(df -h | awk '{ print " | " $1 " | " $2 " | " $3 " | " $4 " | " $5 " | " $6 " |" "\t" }' | \ | |
sed 's/Mounted |/Mounted |\n |---------------------------------------------------|/') | |
## Running the actual backup command: | |
echo "starting backup command ..." | |
echo | |
nice -n 19 rsnapshot -c /home/user/archive/backup/hostname/rsnapshot_${BACKUPNAME}.conf alpha 2>&1 > "${LOGFILE}" || \ | |
sudo -u user /usr/local/bin/appendorgheading --title "rsnapshot run resultet in an error, see file:${LOGFILE}" --level 1 | |
echo | |
echo "end: $(date)" | |
## After-backup statistics: | |
echo | |
echo "Situation after backup:" | |
echo | |
df -h | egrep 'Filesystem|luks|crypt|sda1|backup' | |
df_after=$(df -h | awk '{ print " | " $1 " | " $2 " | " $3 " | " $4 " | " $5 " | " $6 " |" "\t" }' | \ | |
sed 's/Mounted |/Mounted |\n |---------------------------------------------------|/') | |
script_end=$(date +%s) | |
script_runtime=$((script_end-script_start)) | |
script_HMS=$(date -u -d @${script_runtime} +"%T") | |
echo | |
echo "Running times (in hh:mm:ss)" | |
echo "| Total | ${script_HMS} |" | |
echo | |
ENDTIME_IN_ORG_TIMESTAMP="<$(date '+%Y-%m-%d %a %H:%M')>" | |
## Generate Org mode result block: | |
TEMPFILE=$(mktemp) | |
echo > "${TEMPFILE}" | |
echo "#+BEGIN_SRC emacs-lisp" >> "${TEMPFILE}" | |
echo "(my-org-refile \"${REFILE_ORGFILE}\" \"${REFILE_HEADING}\")" >> "${TEMPFILE}" | |
echo "#+END_SRC" >> "${TEMPFILE}" | |
echo "" >> "${TEMPFILE}" | |
echo "- logfile: [[file:${LOGFILE}][${LOGFILE}]]" >> "${TEMPFILE}" | |
echo "- Backup target UUID: ${UUID}" >> "${TEMPFILE}" | |
echo >> "${TEMPFILE}" | |
echo "- \"df -h\" before backup:" >> "${TEMPFILE}" | |
echo >> "${TEMPFILE}" | |
echo "${df_before}" >> "${TEMPFILE}" | |
echo >> "${TEMPFILE}" | |
echo "- \"df -h\" after backup:" >> "${TEMPFILE}" | |
echo >> "${TEMPFILE}" | |
echo "${df_after}" >> "${TEMPFILE}" | |
echo >> "${TEMPFILE}" | |
echo >> "${TEMPFILE}" | |
body=$(cat "${TEMPFILE}") | |
rm "${TEMPFILE}" | |
sudo -u user /usr/local/bin/appendorgheading \ | |
--title "${STARTTIME_IN_ORG_TIMESTAMP}--${ENDTIME_IN_ORG_TIMESTAMP} vkbackup: ${BACKUPNAME} took ${script_HMS} (HH:MM:SS)" \ | |
--output /home/user/org/inbox.org \ | |
--level 1 \ | |
--section "${body}" \ | |
--filecontent "${LOGFILE}" \ | |
--nodaily | |
## Notify user and wait for one minute before umounting LUKS device: | |
sudo -u user notify-send "${BACKUPNAME} finalized 🔜 unmounting" "`/bin/date '+%Y-%m-%dT%H:%M:%S'`" & | |
echo "wait for one minute and do grml-crypt stop ..." | |
sleep 1m ; grml-crypt stop ${MOUNTPOINT} | |
sudo -u user notify-send "${BACKUPNAME} finished and umounted" "`/bin/date '+%Y-%m-%dT%H:%M:%S'`" -u critical & | |
echo "vkbackup ${BACKUPNAME} ended." | |
#end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment