aboutsummaryrefslogtreecommitdiff
path: root/borger
diff options
context:
space:
mode:
Diffstat (limited to 'borger')
-rwxr-xr-xborger170
1 files changed, 170 insertions, 0 deletions
diff --git a/borger b/borger
new file mode 100755
index 0000000..990c493
--- /dev/null
+++ b/borger
@@ -0,0 +1,170 @@
+#!/bin/bash
+#
+# Borg script for home folder backups.
+# Adapted from https://borgbackup.readthedocs.io/en/stable/quickstart.html#automating-backups
+#
+# Example config to be put at ~/.config/borger/destination-name:
+#
+# # Backup destination
+# export SSH_SERVER="user@host"
+# export SSH_PORT="2202"
+#
+# # Repository path
+# export BORG_REPO_DIR="/var/backups/users/$USER/borg"
+# export BORG_REPO="ssh://$SSH_SERVER:$SSH_PORT/$BORG_REPO_DIR"
+#
+# # Setting this, so you won't be asked for your repository passphrase:
+# #export BORG_PASSPHRASE='HACKME'
+# #export BORG_PASSCOMMAND='pass show backup'
+# #export BORG_PASSCOMMAND='keyringer default decrypt pessoal/backups/borg 2> /dev/null'
+#
+# # Backup config
+# keepdaily="7"
+# keepweekly="4"
+# keepmonth="6"
+# encryption="keyfile"
+# placeholder="{user}"
+
+# Parameters
+BASENAME="`basename $0`"
+DESTINATION="$1"
+OPTION="$2"
+BASE_CONFIG="$HOME/.config/borger"
+CONFIG="$BASE_CONFIG/$DESTINATION"
+
+# Print info
+function info {
+ printf "[$BASENAME] [%s] %s\n" "$(date)" "$*" >&2;
+}
+
+# Fata error
+function fatal {
+ info [fatal] $*
+ exit 1;
+}
+
+function borger_usage {
+ # Ensure we have our base config folder
+ mkdir -p $BASE_CONFIG
+
+ # List available targets
+ if [ -z "$DESTINATION" ]; then
+ echo "usage: $BASENAME <destination> [--check]"
+ echo -n "available destinations from $BASE_CONFIG: "
+ ls $BASE_CONFIG
+ exit 1
+ fi
+}
+
+# Config
+function borger_config {
+ # Ensure we have an username
+ if [ -z "$USER" ]; then
+ USER="`whoami`"
+ fi
+
+ # In case your home folder is a symlink
+ if [ ! -z "`readlink $HOME`" ]; then
+ ORIG="`readlink $HOME`"
+ else
+ ORIG="$HOME"
+ fi
+
+ # Default backup config
+ keepdaily="7"
+ keepweekly="4"
+ keepmonth="6"
+ encryption="keyfile"
+ placeholder="{user}"
+
+ if [ -e "$CONFIG" ] ; then
+ source $CONFIG
+ else
+ fatal "No such config $CONFIG"
+ fi
+
+ # Setting this, so the repo does not need to be given on the commandline:
+ if [ -z "$BORG_REPO" ]; then
+ export BORG_REPO_DIR="/var/backups/users/$USER/borg"
+ export BORG_REPO="ssh://$SSH_SERVER:$SSH_PORT/$BORG_REPO_DIR"
+ fi
+}
+
+# Check
+function borger_check {
+ if [ "$OPTION" == "--check" ]; then
+ borg list
+ exit $?
+ fi
+}
+
+# Our trap
+function borger_trap {
+ trap 'info Backup interrupted >&2; exit 2' INT TERM
+}
+
+# Initialize
+function borger_init {
+ if ! ssh $SSH_SERVER -p $SSH_PORT test -f $BORG_REPO_DIR/config; then
+ info "Initializing borg repository at $BORG_REPO..."
+ borg init --encryption=$encryption $BORG_REPO
+
+ init_exit=$?
+
+ if [ "$init_exit" != "0" ]; then
+ fatal "Error initializing repository"
+ fi
+ fi
+}
+
+# Backup the most important directories into an archive named after
+# the machine this script is currently running on:
+function borger_create {
+ info "Starting backup..."
+
+ borg create \
+ --verbose \
+ --filter AME \
+ --list \
+ --stats \
+ --show-rc \
+ --compression lz4 \
+ --exclude-caches \
+ ::"${placeholder}-{now}" \
+ $ORIG
+
+ backup_exit=$?
+
+ if [ "$backup_exit" != "0" ]; then
+ fatal "Error creating snapshot"
+ fi
+}
+
+# Use the `prune` subcommand to maintain daily, weekly and monthly archives.
+# The '${placeholder}-' prefix is very important to limit prune's operation to
+# one specific archive and not apply to archives also.
+function borger_prune {
+ info "Pruning repository..."
+ borg prune \
+ --list \
+ --prefix "${placeholder}-" \
+ --show-rc \
+ --keep-daily $keepdaily \
+ --keep-weekly $keepweekly \
+ --keep-monthly $keepmonthly \
+
+ prune_exit=$?
+
+ if [ "$prune_exit" != "0" ]; then
+ fatal "Error pruning repository"
+ fi
+}
+
+# Main
+borger_usage
+borger_config
+borger_check
+borger_trap
+borger_init
+borger_create
+borger_prune