snap-sync: restructure function block

- new function get_disk_info()
- new function run_config()
- new function run_backup()
- new function get_target_disk()
- apply them to be in lexical order

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
This commit is contained in:
2017-11-08 17:16:30 +01:00
parent 15a0aee30e
commit 2ed161c8db

View File

@@ -70,6 +70,38 @@ error() {
notify_error 'Error' 'Check journal for more information.' notify_error 'Error' 'Check journal for more information.'
} >&2 } >&2
get_disk_infos () {
if [[ "$(findmnt -n -v --target / -o FSTYPE)" == "btrfs" ]]; then
EXCLUDE_UUID=$(findmnt -n -v -t btrfs --target / -o UUID)
TARGETS=$($ssh findmnt -n -v -t btrfs -o UUID,TARGET --list | grep -v $EXCLUDE_UUID | awk '{print $2}')
UUIDS=$($ssh findmnt -n -v -t btrfs -o UUID,TARGET --list | grep -v $EXCLUDE_UUID | awk '{print $1}')
else
TARGETS=$($ssh findmnt -n -v -t btrfs -o TARGET --list)
UUIDS=$($ssh findmnt -n -v -t btrfs -o UUID --list)
fi
declare -a TARGETS_ARRAY
declare -a UUIDS_ARRAY
i=0
disk=-1
disk_count=0
for x in $UUIDS; do
UUIDS_ARRAY[$i]=$x
if [[ "$x" == "$uuid_cmdline" ]]; then
disk=$i
disk_count=$(($disk_count+1))
fi
i=$((i+1))
done
i=0
for x in $TARGETS; do
TARGETS_ARRAY[$i]=$x
i=$((i+1))
done
}
notify() { notify() {
for u in $(users | sed 's/ /\n/' | sort -u); do for u in $(users | sed 's/ /\n/' | sort -u); do
sudo -u $u DISPLAY=:0 \ sudo -u $u DISPLAY=:0 \
@@ -169,158 +201,22 @@ parse_params () {
fi fi
} }
traperror() { run_config () {
printf "Exited due to error on line %s.\n" $1 declare -a BACKUPDIRS_ARRAY
printf "exit status: %s\n" "$2" declare -a MYBACKUPDIR_ARRAY
printf "command: %s\n" "$3" declare -a OLD_NUM_ARRAY
printf "bash line: %s\n" "$4" declare -a OLD_SNAP_ARRAY
printf "function progname: %s\n" "$5" declare -a NEW_NUM_ARRAY
exit 1 declare -a NEW_SNAP_ARRAY
} declare -a NEW_INFO_ARRAY
declare -a BACKUPLOC_ARRAY
declare -a CONT_BACKUP_ARRAY
trapkill() { printf "\nInitial configuration...\n" | tee $PIPE
die "Exited due to user intervention."
}
usage() { # Initial configuration of where backup directories are
cat <<EOF i=0
$progname $version for x in $selected_configs; do
Usage: $progname [options]
Options:
-d, --description <desc> Change the snapper description. Default: "latest incremental backup"
-c, --config <config> Specify the snapper configuration to use. Otherwise will perform for each snapper
configuration. Can list multiple configurations within quotes, space-separated
(e.g. -c "root home").
-n, --noconfirm Do not ask for confirmation for each configuration. Will still prompt for backup
directory name on first backup"
-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."
--remote <address> Send the snapshot backup to a remote machine. The snapshot will be sent via ssh. You
should specify the remote machine's hostname or ip address. The 'root' user must be
permitted to login on the remote machine.
-v, --verbose Be more verbose on what's going on.
EOF
}
###
# Main
###
trap 'traperror ${LINENO} $? "$BASH_COMMAND" $BASH_LINENO "${FUNCPROGNAME[@]}"' ERR
trap trapkill SIGTERM SIGINT
cwd=`pwd`
ssh=""
parse_params $@
check_prerequisites
if [[ "$uuid_cmdline" != "none" ]]; then
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
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
if [[ "$(findmnt -n -v --target / -o FSTYPE)" == "btrfs" ]]; then
EXCLUDE_UUID=$(findmnt -n -v -t btrfs --target / -o UUID)
TARGETS=$($ssh findmnt -n -v -t btrfs -o UUID,TARGET --list | grep -v $EXCLUDE_UUID | awk '{print $2}')
UUIDS=$($ssh findmnt -n -v -t btrfs -o UUID,TARGET --list | grep -v $EXCLUDE_UUID | awk '{print $1}')
else
TARGETS=$($ssh findmnt -n -v -t btrfs -o TARGET --list)
UUIDS=$($ssh findmnt -n -v -t btrfs -o UUID --list)
fi
declare -a TARGETS_ARRAY
declare -a UUIDS_ARRAY
i=0
disk=-1
disk_count=0
for x in $UUIDS; do
UUIDS_ARRAY[$i]=$x
if [[ "$x" == "$uuid_cmdline" ]]; then
disk=$i
disk_count=$(($disk_count+1))
fi
i=$((i+1))
done
i=0
for x in $TARGETS; do
TARGETS_ARRAY[$i]=$x
i=$((i+1))
done
if [[ "${#UUIDS_ARRAY[$@]}" -eq 0 ]]; then
die "No external btrfs subvolumes found to backup to."
fi
if [[ "$disk_count" > 1 ]]; then
printf "Multiple mount points were found with UUID %s.\n" "$uuid_cmdline"
disk="-1"
fi
if [[ "$disk" == -1 ]]; then
if [[ "$disk_count" == 0 && "$uuid_cmdline" != "none" ]]; then
error "A device with UUID $uuid_cmdline was not found to be mounted, or it is not a BTRFS device."
fi
if [[ -z $ssh ]]; then
printf "Select a mounted BTRFS device on your local machine to backup to.\n"
else
printf "Select a mounted BTRFS device on %s to backup to.\n" "$remote"
fi
while [[ $disk -lt 0 || $disk -gt $i ]]; do
for x in "${!TARGETS_ARRAY[@]}"; do
printf "%4s) %s (%s)\n" "$((x+1))" "${UUIDS_ARRAY[$x]}" "${TARGETS_ARRAY[$x]}"
done
printf "%4s) Exit\n" "0"
read -r -p "Enter a number: " disk
if ! [[ $disk == ?(-)+([0-9]) ]]; then
printf "\nNo disk selected. Select a disk to continue.\n"
disk=-1
fi
done
if [[ $disk == 0 ]]; then
exit 0
fi
disk=$(($disk-1))
fi
selected_uuid="${UUIDS_ARRAY[$((disk))]}"
selected_mnt="${TARGETS_ARRAY[$((disk))]}"
printf "\nYou selected the disk with UUID %s.\n" "$selected_uuid" | 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
declare -a BACKUPDIRS_ARRAY
declare -a MYBACKUPDIR_ARRAY
declare -a OLD_NUM_ARRAY
declare -a OLD_SNAP_ARRAY
declare -a NEW_NUM_ARRAY
declare -a NEW_SNAP_ARRAY
declare -a NEW_INFO_ARRAY
declare -a BACKUPLOC_ARRAY
declare -a CONT_BACKUP_ARRAY
printf "\nInitial configuration...\n" | tee $PIPE
# Initial configuration of where backup directories are
i=0
for x in $selected_configs; do
if [[ "$(snapper -c $x list -t single | awk '/'"$selected_uuid"'/ {cnt++} END {print cnt}')" -gt 1 ]]; then if [[ "$(snapper -c $x list -t single | awk '/'"$selected_uuid"'/ {cnt++} END {print cnt}')" -gt 1 ]]; then
error "More than one snapper entry found with UUID $selected_uuid for configuration $x. Skipping configuration $x." error "More than one snapper entry found with UUID $selected_uuid for configuration $x. Skipping configuration $x."
@@ -367,7 +263,7 @@ for x in $selected_configs; do
if [[ -z "$old_num" ]]; then if [[ -z "$old_num" ]]; then
printf "No backups have been performed for '%s' on this disk.\n" "$x" printf "No backups have been performed for '%s' on this disk.\n" "$x"
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 progname 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"
$ssh mkdir -p -m700 "$BACKUPDIR" $ssh mkdir -p -m700 "$BACKUPDIR"
@@ -421,12 +317,14 @@ for x in $selected_configs; do
i=$(($i+1)) i=$(($i+1))
done done
}
# Actual backing up run_backup () {
printf "\nPerforming backups...\n" | tee $PIPE # Actual backing up
i=-1 printf "\nPerforming backups...\n" | tee $PIPE
for x in $selected_configs; do i=-1
for x in $selected_configs; do
i=$(($i+1)) i=$(($i+1))
@@ -492,10 +390,132 @@ for x in $selected_configs; do
printf "Backup complete for configuration %s.\n" "$x" > $PIPE printf "Backup complete for configuration %s.\n" "$x" > $PIPE
done done
printf "\nDone!\n" | tee $PIPE printf "\nDone!\n" | tee $PIPE
exec 3>&- exec 3>&-
}
select_target_disk () {
if [[ "${#UUIDS_ARRAY[$@]}" -eq 0 ]]; then
die "No external btrfs subvolumes found to backup to."
fi
if [[ "$disk_count" > 1 ]]; then
printf "Multiple mount points were found with UUID %s.\n" "$uuid_cmdline"
disk="-1"
fi
if [[ "$disk" == -1 ]]; then
if [[ "$disk_count" == 0 && "$uuid_cmdline" != "none" ]]; then
error "A device with UUID $uuid_cmdline was not found to be mounted, or it is not a BTRFS device."
fi
if [[ -z $ssh ]]; then
printf "Select a mounted BTRFS device on your local machine to backup to.\n"
else
printf "Select a mounted BTRFS device on %s to backup to.\n" "$remote"
fi
while [[ $disk -lt 0 || $disk -gt $i ]]; do
for x in "${!TARGETS_ARRAY[@]}"; do
printf "%4s) %s (%s)\n" "$((x+1))" "${UUIDS_ARRAY[$x]}" "${TARGETS_ARRAY[$x]}"
done
printf "%4s) Exit\n" "0"
read -r -p "Enter a number: " disk
if ! [[ $disk == ?(-)+([0-9]) ]]; then
printf "\nNo disk selected. Select a disk to continue.\n"
disk=-1
fi
done
if [[ $disk == 0 ]]; then
exit 0
fi
disk=$(($disk-1))
fi
}
traperror() {
printf "Exited due to error on line %s.\n" $1
printf "exit status: %s\n" "$2"
printf "command: %s\n" "$3"
printf "bash line: %s\n" "$4"
printf "function progname: %s\n" "$5"
exit 1
}
trapkill() {
die "Exited due to user intervention."
}
usage() {
cat <<EOF
$progname $version
Usage: $progname [options]
Options:
-d, --description <desc> Change the snapper description. Default: "latest incremental backup"
-c, --config <config> Specify the snapper configuration to use. Otherwise will perform for each snapper
configuration. Can list multiple configurations within quotes, space-separated
(e.g. -c "root home").
-n, --noconfirm Do not ask for confirmation for each configuration. Will still prompt for backup
directory name on first backup"
-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."
--remote <address> Send the snapshot backup to a remote machine. The snapshot will be sent via ssh. You
should specify the remote machine's hostname or ip address. The 'root' user must be
permitted to login on the remote machine.
-v, --verbose Be more verbose on what's going on.
EOF
}
###
# Main
###
trap 'traperror ${LINENO} $? "$BASH_COMMAND" $BASH_LINENO "${FUNCPROGNAME[@]}"' ERR
trap trapkill SIGTERM SIGINT
cwd=`pwd`
ssh=""
parse_params $@
check_prerequisites
if [[ "$uuid_cmdline" != "none" ]]; then
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
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
# read mounted BTRFS structures
get_disk_infos
# select the target BTRFS subvol
select_target_disk
selected_uuid="${UUIDS_ARRAY[$((disk))]}"
selected_mnt="${TARGETS_ARRAY[$((disk))]}"
printf "\nYou selected the disk with UUID %s.\n" "$selected_uuid" | 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
# create and initialize structures for snapper configs
run_config
# run backups using btrfs-send -> btrfs-receive
run_backup
if [[ "$uuid_cmdline" != "none" ]]; then if [[ "$uuid_cmdline" != "none" ]]; then
notify_info "Finished" "Backups to $uuid_cmdline complete!" notify_info "Finished" "Backups to $uuid_cmdline complete!"