snap-sync: enhance verify_snapper_structure
- harden testings when creating snapper structure on target - reorder function get_config - remove tee to PIPE Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
This commit is contained in:
206
bin/snap-sync
206
bin/snap-sync
@@ -31,8 +31,10 @@ version="0.5.2.1"
|
||||
|
||||
# The following lines are modified by the Makefile or
|
||||
# find_snapper_config script
|
||||
SNAPPER_CONFIG=/etc/conf.d/snapper
|
||||
SNAPPER_TEMPLATES=/etc/snapper/config-templates
|
||||
#SNAPPER_CONFIG=/etc/conf.d/snapper
|
||||
SNAPPER_CONFIG=/etc/default/snapper
|
||||
SNAPPER_TEMPLATE_DIR=/etc/snapper/config-templates
|
||||
SNAPPER_CONFIG_DIR=/etc/snapper/configs
|
||||
|
||||
# define fifo pipes
|
||||
TMPDIR_PIPE=$(mktemp -d)
|
||||
@@ -99,7 +101,8 @@ check_snapper_failed_ids () {
|
||||
if [ "$batch" ]; then
|
||||
answer="yes"
|
||||
else
|
||||
printf "\nNOTE: Found %s previous failed sync runs for '%s'.\n" "${snapper_failed_ids}" "$selected_config" | tee $PIPE
|
||||
#printf "\nNOTE: Found %s previous failed sync runs for '%s'.\n" "${snapper_failed_ids}" "$selected_config" | tee $PIPE
|
||||
printf "\nNOTE: Found %s previous failed sync runs for '%s'.\n" "${snapper_failed_ids}" "$selected_config"
|
||||
answer=no
|
||||
get_answer_yes_no "Delete failed backup snapshots [y/N]? " "$answer"
|
||||
fi
|
||||
@@ -121,6 +124,51 @@ error () {
|
||||
notify_error 'Error' 'Check journal for more information.'
|
||||
} >&2
|
||||
|
||||
get_answer_yes_no () {
|
||||
local message="${1:-'Do you want to proceed [y/N]? '}"
|
||||
local i="none"
|
||||
|
||||
# hack: answer is a global variable, using it for preselection
|
||||
while [ "$i" = "none" ]; do
|
||||
read -r -p "$message" i
|
||||
|
||||
case $i in
|
||||
y|Y|yes|Yes)
|
||||
answer="yes"
|
||||
break
|
||||
;;
|
||||
n|N|no|No)
|
||||
answer="no"
|
||||
break
|
||||
;;
|
||||
*)
|
||||
if [ -n "$answer" ]; then
|
||||
i="$answer"
|
||||
else
|
||||
i="none"
|
||||
printf "Select 'y' or 'n'.\n"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
get_config(){
|
||||
local config=${1:-"$TEMPLATE_DIR/$snapper_snapsync_template"}
|
||||
local config_key=${2:-SUBVOLUME}
|
||||
|
||||
# IFS="="
|
||||
# while read -r name value
|
||||
# do
|
||||
# if [ "$name" = "$config_key" ]; then
|
||||
# value="$value"
|
||||
# SUBVOLUME="$value"
|
||||
# break
|
||||
# fi
|
||||
# done < $config
|
||||
|
||||
}
|
||||
|
||||
get_disk_infos () {
|
||||
local disk_uuid
|
||||
local disk_target
|
||||
@@ -188,50 +236,6 @@ get_disk_infos () {
|
||||
done
|
||||
}
|
||||
|
||||
get_answer_yes_no () {
|
||||
local message="${1:-'Do you want to proceed [y/N]? '}"
|
||||
local i="none"
|
||||
|
||||
# hack: answer is a global variable, using it for preselection
|
||||
while [ "$i" = "none" ]; do
|
||||
read -r -p "$message" i
|
||||
|
||||
case $i in
|
||||
y|Y|yes|Yes)
|
||||
answer="yes"
|
||||
break
|
||||
;;
|
||||
n|N|no|No)
|
||||
answer="no"
|
||||
break
|
||||
;;
|
||||
*)
|
||||
if [ -n "$answer" ]; then
|
||||
i="$answer"
|
||||
else
|
||||
i="none"
|
||||
printf "Select 'y' or 'n'.\n"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
get_config(){
|
||||
local config=${1:-/etc/snapper/config-templates/"$snapper_snapsync_template"}
|
||||
local config_key=${2:-SUBVOLUME}
|
||||
|
||||
# IFS="="
|
||||
# while read -r name value
|
||||
# do
|
||||
# if [ "$name" = "$config_key" ]; then
|
||||
# value="$value"
|
||||
# SUBVOLUME="$value"
|
||||
# break
|
||||
# fi
|
||||
# done < $config
|
||||
|
||||
}
|
||||
|
||||
notify () {
|
||||
# estimation: batch calls should just log
|
||||
@@ -509,10 +513,10 @@ run_config () {
|
||||
awk '/subvolid='"$selected_subvol"'/, /uuid='"$selected_uuid"'/ {cnt++} END {print cnt}')
|
||||
if [ -n "$count" ] && [ "$count" -gt 1 ]; then
|
||||
printf "%s entries are marked as '%s' for snapper config '%s'\n" \
|
||||
"$count" "$snap_description_synced" "$selected_config" | tee PIPE
|
||||
"$count" "$snap_description_synced" "$selected_config"
|
||||
printf "Pointing to target with UUID '%s' and SUBVOLID '%s'. Skipping configuration '%s'.\n" \
|
||||
"$selected_uuid" "$selected_subvol" "$selected_config"
|
||||
printf "Please cleanup for further processing.\n" | tee PIPE
|
||||
printf "Please cleanup for further processing.\n"
|
||||
error "Skipping configuration $selected_config."
|
||||
selected_configs=$(echo $selected_configs | sed -e "s/\($selected_config\)//")
|
||||
continue
|
||||
@@ -621,9 +625,9 @@ run_config () {
|
||||
snapper_target_config="snap-$selected_config"
|
||||
snapper_target_snapshot=$backup_root/$snapper_target_config/.snapshots/$snapper_new_id
|
||||
if [ -z "$remote" ]; then
|
||||
printf "Will backup %s to %s\n" "$snapper_new_snapshot" "$snapper_target_snapshot/snapshot" | tee $PIPE
|
||||
printf "Will backup %s to %s\n" "$snapper_new_snapshot" "$snapper_target_snapshot/snapshot"
|
||||
else
|
||||
printf "Will backup %s to %s\n" "$snapper_new_snapshot" "$remote":"$snapper_target_snapshot/snapshot" | tee $PIPE
|
||||
printf "Will backup %s to %s\n" "$snapper_new_snapshot" "$remote":"$snapper_target_snapshot/snapshot"
|
||||
fi
|
||||
|
||||
# save in config specific infos in pseudo Arrays
|
||||
@@ -769,7 +773,7 @@ run_backup () {
|
||||
# need to use source snapshot to provide metadata for target
|
||||
if [ ! "$dryrun" ]; then
|
||||
if [ "$verbose" ]; then
|
||||
printf "btrfs-send is using snapshot '%s' from source to read metadata ...\n" "$snapper_sync_snapshot" | tee $PIPE
|
||||
printf "btrfs-send is using snapshot '%s' from source to read metadata ...\n" "$snapper_sync_snapshot"
|
||||
fi
|
||||
cmd="btrfs send $verbose_flag -p $snapper_sync_snapshot $snapper_new_snapshot 2>$BTRFS_PIPE | $cmd_pv $ssh btrfs receive $verbose_flag $snapper_target_snapshot 2>BTRFS_PIPE"
|
||||
#$(eval $cmd)
|
||||
@@ -817,7 +821,7 @@ run_backup () {
|
||||
|
||||
run_finalize () {
|
||||
# Actual backing up
|
||||
printf "\nFinalize backups...\n" | tee $PIPE
|
||||
printf "\nFinalize backups...\n"
|
||||
|
||||
i=-1
|
||||
for selected_config in $selected_configs; do
|
||||
@@ -871,7 +875,7 @@ run_finalize () {
|
||||
if [ ! "$dryrun" ]; then
|
||||
# source snapshot
|
||||
if [ "$verbose" ]; then
|
||||
printf "Tagging snapper metadata on source for configuration '%s' ...\n" "$selected_config" | tee $PIPE
|
||||
printf "Tagging snapper metadata on source for configuration '%s' ...\n" "$selected_config"
|
||||
fi
|
||||
cmd="snapper --verbose --config \"$selected_config\" modify --description \"$snap_description_synced\" --userdata \"$userdata\" \"$snapper_new_id\""
|
||||
ret=$(eval $cmd)
|
||||
@@ -880,7 +884,7 @@ run_finalize () {
|
||||
|
||||
# target snapshot
|
||||
if [ "$verbose" ]; then
|
||||
printf "Tagging snapper metadata on target for configuration '%s' ...\n" "$selected_config" | tee $PIPE
|
||||
printf "Tagging snapper metadata on target for configuration '%s' ...\n" "$selected_config"
|
||||
fi
|
||||
i=1
|
||||
i_max=20
|
||||
@@ -1116,47 +1120,21 @@ verify_snapper_structure () {
|
||||
|
||||
# verify that we have a snapper compatible structure for selected config on target
|
||||
if $ssh [ ! -d $backup_root/$snapper_config ]; then
|
||||
if $ssh [ ! -f $SNAPPER_TEMPLATES/snap-sync ]; then
|
||||
printf "A snapper template %s to configure the snapper subvolume %s is missing in %s on %s.\n" "$snapper_snapsync_template" "$snapper_config" "$SNAPPER_TEMPLATES" "$remote_host"
|
||||
printf "Did you miss to install the snap-sync's default snapper template on %s?\n" "$remote"
|
||||
die "snapper template %s to configure the snapper subvolume %s is missing in %s on %s.\n" "$snapper_snapsync_template" "$snapper_config" "$SNAPPER_TEMPLATES" "$remote_host"
|
||||
if [ "$verbose" ]; then
|
||||
printf "Create new snapper capable BTRFS subvolume '%s:%s' ...\n" "$remote_host" "$backup_root/$snapper_config"
|
||||
fi
|
||||
if [ ! "$dryrun" ]; then
|
||||
if [ "$verbose" ]; then
|
||||
printf "Create new snapper capable subvolume in '%s:%s' ...\n" "$remote_host" "$backup_root/$snapper_config"
|
||||
# verify that we can use a snap-sync aware template
|
||||
if $ssh [ ! -f $SNAPPER_TEMPLATE_DIR/$snapper_snapsync_template ]; then
|
||||
printf "A snapper template %s to configure the snapper subvolume %s is missing in %s on %s.\n" "$snapper_snapsync_template" "$snapper_config" "$SNAPPER_TEMPLATE_DIR" "$remote_host"
|
||||
printf "Did you miss to install the snap-sync's default snapper template on %s?\n" "$remote"
|
||||
die "snapper template %s to configure the snapper subvolume %s is missing in %s on %s.\n" "$snapper_snapsync_template" "$snapper_config" "$SNAPPER_TEMPLATE_DIR" "$remote_host"
|
||||
fi
|
||||
|
||||
# notify if SUBVOLUME has changed
|
||||
create_config="btrfs subvolume create $backup_root/$snapper_config"
|
||||
$ssh $create_config || die "Snapper structure for config %s to hold target snapshots could not be created in directory on %s on %s.\n" "$snapper_config" "$backup_root" "$remote_host"
|
||||
|
||||
if $ssh [ ! -f /etc/snapper/configs/$snapper_config ]; then
|
||||
# snapper-logic will create $backup_root/$snapper_config/.snapshots
|
||||
$ssh snapper create-config $snapper-config --template $snapper_snapsync_template $backup_root/$snapper_config
|
||||
else
|
||||
# if changed, adapt targets SUBVOLUME in given config
|
||||
#get_config "/etc/snapper/configs/$snapper_config" "SUBVOLUME"
|
||||
if $ssh [ "$SUBVOLUME" != \"$backup_root/$snapper_config\" ]; then
|
||||
SUBVOLUME="$backup_root/$snapper_config"
|
||||
set_config "/etc/snapper/configs/$snapper_config" "SUBVOLUME" "$SUBVOLUME"
|
||||
cmd="btrfs subvolume create $backup_root/$snapper_config/$snapper_snapshots"
|
||||
$ssh $cmd || die "Can't create subvolume %s in %s to hold target snapshots.\n" "$snapper_snapshots" "$backup_root/$snapper_config"
|
||||
fi
|
||||
fi
|
||||
$ssh chmod 0700 $backup_root/$snapper_config
|
||||
sync
|
||||
if $ssh [ ! -d $backup_root/$snapper_subvol ]; then
|
||||
create_subvol="btrfs subvolume create $backup_root/$snapper_subvol"
|
||||
if $ssh [ $create_subvol ]; then
|
||||
if [ $verbose ]; then
|
||||
printf "Created BTRFS subvolume %s.\n" "$backup_root/$snapper_subvol"
|
||||
fi
|
||||
else
|
||||
die "Create BTRFS subvolume to hold snapshots on remote failed."
|
||||
fi
|
||||
fi
|
||||
$ssh snapper --config $snapper_subvol create-config --template $snapper_snapsync_template $backup_root/$snapper_subvol
|
||||
$ssh chmod 0700 $backup_root/$snapper_subvol
|
||||
# create the non existing remote BTRFS subvolume
|
||||
cmd="btrfs subvolume create $backup_root/$snapper_config"
|
||||
$ssh $cmd || die "Creation of BTRFS subvolume %s:%s failed.\n" "$remote_host" "$backup_root/$snapper_config"
|
||||
cmd="chmod 0700 $backup_root/$snapper_config"
|
||||
$ssh $cmd || die "Changing the directory mode for %s on %s failed.\n" "$backup_root/$snapper_config" "$remote_host"
|
||||
else
|
||||
printf "dryrun: Would create new snapper structure in '%s:%s' ...\n" "$backup_root/$snapper_config"
|
||||
printf "dryrun: Would create new snapper configuration from template %s ...\n" "$snapper_snapsync_template"
|
||||
@@ -1173,10 +1151,38 @@ verify_snapper_structure () {
|
||||
# SUBVOLUME="$backup_root/$snapper_config"
|
||||
# set_config "/etc/snapper/configs/$snapper_config" "SUBVOLUME" "$SUBVOLUME"
|
||||
#fi
|
||||
if $ssh [ ! -d $backup_root/$snapper_config/$snapper_snapshots ]; then
|
||||
cmd="btrfs subvolume create $backup_root/$snapper_config/$snapper_snapshots"
|
||||
$ssh $cmd || die "Can't create subvolume %s in %s to hold target snapshots.\n" "$snapper_snapshots" "$backup_root/$snapper_config"
|
||||
fi
|
||||
|
||||
# verify that we have a valid snapper config
|
||||
if [ ! "$dryrun" ]; then
|
||||
if $ssh [ ! -f $SNAPPER_CONFIG_DIR/$snapper_config ]; then
|
||||
# snapper-logic will create $backup_root/$snapper_config/.snapshots
|
||||
cmd="snapper --config $snapper_config create-config --template $snapper_snapsync_template --fstype btrfs $backup_root/$snapper_config"
|
||||
$ssh $cmd || die "Creation of snapper capable config %s on %s failed.\n" "$backup_root/$snapper_config" "$remote_host"
|
||||
else
|
||||
# verify if SUBVOLUME needs to be updated for given snapper config
|
||||
cmd="snapper list-configs | grep $snapper_config 1>/dev/null"
|
||||
if $ssh [ ! $(eval $cmd) ]; then
|
||||
# if changed, adapt targets SUBVOLUME path
|
||||
if [ $verbose ]; then
|
||||
printf "TODO: verify for SUBVOLUME update in %s\n" "$snapper_config"
|
||||
fi
|
||||
#get_config "/etc/snapper/configs/$snapper_config" "SUBVOLUME"
|
||||
#if $ssh [ "$SUBVOLUME" != \"$backup_root/$snapper_config\" ]; then
|
||||
# SUBVOLUME="$backup_root/$snapper_config"
|
||||
# set_config "/etc/snapper/configs/$snapper_config" "SUBVOLUME" "$SUBVOLUME"
|
||||
# cmd="btrfs subvolume create $backup_root/$snapper_config/$snapper_snapshots"
|
||||
# $ssh $cmd || die "Can't create subvolume %s in %s to hold target snapshots.\n" "$snapper_snapshots" "$backup_root/$snapper_config"
|
||||
#fi
|
||||
fi
|
||||
if $ssh [ ! -d $backup_root/$snapper_config/$snapper_snapshots ]; then
|
||||
cmd="btrfs subvolume create $backup_root/$snapper_config/$snapper_snapshots"
|
||||
$ssh $cmd || die "Can't create subvolume %s in %s to hold target snapshots.\n" "$snapper_snapshots" "$backup_root/$snapper_config"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
printf "dryrun: Would check/create for valid snapper config %s ...\n" \
|
||||
"$snapper_config"
|
||||
fi
|
||||
|
||||
# verify that target snapshot id can take the new snapshot data
|
||||
@@ -1248,11 +1254,11 @@ fi
|
||||
# select the target BTRFS subvol
|
||||
select_target_disk
|
||||
|
||||
printf "\nYou selected the disk with UUID %s (subvolid=%s).\n" "$selected_uuid" "$selected_subvol" | tee $PIPE
|
||||
printf "\nYou selected the disk with UUID %s (subvolid=%s).\n" "$selected_uuid" "$selected_subvol"
|
||||
if [ -z "$remote" ]; then
|
||||
printf "The disk is mounted at %s.\n" "$selected_target" | tee $PIPE
|
||||
printf "The disk is mounted at %s.\n" "$selected_target"
|
||||
else
|
||||
printf "The disk is mounted at %s:%s.\n" "$remote" "$selected_target" | tee $PIPE
|
||||
printf "The disk is mounted at %s:%s.\n" "$remote" "$selected_target"
|
||||
fi
|
||||
|
||||
# create and initialize structures for snapper configs
|
||||
@@ -1264,7 +1270,7 @@ run_backup
|
||||
# finalize backup tasks
|
||||
run_finalize
|
||||
|
||||
printf "\nDone!\n" | tee $PIPE
|
||||
printf "\nDone!\n"
|
||||
exec 3>&-
|
||||
|
||||
# cleanup
|
||||
|
||||
Reference in New Issue
Block a user