admin-scripts/backup.sh

123 lines
4.0 KiB
Bash
Executable File

#!/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