#!/bin/bash ################################################################################ # Backup Script # ------------- # # This script orchestrates and performs system backups with borg according to # the environment variables in config/backup and .borgenv files per borg # repository you wish to backup to. This script assumes two backups for each # repository, splitting up the base operating system (debian) and the zfs array # (zfs) which can be custom named in the config file. # # EXPECT THESE BACKUP SCRIPTS TO CHANGE IN THE NEAR FUTURE! # # Author: Robin Meier - robin@meier.si ################################################################################ # Load configuration script_dir=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) set -o allexport source ${script_dir}/config/backup > /dev/null 2>&1 set +o allexport # Import logging functionality logfile=${script_dir}/log/backup.log log_identifier="BACKUP" source ${script_dir}/functions/logging.sh # Check if executables installed EXEC_DEPS="borg grep sed zfs tac mount umount" if ! which $EXEC_DEPS >/dev/null 2>&1; then log_echo "Missing executables! ($EXEC_DEPS)" >&2 exit 9 fi log "Backup Script Started" # Run backup preparations (scripts for db dumps etc.) ${script_dir}/backup_preparations.sh # Check preparations exit code prep_exit=$? if [[ $prep_exit > 0 ]]; then log_echo "Preparations failed with exit code $prep_exit" echo -n "Preparations failed with exit code $prep_exit" | ${script_dir}/helpers/tg_notify.sh # Do not continue with the backup exit $prep_exit fi SNAPSHOT_TIMESTAMP=$(date +%Y%m%d%H%M%S) # Make sure this is digits only or adapt regex below # Create ZFS Snapshots for DS in $BORG_ZFS_DATASETS; do zfs snapshot -r "$DS@$SNAPSHOT_TIMESTAMP" done # Mount snapshots under $ZFS_SNAPSHOT_MOUNTPOINT for SNAP in $(zfs list -t snapshot -o name | grep "$SNAPSHOT_TIMESTAMP"); do SNAP_MOUNTPOINT="$ZFS_SNAPSHOT_MOUNTPOINT/$(sed 's/@[[:digit:]]\+$//' <<< "$SNAP")" log "Mount $SNAP at $SNAP_MOUNTPOINT" mkdir -p "$SNAP_MOUNTPOINT" mount -t zfs "$SNAP" "$SNAP_MOUNTPOINT" done # Run backup script for each configuration global_exit=0 for BORG_ENV in $BORG_DESTINATION_ENV_FILES; do log "BORG Backup for $BORG_ENV" if [[ ! -f "$BORG_ENV" ]]; then # Exit if given env file does not exist exit 8 fi set -o allexport source $BORG_ENV set +o allexport log "Backup debian system..." ${script_dir}/backup_borg.sh debian $(date +%Y%m%d%H%M%S) "$BORG_DEBIAN_DIRS" "--exclude=var/tmp/* --exclude=var/lib/docker" &>> $logfile system_exit=$? log "Backupped debian system (exit code: $system_exit)" if [[ $system_exit -gt 1 ]]; then log_echo "System backup failed with error code $system_exit" echo -n "System backup failed with error code $system_exit" | ${script_dir}/helpers/tg_notify.sh fi log "Backup zfs array" ${script_dir}/backup_borg.sh ${ZFS_ARRAY_NAME:-zfs} $SNAPSHOT_TIMESTAMP "$ZFS_SNAPSHOT_MOUNTPOINT" "" &>> $logfile zfs_exit=$? log "Backupped zfs array (exit code: $zfs_exit)" if [[ $zfs_exit -gt 0 ]]; then log_echo "ZFS Array Backup Failed with Warning or Error (Exit Code: $external_exit)" echo -n "ZFS Array Backup Failed with Warning or Error (Exit Code: $external_exit)" | ${script_dir}/helpers/tg_notify.sh fi borg_env_exit=$(( system_exit > zfs_exit ? system_exit : zfs_exit )) global_exit=$(( borg_env_exit > global_exit ? borg_env_exit : global_exit )) done # # Wait file for inspecting of /mnt/snapshot # touch /mnt/snapshot/wait_file # while : ; do # [[ ! -f "/mnt/snapshot/wait_file" ]] && break # log_echo "Waiting.." # sleep 2 # done # Unmount snapshots in reverse order (tac reverses lines) for SNAP in $(zfs list -t snapshot -o name | grep "$SNAPSHOT_TIMESTAMP" | tac); do log "Unmount $SNAP" umount "$SNAP" done # Destroy snapshots (recursive) for each dataset for DS in $BORG_ZFS_DATASETS; do log "Destroy snapshot $DS" zfs destroy -r "$DS@$SNAPSHOT_TIMESTAMP" done log "Backup Script Finished ($global_exit)" exit $global_exit