Last active
April 6, 2020 20:09
-
-
Save ntrrgc/292960aa666c8f32ab072879c0af4048 to your computer and use it in GitHub Desktop.
My backup script for synology NAS, with safety checks for archival
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/bash | |
set -eu | |
found_not_mounted=0 | |
function check_not_empty() { | |
local path="$1" | |
if [ ! -d "$path" ]; then | |
found_not_mounted=1 | |
echo "ERROR: $path does not exist!" | |
elif [ ! "$(ls -A "$path")" ]; then | |
found_not_mounted=1 | |
echo "ERROR: $path is empty!" | |
fi | |
} | |
# Check all fancy encrypted volumes to backup are properly mounted! | |
check_not_empty /nas | |
check_not_empty /nas/Archive | |
check_not_empty /nas/Dibujos | |
check_not_empty /nas/FileHistory | |
if [ "$found_not_mounted" -ne 0 ]; then | |
echo "Please make sure /nas is mounted and all encrypted volumes in the NAS Shared Folders are also properly mounted." | |
exit 1 | |
fi | |
DRIVE_GLOB="/run/media/ntrrgc/NAS-*" | |
DRIVE="" | |
for drive in $(ls -1 -d $DRIVE_GLOB); do | |
if [ -z "$DRIVE" ]; then | |
DRIVE="$drive" | |
else | |
echo "Ambiguous drive selection, there are more than one possible NAS backup drives!" | |
ls -1 -d $DRIVE_GLOB | |
exit 1 | |
fi | |
done | |
if [ -z "$DRIVE" ]; then | |
echo "Plug and mount a NAS backup drive in $DRIVE_GLOB!" | |
exit 1 | |
fi | |
echo "Backing up NAS in $DRIVE..." | |
sleep 3s # to confirm... enough time to ^C if it goes haywire | |
export RSYNC_PASSWORD=YOUR_SYNOLOGY_RYSNC_PASS | |
RSYNC_EXCLUDE_OPTS=(--exclude '*@SynoEAStream' --exclude '*@SynoResource' --exclude '@eaDir' --exclude '#recycle') | |
RSYNC_SRC="rsync://ntrrgc@mami.local" | |
DRY_RUN_EXCLUDE=(grep -vi 'Thumbs.db') | |
found_deletions=0 | |
deletions_msg="" | |
function archive_check() { | |
local nas_path="$1" # must NOT start or end with / | |
mkdir -p /tmp/backup-nas-dry-run/"$nas_path" | |
local dry_run_file="/tmp/backup-nas-dry-run/$nas_path/dry-run.txt" | |
echo "Checking for deletions in $nas_path..." | |
rsync -aXx "${RSYNC_EXCLUDE_OPTS[@]}" --delete --inplace -nv "$RSYNC_SRC/$nas_path/" "$DRIVE/$nas_path" > "$dry_run_file" 2>&1 | |
if cat "$dry_run_file" | "${DRY_RUN_EXCLUDE[@]}" | grep '^deleting '; then | |
found_deletions=1 | |
local count=$(cat "$dry_run_file" | "${DRY_RUN_EXCLUDE[@]}" | grep -c '^deleting ') | |
deletions_msg="${deletions_msg}$count deletions have been found in $nas_path."$'\n' | |
fi | |
} | |
function request_delete_confirmation() { | |
if [[ "$found_deletions" -ne 0 ]]; then | |
deletions_msg="${deletions_msg}Please check everything is right and confirm to continue the backup with the deletions." | |
telegram-notify send "$deletions_msg" | |
echo "You can check the full dry-run logs in /tmp/backup-nas-dry-run. Type 'yes' to continue with the backup deleting the files above from the backup drive." | |
echo -n "Continue? " | |
read answer | |
if [[ "$answer" != "yes" ]]; then | |
echo "Cancelling backup." | |
exit 1 | |
fi | |
fi | |
} | |
function sync_folder() { | |
local nas_path="$1" # must NOT start or end with / | |
# --inplace should make synchronization of big files (e.g. disk images) faster | |
rsync -aXx --info=progress2 \ | |
"${RSYNC_EXCLUDE_OPTS[@]}" \ | |
--delete --inplace \ | |
"$RSYNC_SRC/$nas_path/" "$DRIVE/$nas_path/" | |
} | |
# Deleting files from the backup in these directories will need confirmation (they are intended to be mostly addition-only). | |
archive_check Archive | |
archive_check Dibujos | |
archive_check photo | |
request_delete_confirmation | |
sync_folder Archive | |
sync_folder Dibujos | |
sync_folder photo | |
sync_folder homes | |
sync_folder FileHistory | |
date | sudo tee "$DRIVE/last-backup-date.txt" > /dev/null | |
if safely-remove "$DRIVE"; then | |
telegram-notify send "Finished backing up NAS into $DRIVE. You can now unplug the drive." | |
else | |
telegram-notify send "Finished backing up NAS into $DRIVE. COULDN'T UNMOUNT THE DEVICE, IT MAY STILL BE IN USE." | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment