#!/usr/bin/env bash # called before backup borgwrapper_pre_backup() { return; } # called after backup borgwrapper_post_backup() { return; } # usage usage() { USAGE=$(cat <'. EOF ) echo "$USAGE"; } set -e; # helper functions source_config() { local config=$1; local configFallback=$2; if [[ ! -f "$config" ]]; then if [[ ! -f "$configFallback" ]]; then echo "No config file specified and could not find default in '${configFallback}'!"; echo ""; usage; exit 1; else config=${configFallback}; fi fi set -a; source "${config}"; set +a; } apply_defaults() { [ -z ${BORGWRAPPER_BACKUP_PASSWORD} ] && BORGWRAPPER_BACKUP_PASSWORD=''; [ -z ${BORGWRAPPER_BACKUP_TIMESTAMP_FORMAT} ] && BORGWRAPPER_BACKUP_TIMESTAMP_FORMAT=$(date "+%s"); [ -z ${BORGWRAPPER_BACKUP_PRUNE} ] && BORGWRAPPER_BACKUP_PRUNE=true; [ -z ${BORGWRAPPER_BACKUP_KEEP_IN_DAYS} ] && BORGWRAPPER_BACKUP_KEEP_IN_DAYS=60; [ -z ${BORGWRAPPER_BACKUP_CHECK} ] && BORGWRAPPER_BACKUP_CHECK=true; [ -z ${BORGWRAPPER_BACKUP_CHECK_MAX_AGE_IN_SECONDS} ] && BORGWRAPPER_BACKUP_CHECK_MAX_AGE_IN_SECONDS=604800; [ -z ${BORGWRAPPER_BACKUP_CHECK_FILE} ] && BORGWRAPPER_BACKUP_CHECK_FILE="$HOME/.borg-backup-${BORGWRAPPER_BACKUP_NAME}.check"; [ -z ${BORGWRAPPER_BACKUP_LOG} ] && BORGWRAPPER_BACKUP_LOG=true; [ -z ${BORGWRAPPER_BACKUP_LOG_PRUNE} ] && BORGWRAPPER_BACKUP_LOG_PRUNE=true; [ -z ${BORGWRAPPER_BACKUP_LOG_FILE} ] && BORGWRAPPER_BACKUP_LOG_FILE="$HOME/.borg-backup-${BORGWRAPPER_BACKUP_NAME}.log"; [ -z ${BORGWRAPPER_BACKUP_NOTIFY_VIA_MAIL} ] && BORGWRAPPER_BACKUP_NOTIFY_VIA_MAIL=false; [ -z ${BORGWRAPPER_BACKUP_NOTIFY_MAIL_ADDRESS} ] && BORGWRAPPER_BACKUP_NOTIFY_MAIL_ADDRESS=""; [ -z ${BORGWRAPPER_BACKUP_NOTIFY_UI} ] && BORGWRAPPER_BACKUP_NOTIFY_UI=false; [ -z ${BORGWRAPPER_BACKUP_COMPRESSION} ] && BORGWRAPPER_BACKUP_COMPRESSION=lz4; [ -z ${BORGWRAPPER_BACKUP_ENCRYPTION} ] && BORGWRAPPER_BACKUP_ENCRYPTION=none; [ -z ${BORGWRAPPER_BORG_BINARY} ] && BORGWRAPPER_BORG_BINARY=$(which borg); [ -z ${BORGWRAPPER_BORG_INIT_PARAMS} ] && BORGWRAPPER_BORG_INIT_PARAMS="--encryption=${BORGWRAPPER_BACKUP_ENCRYPTION}"; [ -z ${BORGWRAPPER_BORG_CREATE_PARAMS} ] && BORGWRAPPER_BORG_CREATE_PARAMS="-v -s -p -C ${BORGWRAPPER_BACKUP_COMPRESSION}"; [ -z ${BORGWRAPPER_BORG_CHECK_PARAMS} ] && BORGWRAPPER_BORG_CHECK_PARAMS="-v"; [ -z ${BORGWRAPPER_BORG_PRUNE_PARAMS} ] && BORGWRAPPER_BORG_PRUNE_PARAMS="-v -s -d ${BORGWRAPPER_BACKUP_KEEP_IN_DAYS}"; } # check for config file and use it source_config "$1" "${HOME}/.borgwrapper.conf"; apply_defaults; # start and info echo "Using ${BORGWRAPPER_BORG_BINARY} as binary"; borgwrapper_pre_backup; # export passphrase if not blank if [ ! -z "${BORGWRAPPER_BACKUP_PASSWORD}" ]; then export BORG_PASSPHRASE=${BORGWRAPPER_BACKUP_PASSWORD}; fi # init hint echo "Hint: If you haven't, you need to create the borg repository manually before first run if it doesn't exist:"; echo "${BORGWRAPPER_BORG_BINARY} init ${BORGWRAPPER_BORG_INIT_PARAMS} ${BORGWRAPPER_BACKUP_REPOSITORY}${BORGWRAPPER_BACKUP_NAME}"; # notify UI if [ "${BORGWRAPPER_BACKUP_NOTIFY_UI}" = true ]; then notify-send "Starting backup" ${BORGWRAPPER_BACKUP_REPOSITORY}${BORGWRAPPER_BACKUP_NAME}::${BORGWRAPPER_BACKUP_TIMESTAMP_FORMAT}; fi # create ${BORGWRAPPER_BORG_BINARY} create ${BORGWRAPPER_BORG_CREATE_PARAMS} ${BORGWRAPPER_BACKUP_REPOSITORY}${BORGWRAPPER_BACKUP_NAME}::${BORGWRAPPER_BACKUP_TIMESTAMP_FORMAT} "${BORGWRAPPER_BACKUP_FILES[@]}"; # check if [ "${BORGWRAPPER_BACKUP_CHECK}" = true ]; then # use for first time creation doCheck=false if [ ! -f "${BORGWRAPPER_BACKUP_CHECK_FILE}" ]; then touch ${BORGWRAPPER_BACKUP_CHECK_FILE} doCheck=true fi # compare date lastMod=$(date -r ${BORGWRAPPER_BACKUP_CHECK_FILE} +%s) age=$((${BORGWRAPPER_BACKUP_TIMESTAMP_FORMAT} - ${lastMod})) if [ "$age" -gt "${BORGWRAPPER_BACKUP_CHECK_MAX_AGE_IN_SECONDS}" ]; then doCheck=true fi if [ "$doCheck" = true ]; then ${BORGWRAPPER_BORG_BINARY} check ${BORGWRAPPER_BORG_CHECK_PARAMS} ${BORGWRAPPER_BACKUP_REPOSITORY}${BORGWRAPPER_BACKUP_NAME}; touch ${BORGWRAPPER_BACKUP_CHECK_FILE} fi fi # prune if [ "${BORGWRAPPER_BACKUP_PRUNE}" = true ]; then ${BORGWRAPPER_BORG_BINARY} prune ${BORGWRAPPER_BORG_PRUNE_PARAMS} ${BORGWRAPPER_BACKUP_REPOSITORY}${BORGWRAPPER_BACKUP_NAME}; fi # log if [ "${BORGWRAPPER_BACKUP_LOG}" = true ]; then if [ "${BORGWRAPPER_BACKUP_LOG_PRUNE}" = true ] && [ -f "${BORGWRAPPER_BACKUP_LOG_FILE}" ]; then rm ${BORGWRAPPER_BACKUP_LOG_FILE}; fi touch ${BORGWRAPPER_BACKUP_LOG_FILE}; ${BORGWRAPPER_BORG_BINARY} list -v ${BORGWRAPPER_BACKUP_REPOSITORY}${BORGWRAPPER_BACKUP_NAME} >> ${BORGWRAPPER_BACKUP_LOG_FILE}; echo "---" >> ${BORGWRAPPER_BACKUP_LOG_FILE}; ${BORGWRAPPER_BORG_BINARY} info ${BORGWRAPPER_BACKUP_REPOSITORY}${BORGWRAPPER_BACKUP_NAME}::${BORGWRAPPER_BACKUP_TIMESTAMP_FORMAT} >> ${BORGWRAPPER_BACKUP_LOG_FILE}; if [ "${BORGWRAPPER_BACKUP_NOTIFY_VIA_MAIL}" = true ]; then cat ${BORGWRAPPER_BACKUP_LOG_FILE}|mailx -Ssendwait -s "[borgwrapper ${BORGWRAPPER_BACKUP_NAME}]" ${BORGWRAPPER_BACKUP_NOTIFY_MAIL_ADDRESS}; fi fi # notify UI if [ "${BORGWRAPPER_BACKUP_NOTIFY_UI}" = true ]; then notify-send "Finished backup" ${BORGWRAPPER_BACKUP_REPOSITORY}${BORGWRAPPER_BACKUP_NAME}::${BORGWRAPPER_BACKUP_TIMESTAMP_FORMAT}; fi borgwrapper_post_backup;