#!/bin/bash SELF="$0" HOST="" PORT="22" REMOTE_PATH="borg" NAME="" LOGIN="$(whoami)" die () { echo $1 >&2 exit 1 } generate_passphrase() { tr -dc A-Za-z0-9 "$CONFIGDIR/borg_passphrase" ssh-keygen -t ed25519 -N "" -q -f "$CONFIGDIR/ssh_key" -C "borg access from $(hostname --long)" exec ssh-copy-id -i "$CONFIGDIR/ssh_key.pub" -p $PORT "$LOGIN@$HOST" } test_ssh() { ssh -q -o "BatchMode=yes" -i "$CONFIGDIR/ssh_key" -p "$PORT" "$LOGIN@$HOST" "mkdir -p $REMOTE_PATH" \ || die "SSH connection attempt failed." return 0 } test_repo_exists() { ssh -q -o "BatchMode=yes" -i "$CONFIGDIR/ssh_key" -p "$PORT" "$LOGIN@$HOST" "cat $REMOTE_PATH/README" 2>/dev/null | grep -q "This is a Borg Backup repository." return $? } invoke_borg() { ( export BORG_RSH="ssh -i $CONFIGDIR/ssh_key" export BORG_REPO="ssh://$LOGIN@$HOST:${PORT}${REMOTE_PATH}" export BORG_PASSPHRASE_FD=0 exec /usr/bin/borg $@ < "$CONFIGDIR/borg_passphrase" ) } init_repo() { echo "> init repo" invoke_borg init -e repokey-blake2 || die "failed to init borg repo" } show_repo() { echo "> testing repo connection" invoke_borg info || die "failed to access borg repo" } usage() { die "Usage: $SELF PROFILE_NAME --host=server --port=22 --login=backup-user --directory=/backup/path" } for arg in "$@"; do case "$arg" in -p*) PORT="${arg#-p}" ;; --port=*) PORT="${arg#--port=}" ;; -l*) LOGIN="${arg#-l}" ;; --login=*) LOGIN="${arg#--login=}" ;; -h*) HOST="${arg#-h}" ;; --host=*) HOST="${arg#--host=}" ;; -d*) REMOTE_PATH="${arg#-d}" ;; --directory=*) REMOTE_PATH="${arg#--directory=}" ;; -*) usage ;; *) NAME="$arg" esac done [ "x$NAME" == "x" ] && usage CONFIGDIR="/etc/borg/$NAME" echo "> checking config" [ -e "$CONFIGDIR" ] || init_config_dir || die "Failed setting up config directory and ssh connection" [ -d "$CONFIGDIR" ] || die "Config directory isn't valid: $CONFIGDIR" [ -r "$CONFIGDIR/borg_passphrase" ] || die "File isn't readable: $CONFIGDIR/borg_passphrase" [ -r "$CONFIGDIR/ssh_key" ] || die "File isn't readable: $CONFIGDIR/ssh_key" # write config every time, parameter may change with each invocation echo "BORG_REPO=ssh://$LOGIN@$HOST:${PORT}${REMOTE_PATH}" > "$CONFIGDIR/config.env" [ -r "$CONFIGDIR/config.env" ] || die "File isn't readable: $CONFIGDIR/config.env" echo "> testing ssh and destination path" test_ssh || die "Can't establish ssh connection! Try: ssh-copy-id -i $CONFIGDIR/ssh_key.pub -p $PORT $LOGIN@$HOST" echo "> testing borg repo" test_repo_exists || init_repo show_repo