Skip to content

Instantly share code, notes, and snippets.

@casesolved-co-uk
Last active February 15, 2023 14:40
Show Gist options
  • Save casesolved-co-uk/c8f68c4e8c60f98916f66866ad50e195 to your computer and use it in GitHub Desktop.
Save casesolved-co-uk/c8f68c4e8c60f98916f66866ad50e195 to your computer and use it in GitHub Desktop.
Whole linux server offsite backup using rclone (Ubuntu 22.04)
#!/usr/bin/env bash
# Copyright (c) 2023, CaseSolved.co.uk
# Whole linux server offsite backup using rclone (Ubuntu 22.04)
# tar should achieve roughly 50% compression
read -r -d "" usage << EOM
arg1: rclone remote
arg2: remote directory
optional:
-R remove everything in remote dir first !! be careful !!
EOM
exit_msg () {
# $1 code, $2 msg
>&2 echo "Error: '$2', code: $1"
exit $1
}
exec_exit () {
# command to run
"$@"
code=$?
if [ $code != 0 ]; then
exit_msg $code "$@"
fi
}
if [ $# -lt 2 ]; then
echo "$usage"
exit_msg 1 "Illegal number of parameters"
fi
for arg in "$@"; do
if [ "$arg" == "-R" ]; then
remove_first="true"
echo "WARNING: Removing content of remote directory first!!"
elif [ -z ${remote+x} ]; then
remote="$arg"
elif [ -z ${root+x} ]; then
root="$arg"
fi
done
if [ -z ${root+x} ]; then
echo "$usage"
exit_msg 2 "remote directory not supplied"
fi
rclonex="rclone"
local_dir="/opt/backup"
remote_dir="$remote:$root"
backup_file="$(hostname)__$(date +%Y-%m-%d_%H-%M-%S).tar.gz"
excludes=(--exclude={lost+found,dev/*,proc/*,run/*,sys/*,tmp/*,cdrom/*,swap*,mnt/*,media/*,opt/backup/*})
# for testing:
#excludes=(--exclude={lost+found,dev/*,proc/*,run/*,sys/*,tmp/*,cdrom/*,swap*,mnt/*,media/*,opt/backup/*,var/*,usr/*,home/*})
echo "Remote: $remote_dir, file: $backup_file, excluding: ${excludes[@]}"
# Create backup dir
exec_exit mkdir -p "$local_dir"
# Check rclone remote dir is okay
# 0 ok, 3 dir not exist, else fail
$rclonex ls --human-readable "$remote_dir"
code=$?
if [ $code == 3 ]; then
exec_exit $rclonex mkdir "$remote_dir"
exec_exit $rclonex ls --human-readable "$remote_dir"
elif [ $code != 0 ]; then
exit_msg $code "Remote connection failed"
fi
# sync mysql & wait
exec_exit service mysql restart
exec_exit sleep 60
# sync filesystem
exec_exit sync
# create backup
exec_exit cd "$local_dir" && tar --totals -czf "$backup_file" --directory=/ "${excludes[@]}" .
# print file size
exec_exit ls -lh "$local_dir/$backup_file"
# remove remote contents first
if [ "$remove_first" == "true" ]; then
exec_exit $rclonex delete "$remote_dir"
fi
# move backup via rclone
exec_exit $rclonex --stats-log-level NOTICE --stats 30m move "$local_dir/$backup_file" "$remote_dir"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment