backup-local-dir/backup-local-dir

263 lines
4.6 KiB
Bash
Executable File

#!/bin/bash
#
log()
{
logger "[Backup Local Dir] $1"
echo "[Backup Local Dir] $1"
}
notify()
{
notify-send "[Backup Local Dir] $1"
log "$1"
}
complain()
{
logger -s "[Backup Local Dir] $1"
notify-send "[Backup Local Dir] $1"
}
die()
{
complain "Fatal: $1"
echo
sleep 600
exit 1
}
quit()
{
local MSG="$1"
if [ "$MSG" = "" ] ; then
log "Quitting ..."
else
log "Quitting: ${MSG}"
fi
echo
sleep 120
exit 0
}
heading()
{
echo
log "******************************"
log "******************************"
log "********** $1"
log "******************************"
log "******************************"
}
list_snapshots()
{
local REPO="$1"
echo
log "Listing snapshots for: ${REPO}"
restic snapshots -r "${REPO}"
if [ "$?" -ne 0 ] ; then
die "Failed to list snapshots for repo!: ${REPO}"
fi
echo
}
do_backup()
{
local REPO="$1"
local LOCAL_DIR="$2"
list_snapshots "${REPO}"
local COMMAND=""
COMMAND+="restic backup"
COMMAND+=" -r \"${REPO}\""
COMMAND+=" \"${LOCAL_DIR}\""
COMMAND+=" --exclude='.sync_*'"
if [ "$RESTIC_TAG" != "" ] ; then
COMMAND+=" --tag \"${RESTIC_TAG}\""
fi
log "Backing up local dir \"${LOCAL_DIR}\" to: ${REPO}"
log "Using command: "
log "$COMMAND"
eval "${COMMAND}"
if [ "$?" -ne 0 ] ; then
die "Failed to backup!: \"${LOCAL_DIR}\" to \"${REPO}\""
fi
log "Backup was successful"
list_snapshots "${REPO}"
}
forget_snapshots()
{
local REPO="$1"
local WITHIN="$2"
local COMMAND=""
COMMAND+="restic forget"
COMMAND+=" -r \"${REPO}\""
COMMAND+=" --keep-within \"${WITHIN}\""
if [ "$RESTIC_TAG" != "" ] ; then
COMMAND+=" --tag \"${RESTIC_TAG}\""
fi
log "Forgetting snapshots older than \"${WITHIN}\" from: ${REPO}"
log "Using command:"
log "$COMMAND"
eval "$COMMAND"
if [ "$?" -ne 0 ] ; then
die "Failed to forget snapshots!"
fi
}
prune_repo()
{
local REPO="$1"
#
log "Pruning repository: ${REPO}"
restic -r "${REPO}" prune
}
#
LOCAL_DIR=""
RESTIC_REPOSITORY=""
RESTIC_REPOSITORY_REMOTE=""
RESTIC_PASSWORD=""
RESTIC_FORGET_KEEP_WITHIN="3m"
RESTIC_TAG=""
#
log "Begin parsing arguments ..."
while [ "${#}" -gt 0 ]
do
ARG="$1"
shift
case "$ARG" in
--help|-h)
log
log "*** Backup Local Directory - Help Menu ***"
log "A simple utility to help backup a local directory to a restic repo"
log
log "--local ==> Specify local directory (Currently: \"${LOCAL_DIR}\")"
log "--repo ==> Specify restic repo for backup destination (Currently: \"${RESTIC_REPOSITORY}\")"
log "--repo-remote ==> Specify remote restic repo for backup destination (Currently: \"${RESTIC_REPOSITORY_REMOTE}\") (consult restic docs for format)"
log "--tag ==> Specify a tag to associate with this backup (Currently: \"${RESTIC_TAG}\")"
log
;;
--local|--local-dir|--dir|-l|-d)
LOCAL_DIR="$1"
log "Found cloud dir argument: $LOCAL_DIR"
shift
;;
--repo|--restic|--restic-repo|-r)
RESTIC_REPOSITORY="$1"
log "Found restic repo argument: ${RESTIC_REPOSITORY}"
shift
;;
--repo-remote|--restic-remote|--restic-repo-remote|-rr)
RESTIC_REPOSITORY_REMOTE="$1"
log "Found restic repo argument: ${RESTIC_REPOSITORY_REMOTE}"
shift
;;
--tag|-t)
RESTIC_TAG="$1"
log "Found tag argument: ${RESTIC_TAG}"
shift
;;
--password|--restic-password|--restic-repo-password|--repo-password|-p)
RESTIC_PASSWORD="$1"
log "Found restic repo password argument."
shift
;;
*)
die "Unexpected argument: $ARG"
;;
esac
done
log "Finished parsing arguments"
# Local dir should be set
if [ "$LOCAL_DIR" = "" ] ; then
die "Local dir should be set"
elif [ ! -d "$LOCAL_DIR" ] ; then
die "Local dir should be a valid directory: ${LOCAL_DIR}"
fi
# Restic repo should be set
if [ "$RESTIC_REPOSITORY" = "" ] ; then
die "Restic repo should be set"
fi
# Remote restic repo should be set
if [ "$RESTIC_REPOSITORY_REMOTE" = "" ] ; then
die "Remote restic repo should be set"
fi
# Password shouldn't be blank
if [ "$RESTIC_PASSWORD" = "" ] ; then
die "Restic repo password should be set"
fi
# Export for restic
export RESTIC_PASSWORD
# Backup locally
heading "Local Backup"
do_backup "${RESTIC_REPOSITORY}" "${LOCAL_DIR}"
# Backup to another cloud
heading "Remote Backup"
do_backup "${RESTIC_REPOSITORY_REMOTE}" "${LOCAL_DIR}"
# Forget old snapshots
heading "Forget old snapshots"
forget_snapshots "${RESTIC_REPOSITORY}" "${RESTIC_FORGET_KEEP_WITHIN}"
forget_snapshots "${RESTIC_REPOSITORY_REMOTE}" "${RESTIC_FORGET_KEEP_WITHIN}"
# Prune
heading "Pruning repositories"
prune_repo "${RESTIC_REPOSITORY}"
prune_repo "${RESTIC_REPOSITORY_REMOTE}"
#
notify "Finished!"
quit "Finished!"