ssh backups

This commit is contained in:
James Barnett
2017-04-11 10:32:45 -05:00
parent cf02a5cf51
commit 615d1a5dc5

View File

@@ -66,12 +66,15 @@ Options:
directory name on first backup" directory name on first backup"
-u, --UUID <UUID> Specify the UUID of the mounted BTRFS subvolume to back up to. Otherwise will prompt." -u, --UUID <UUID> Specify the UUID of the mounted BTRFS subvolume to back up to. Otherwise will prompt."
If multiple mount points are found with the same UUID, will prompt user." If multiple mount points are found with the same UUID, will prompt user."
--remote <address> The destination for the snapshot if it is not on the local machine. The snapshot will
be sent via ssh. You should specify the remote machine's hostname or ip address.
EOF EOF
} }
trap error ERR trap error ERR
trap sigkill SIGTERM SIGINT trap sigkill SIGTERM SIGINT
ssh=""
while [[ $# -gt 0 ]]; do while [[ $# -gt 0 ]]; do
key="$1" key="$1"
@@ -96,6 +99,11 @@ while [[ $# -gt 0 ]]; do
usage usage
exit 1 exit 1
;; ;;
--remote)
remote=$2
ssh="ssh $remote"
shift 2
;;
*) *)
die "Unknown option: $key\nRun '$name -h' for valid options.\n" die "Unknown option: $key\nRun '$name -h' for valid options.\n"
;; ;;
@@ -107,13 +115,21 @@ uuid_cmdline=${uuid_cmdline:-"none"}
noconfirm=${noconfirm:-"no"} noconfirm=${noconfirm:-"no"}
if [[ "$uuid_cmdline" != "none" ]]; then if [[ "$uuid_cmdline" != "none" ]]; then
notify_info "Backup started" "Starting backups to $uuid_cmdline..." if [[ -z $ssh ]]; then
notify_info "Backup started" "Starting backups to $uuid_cmdline..."
else
notify_info "Backup started" "Starting backups to $uuid_cmdline at $remote..."
fi
else else
notify_info "Backup started" "Starting backups. Use command line menu to select disk." if [[ -z $ssh ]]; then
notify_info "Backup started" "Starting backups. Use command line menu to select disk."
else
notify_info "Backup started" "Starting backups. Use command line menu to select disk on $remote."
fi
fi fi
TARGETS="$(findmnt -n -v -t btrfs -o TARGET --list)" TARGETS="$($ssh findmnt -n -v -t btrfs -o TARGET --list)"
UUIDS="$(findmnt -n -v -t btrfs -o UUID --list)" UUIDS="$($ssh findmnt -n -v -t btrfs -o UUID --list)"
declare -a TARGETS_ARRAY declare -a TARGETS_ARRAY
declare -a UUIDS_ARRAY declare -a UUIDS_ARRAY
@@ -162,7 +178,11 @@ fi
selected_uuid="${UUIDS_ARRAY[$((disk))]}" selected_uuid="${UUIDS_ARRAY[$((disk))]}"
selected_mnt="${TARGETS_ARRAY[$((disk))]}" selected_mnt="${TARGETS_ARRAY[$((disk))]}"
printf "\nYou selected the disk with UUID %s.\n" "$selected_uuid" | tee $PIPE printf "\nYou selected the disk with UUID %s.\n" "$selected_uuid" | tee $PIPE
printf "The disk is mounted at %s.\n" "$selected_mnt" | tee $PIPE if [[ -z $ssh ]]; then
printf "The disk is mounted at %s.\n" "$selected_mnt" | tee $PIPE
else
printf "The disk is mounted at %s:%s.\n" "$remote" "$selected_mnt" | tee $PIPE
fi
if [[ -f /etc/conf.d/snapper ]]; then if [[ -f /etc/conf.d/snapper ]]; then
source /etc/conf.d/snapper source /etc/conf.d/snapper
@@ -188,7 +208,7 @@ printf "\nInitial configuration...\n" | tee $PIPE
i=0 i=0
for x in $selected_configs; do for x in $selected_configs; do
if [[ "$(sudo snapper -c $x list -t single | awk '/'$name' backup in progress/ {cnt++} END {print cnt}')" -gt 0 ]]; then if [[ "$(snapper -c $x list -t single | awk '/'$name' backup in progress/ {cnt++} END {print cnt}')" -gt 0 ]]; then
printf "\nNOTE: Previous failed $name backup snapshots found for '$x'.\n" | tee $PIPE printf "\nNOTE: Previous failed $name backup snapshots found for '$x'.\n" | tee $PIPE
fi fi
@@ -217,13 +237,11 @@ for x in $selected_configs; do
read -r -p "Enter name of directory to store backups, relative to $selected_mnt (to be created if not existing): " mybackupdir read -r -p "Enter name of directory to store backups, relative to $selected_mnt (to be created if not existing): " mybackupdir
printf "This will be the initial backup for snapper configuration '%s' to this disk. This could take awhile.\n" "$x" printf "This will be the initial backup for snapper configuration '%s' to this disk. This could take awhile.\n" "$x"
BACKUPDIR="$selected_mnt/$mybackupdir" BACKUPDIR="$selected_mnt/$mybackupdir"
mkdir -p -m700 "$BACKUPDIR" $mkdir -p -m700 "$BACKUPDIR"
else else
mybackupdir=$(snapper -c root list -t single | awk -F"|" '/'"$selected_uuid"'/ {print $5}' | awk -F "," '/backupdir/ {print $1}' | awk -F"=" '{print $2}') mybackupdir=$(snapper -c root list -t single | awk -F"|" '/'"$selected_uuid"'/ {print $5}' | awk -F "," '/backupdir/ {print $1}' | awk -F"=" '{print $2}')
BACKUPDIR="$selected_mnt/$mybackupdir" BACKUPDIR="$selected_mnt/$mybackupdir"
if [[ ! -d $BACKUPDIR ]]; then $ssh test -d $BACKUPDIR || die "%s is not a directory on %s.\n" "$BACKUPDIR" "$selected_uuid"
die "%s is not a directory on %s.\n" "$BACKUPDIR" "$selected_uuid"
fi
fi fi
BACKUPDIRS_ARRAY[$i]="$BACKUPDIR" BACKUPDIRS_ARRAY[$i]="$BACKUPDIR"
MYBACKUPDIR_ARRAY[$i]="$mybackupdir" MYBACKUPDIR_ARRAY[$i]="$mybackupdir"
@@ -234,7 +252,11 @@ for x in $selected_configs; do
new_info=$SUBVOLUME/.snapshots/$new_num/info.xml new_info=$SUBVOLUME/.snapshots/$new_num/info.xml
sync sync
backup_location=$BACKUPDIR/$x/$new_num/ backup_location=$BACKUPDIR/$x/$new_num/
printf "Will backup %s to %s\n" "$new_snap" "$backup_location/snapshot" | tee $PIPE if [[ -z $ssh ]]; then
printf "Will backup %s to %s\n" "$new_snap" "$backup_location/snapshot" | tee $PIPE
else
printf "Will backup %s to %s\n" "$new_snap" "$remote":"$backup_location/snapshot" | tee $PIPE
fi
NEW_NUM_ARRAY[$i]="$new_num" NEW_NUM_ARRAY[$i]="$new_num"
NEW_SNAP_ARRAY[$i]="$new_snap" NEW_SNAP_ARRAY[$i]="$new_snap"
@@ -279,6 +301,7 @@ for x in $selected_configs; do
if [[ -f "/etc/snapper/configs/$x" ]]; then if [[ -f "/etc/snapper/configs/$x" ]]; then
source /etc/snapper/configs/$x source /etc/snapper/configs/$x
else
die "Selected snapper configuration $x does not exist." die "Selected snapper configuration $x does not exist."
fi fi
@@ -301,11 +324,11 @@ for x in $selected_configs; do
new_info="${NEW_INFO_ARRAY[$i]}" new_info="${NEW_INFO_ARRAY[$i]}"
backup_location="${BACKUPLOC_ARRAY[$i]}" backup_location="${BACKUPLOC_ARRAY[$i]}"
mkdir -p "$backup_location" $ssh mkdir -p $backup_location
if [[ -z "$old_num" ]]; then if [[ -z "$old_num" ]]; then
printf "Sending first snapshot for %s...\n" "$x" | tee $PIPE printf "Sending first snapshot for %s...\n" "$x" | tee $PIPE
btrfs send "$new_snap" | btrfs receive "$backup_location" &>/dev/null btrfs send "$new_snap" | $ssh btrfs receive "$backup_location" &>/dev/null
else else
@@ -314,12 +337,16 @@ for x in $selected_configs; do
# backup location. Using the -c flag instead of -p tells it that there # backup location. Using the -c flag instead of -p tells it that there
# is an identical subvolume to the old snapshot at the receiving # is an identical subvolume to the old snapshot at the receiving
# location where it can get its data. This helps speed up the transfer. # location where it can get its data. This helps speed up the transfer.
btrfs send "$new_snap" -c "$old_snap" | btrfs receive "$backup_location" &>/dev/null btrfs send "$new_snap" -c "$old_snap" | $ssh btrfs receive "$backup_location"
printf "Deleting old snapshot for $x...\n" | tee $PIPE printf "Deleting old snapshot for $x...\n" | tee $PIPE
snapper -c "$x" delete "$old_num" snapper -c "$x" delete "$old_num"
fi fi
cp "$new_info" "$backup_location" if [[ -z $ssh ]]; then
cp "$new_info" "$backup_location"
else
rsync -avzq "$new_info" "$remote":"$backup_location"
fi
# It's important not to change this userdata in the snapshots, since that's how # It's important not to change this userdata in the snapshots, since that's how
# we find the previous one. # we find the previous one.