#!/bin/bash ## Wrapper script running "btrbk" and sending email with results set -uf declare -A rsync_src rsync_dst rsync_log rsync_key rsync_opt now=$(date +%Y%m%d) ##### start config section ##### # Email recipients, separated by whitespace: mailto=$MAILTO # List of mountpoints to be mounted/unmounted (whitespace-separated) # mount_targets="/mnt/btr_pool /mnt/backup" mount_targets= umount_targets=$mount_targets # btrbk configuration file: config="/etc/btrbk/btrbk.conf" # Uncomment this if you only want to receive error messages: #btrbk_opts="-q" #skip_empty_mail=yes # Email subject: mail_subject_prefix="btrbk <${HOSTNAME:-localhost}>" # rsync declarations (repeat complete block for more declarations): rsync_src[example_data]=user@example.com:/data/ rsync_dst[example_data]=/mnt/backup/example.com/data/ rsync_log[example_data]=/mnt/backup/example.com/data-${now}.log rsync_key[example_data]=/mnt/backup/ssh_keys/id_rsa rsync_opt[example_data]="-az --delete" # Enabled rsync declarations (space separated list) #rsync_enable="example_data" rsync_enable= # Log level (1=error, 2=warn, 3=info) loglevel=2 ##### end config section ##### mail_body="" die() { echo "$0 FATAL: $1" 1>&2 echo "$0 FATAL: exiting" 1>&2 exit 1 } log_error() { [ $loglevel -ge 1 ] && echo "$0 ERROR: $1" 1>&2 ; } log_warning() { [ $loglevel -ge 2 ] && echo "$0 WARNING: $1" 1>&2 ; } log_info() { [ $loglevel -ge 3 ] && echo "$0 INFO: $1" 1>&2 ; } # # mount all mountpoints listed in $mount_targets # for mountpoint in $mount_targets; do $(findmnt -r -n -t btrfs $mountpoint 1>&2) if [ $? = 0 ]; then log_warning "btrfs filesystem already mounted: $mountpoint" else log_info "mount $mountpoint" $(mount --target $mountpoint 1>&2) [ $? = 0 ] || log_error "mount failed: $mountpoint" fi done # # run rsync for all $rsync_enable # for key in $rsync_enable; do log_info "starting rsync: $key" [ -n "${rsync_src[$key]}" ] || die "rsync_src is not set for \"$key\"" [ -n "${rsync_dst[$key]}" ] || die "rsync_dst is not set for \"$key\"" [ -n "${rsync_log[$key]}" ] || die "rsync_log is not set for \"$key\"" [ -n "${rsync_key[$key]}" ] || die "rsync_key is not set for \"$key\"" [ -n "${rsync_opt[$key]}" ] || die "rsync_opt is not set for \"$key\"" rsync_header="### rsync ${rsync_opt[$key]} ${rsync_src[$key]} ${rsync_dst[$key]}" if [ -d ${rsync_dst[$key]} ]; then echo "$rsync_header" >> ${rsync_log[$key]} ret=$(rsync ${rsync_opt[$key]} --info=STATS --log-file=${rsync_log[$key]} -e "ssh -i ${rsync_key[$key]}" ${rsync_src[$key]} ${rsync_dst[$key]}) if [ $? != 0 ]; then log_error "rsync failed: $key" ret+="\nERROR: rsync failed with exit code $?\n" fi mail_body+="$rsync_header$ret\n\n" else ret="rsync destination directory not found for \"$key\", skipping: ${rsync_dst[$key]}" mail_body+="$rsync_header\n$ret\n\n" log_error "$ret" fi done # # run btrbk # log_info "running btrbk" ret=$(btrbk -c "$config" ${btrbk_opts:-} run 2>&1) exitcode=$? case $exitcode in 0) status="All backups successful" ;; 10) status="ERROR: At least one backup task aborted!" ;; *) status="ERROR: btrbk failed with error code $exitcode" ;; esac mail_body+=$ret if [ "${skip_empty_mail:-no}" = "yes" ] && [ -z "$mail_body" ] && [ $exitcode -eq 0 ]; then : # skip email sending if skip_empty_mail=yes else # send email echo -e "$mail_body" | mail -s "$mail_subject_prefix - $status" $mailto if [ $? != 0 ]; then log_error "failed to send btrbk mail to \"$mailto\", dumping mail body:" echo -e "$mail_body" 1>&2 fi fi # # sync all mountpoints listed in $umount_targets # # exit on failure! #for mountpoint in $umount_targets; do # log_info "btrfs filesystem sync $mountpoint" # $(btrfs filesystem sync $mountpoint 1>&2) # [ $? = 0 ] || die "btrfs filesystem sync failed: $mountpoint" # sleep 1 #done # # unmount all mountpoints listed in $umount_targets # for mountpoint in $umount_targets; do log_info "umount $mountpoint" $(umount $mountpoint 1>&2) [ $? = 0 ] || log_error "umount failed: $mountpoint" done