150 lines
4.2 KiB
Bash
Executable file
150 lines
4.2 KiB
Bash
Executable file
#!/bin/bash
|
|
|
|
SELF="$0"
|
|
HOST=""
|
|
PORT="22"
|
|
REMOTE_PATH=""
|
|
NAME=""
|
|
LOGIN="$(whoami)"
|
|
|
|
die() {
|
|
echo -e $1 | sed -e 's-^-! -' >&2
|
|
exit 1
|
|
}
|
|
usage() {
|
|
echo -e "usage: $SELF PROFILE_NAME --host=server --port=22 --login=backup-user --directory=/backup/path" >&2
|
|
exit 1
|
|
}
|
|
|
|
generate_passphrase() {
|
|
tr -dc A-Za-z0-9 </dev/urandom | head -c 64
|
|
}
|
|
init_config_dir() {
|
|
[ "x$HOST" == "x" ] && usage
|
|
|
|
install --directory --owner=$(id -u) --group=$(id -g) --mode=600 "$CONFIGDIR" || die "Can't create directory $CONFIGDIR"
|
|
|
|
umask 177
|
|
|
|
generate_passphrase > "$CONFIGDIR/borg_passphrase"
|
|
ssh-keygen -t ed25519 -N "" -q -f "$CONFIGDIR/ssh_key" -C "borg access from $(hostname --long)"
|
|
ssh-copy-id -i "$CONFIGDIR/ssh_key.pub" -p $PORT "$LOGIN@$HOST"
|
|
}
|
|
set_env_config() {
|
|
local file="$1"
|
|
local param="$2"
|
|
local value="$3"
|
|
|
|
# test current config
|
|
# file does not exist
|
|
[ ! -e $file ] && echo "$param=$value" >> $file
|
|
# file isn't readable
|
|
[ ! -r $file ] && die "Config file isn't readable: $file"
|
|
# file exists and value is set => early exit
|
|
local curr_line="$(grep "^$param=" $file)"
|
|
if [ "x$curr_line" == "x" ]; then
|
|
# file ist nicht änderbar
|
|
[ ! -w $file ] && die "Config file isn't writable: $file"
|
|
# param isn't set => append
|
|
echo "$param=$value" >> $file
|
|
elif [ "x${curr_line#$param=}" != "x$value" ]; then
|
|
# param is set with different value
|
|
die "Environment parameter '$param' is already set to '${curr_line#$param=}' in config file: $file\nPlease confirm that you know what you're doing by manually setting the parameter to the desired value '$value'."
|
|
fi
|
|
return 0
|
|
}
|
|
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() {
|
|
# do some sandboxinng
|
|
systemd-run --quiet --pipe --collect --unit=temp-borg-init-sandbox.service \
|
|
--working-directory=/tmp \
|
|
-p "ConfigurationDirectory=borg/$NAME" \
|
|
-p "CacheDirectory=borg/$NAME" \
|
|
-p "ConfigurationDirectoryMode=550" \
|
|
-p "CacheDirectoryMode=550" \
|
|
-p "PrivateTmp=yes" \
|
|
-p "ReadOnlyDirectories=/" \
|
|
-p "EnvironmentFile=/etc/borg/$NAME/config.env" \
|
|
--setenv=BORG_PASSPHRASE_FD=0 \
|
|
--setenv=BORG_BASE_DIR=/tmp/ \
|
|
--setenv=BORG_CONFIG_DIR=/etc/borg/$NAME \
|
|
--setenv=BORG_CACHE_DIR=/var/cache/borg/$NAME \
|
|
/usr/bin/borg $@ < /etc/borg/$NAME/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"
|
|
}
|
|
|
|
for arg in "$@"; do
|
|
case "$arg" in
|
|
-h*)
|
|
HOST="${arg#-h}"
|
|
;;
|
|
--host=*)
|
|
HOST="${arg#--host=}"
|
|
;;
|
|
-p*)
|
|
PORT="${arg#-p}"
|
|
;;
|
|
--port=*)
|
|
PORT="${arg#--port=}"
|
|
;;
|
|
-l*)
|
|
LOGIN="${arg#-l}"
|
|
;;
|
|
--login=*)
|
|
LOGIN="${arg#--login=}"
|
|
;;
|
|
-d*)
|
|
REMOTE_PATH="${arg#-d}"
|
|
;;
|
|
--directory=*)
|
|
REMOTE_PATH="${arg#--directory=}"
|
|
;;
|
|
-*)
|
|
usage
|
|
;;
|
|
*)
|
|
[ "x$NAME" == "x" ] || usage
|
|
NAME="$arg"
|
|
;;
|
|
esac
|
|
done
|
|
|
|
[ "x$NAME" == "x" ] && usage
|
|
[ "x$REMOTE_PATH" == "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
|
|
set_env_config "$CONFIGDIR/config.env" BORG_REPO "ssh://$LOGIN@$HOST:${PORT}${REMOTE_PATH}"
|
|
set_env_config "$CONFIGDIR/config.env" BORG_RSH "ssh -i $CONFIGDIR/ssh_key"
|
|
|
|
[ -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
|