mirror of
https://0xacab.org/liberate/backupninja.git
synced 2024-11-08 20:02:32 +01:00
3d7494bfc2
This enables the handlers to be used for hosts which use a non-standard port, such as is offered by some commercial services. Default to port 22, so it's optional and backwards-compatible.
394 lines
12 KiB
Bash
394 lines
12 KiB
Bash
# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*-
|
|
# vim: set filetype=sh sw=3 sts=3 expandtab autoindent:
|
|
#
|
|
# Copyright 2016 Benjamin Maisonnas <ben@wainei.net>
|
|
#
|
|
# This work is free. You can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation; either version 2 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
|
|
HELPERS="$HELPERS borg:deduplicated_archive_based_backup"
|
|
|
|
declare -a borg_includes
|
|
declare -a borg_excludes
|
|
|
|
# FUNCTIONS
|
|
|
|
do_borg_host_includes() {
|
|
set -o noglob
|
|
# choose the files to backup
|
|
REPLY=
|
|
while [ -z "$REPLY" ]; do
|
|
formBegin "$borg_title - host system: includes"
|
|
for ((i=0; i < ${#borg_includes[@]} ; i++)); do
|
|
formItem include ${borg_includes[$i]}
|
|
done
|
|
formItem include
|
|
formItem include
|
|
formItem include
|
|
formItem include
|
|
formItem include
|
|
formItem include
|
|
formItem include
|
|
formItem include
|
|
formDisplay
|
|
[ $? = 0 ] || return
|
|
unset borg_includes
|
|
borg_includes=($REPLY)
|
|
done
|
|
set +o noglob
|
|
}
|
|
|
|
do_borg_excludes() {
|
|
set -o noglob
|
|
formBegin "$borg_title: host system: excludes"
|
|
for ((i=0; i < ${#borg_excludes[@]} ; i++))
|
|
do
|
|
formItem exclude ${borg_excludes[$i]}
|
|
done
|
|
formItem exclude
|
|
formItem exclude
|
|
formItem exclude
|
|
formItem exclude
|
|
formItem exclude
|
|
formItem exclude
|
|
formItem exclude
|
|
formItem exclude
|
|
formDisplay
|
|
[ $? = 0 ] || return
|
|
unset borg_excludes
|
|
borg_excludes=($REPLY)
|
|
set +o noglob
|
|
}
|
|
|
|
do_borg_src() {
|
|
do_borg_host_includes
|
|
[ $? = 0 ] || return 1
|
|
|
|
do_borg_excludes
|
|
[ $? = 0 ] || return 1
|
|
|
|
_src_done="(DONE)"
|
|
setDefault dest
|
|
}
|
|
|
|
do_borg_dest() {
|
|
declare -a tmp_array
|
|
|
|
set -o noglob
|
|
REPLY=
|
|
while [ -z "$REPLY" -o -z "$borg_directory" -o -z "$borg_host" -o -z "$borg_port" -o -z "$borg_user" -o -z "$borg_archive" -o -z "$borg_compression" ]
|
|
do
|
|
formBegin "$borg_title - destination"
|
|
formItem "directory" "$borg_directory"
|
|
formItem "host" "$borg_host"
|
|
formItem "port" "$borg_port"
|
|
formItem "user" "$borg_user"
|
|
formItem "archive_name" "$borg_archive"
|
|
formItem "compression" "$borg_compression"
|
|
|
|
formDisplay
|
|
[ $? = 0 ] || return
|
|
tmp_array=($REPLY)
|
|
borg_directory=${tmp_array[0]}
|
|
borg_host=${tmp_array[1]}
|
|
borg_port=${tmp_array[2]}
|
|
borg_user=${tmp_array[3]}
|
|
borg_archive=${tmp_array[4]}
|
|
borg_compression=${tmp_array[5]}
|
|
done
|
|
set +o noglob
|
|
|
|
_dest_done="(DONE)"
|
|
setDefault conn
|
|
}
|
|
|
|
do_borg_enc() {
|
|
radioBox "$borg_title" "Encryption mode" \
|
|
"none" "no encryption and no authentication" on \
|
|
"repokey" "encryption with a passphrase" off
|
|
[ $? = 1 ] && return;
|
|
borg_encryption="$REPLY"
|
|
|
|
if [ "$borg_encryption" = "repokey" ]; then
|
|
local question="Enter the passphrase needed to encrypt/decrypt the repository:"
|
|
REPLY=
|
|
while [ -z "$REPLY" -o -z "$borg_passphrase" ]; do
|
|
passwordBox "$borg_title - " "$question"
|
|
[ $? = 0 ] || return 1
|
|
borg_passphrase="$REPLY"
|
|
done
|
|
fi
|
|
|
|
_enc_done="(DONE)"
|
|
setDefault prune
|
|
}
|
|
|
|
do_borg_local_dir() {
|
|
local dir_status="ok"
|
|
|
|
IFS=$' \t\n'
|
|
if [ "$_dest_done" = "" ]; then
|
|
msgBox "$borg_title: error" "You must first configure the destination."
|
|
return 1
|
|
fi
|
|
|
|
echo "Testing to see if the borg backup directory exists and is writable"
|
|
if [ test -d "$borg_directory" ]; then
|
|
if [ test -w "$borg_directory" ]; then
|
|
msgBox "destination directory is not writable!" "The destination directory is not writable by the user you specified. Please fix the permissions on the directory and then try again."
|
|
dir_status=failed
|
|
fi
|
|
else
|
|
booleanBox "Destination does not exist" "The destination backup directory does not exist, do you want me to create it for you?"
|
|
if [ $? = 0 ]; then
|
|
if mkdir -p "$borg_directory"; then
|
|
msgBox "$borg_title: success" "Creation of the destination directory was a success!"
|
|
else
|
|
msgBox "$borg_title: error" "Creation of the destination directory failed, check the directory permissions."
|
|
dir_status=failed
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
[ "$dir_status" = "ok" ] || return 1
|
|
}
|
|
|
|
do_borg_ssh_con() {
|
|
local remote_status="ok"
|
|
|
|
IFS=$' \t\n'
|
|
if [ "$_dest_done" = "" ]; then
|
|
msgBox "$borg_title: error" "You must first configure the destination."
|
|
return 1
|
|
elif [ "$borg_user" = "" ]; then
|
|
msgBox "$borg_title: error" "You must first configure the destination user."
|
|
return 1
|
|
elif [ "$borg_host" = "" ]; then
|
|
msgBox "$borg_title: error" "You must first configure the destination host."
|
|
return 1
|
|
else
|
|
booleanBox "$borg_title" "This step will create a ssh key for the local root user with no passphrase (if one does not already exist), and attempt to copy root's public ssh key to authorized_keys file of $borg_user@$borg_host. This will allow the local root to make unattended backups to $borg_user@$borg_host.\n\n\nAre you sure you want to continue?"
|
|
[ $? = 0 ] || return 1
|
|
fi
|
|
|
|
if [ ! -f /root/.ssh/id_dsa.pub -a ! -f /root/.ssh/id_rsa.pub ]; then
|
|
echo "Creating local root's ssh key"
|
|
ssh-keygen -t rsa -b 4096 -f /root/.ssh/id_rsa -N ""
|
|
echo "Done. hit return to continue"
|
|
read
|
|
fi
|
|
|
|
ssh -o PreferredAuthentications=publickey $borg_host -p $borg_port -l $borg_user "exit" 2> /dev/null
|
|
if [ $? -ne 0 ]; then
|
|
echo "Copying root's public ssh key to authorized_keys of $borg_user@$borg_host. When prompted, specify the password for user $borg_user@$borg_host."
|
|
pubkeys=( /root/.ssh/id_[rd]sa.pub )
|
|
if ! ssh-copy-id -i ${pubkeys[0]} -p $borg_port $borg_user@$borg_host; then
|
|
echo "FAILED: Couldn't copy root's public ssh key to authorized_keys of $borg_user@$borg_host."
|
|
ssh -p $borg_port $borg_user@$borg_host 'test -w .ssh || test -w .'
|
|
result=$?
|
|
echo "Hit return to continue."
|
|
read
|
|
case $result in
|
|
0 ) msgBox "$borg_title: error" "Directories are writable: Probably just a typo the first time." ;;
|
|
1 ) msgBox "$borg_title: error" "Connected successfully to $borg_user@$borg_host, but unable to write. Check ownership and modes of ~$borg_user on $borg_host." ;;
|
|
255 ) msgBox "$borg_title: error" "Failed to connect to $borg_user@$borg_host. Check hostname, username, and password. Also, make sure sshd is running on the destination host." ;;
|
|
* ) msgBox "$borg_title: error" "Unexpected error (return code ${result})." ;;
|
|
esac
|
|
return
|
|
else
|
|
echo "Done. hit return to continue"
|
|
read
|
|
fi
|
|
else
|
|
echo "root@localhost is already in authorized_keys of $borg_user@$borg_host."
|
|
echo "Hit return to continue."
|
|
read
|
|
fi
|
|
|
|
# test to see if the remote borg backup directory exists and is writable
|
|
echo "Testing to see if remote borg backup directory exists and is writable"
|
|
ssh -p $borg_port $borg_user@$borg_host "test -d ${borg_directory}"
|
|
if [ $? = 0 ]; then
|
|
ssh -p $borg_port $borg_user@$borg_host "test -w $borg_directory"
|
|
if [ $? != 0 ]; then
|
|
msgBox "destination directory is not writable!" "The remote destination directory is not writable by the user you specified. Please fix the permissions on the directory and then try again."
|
|
remote_status=failed
|
|
fi
|
|
else
|
|
booleanBox "Remote directory does not exist" "The destination backup directory does not exist, do you want me to create it for you?"
|
|
if [ $? = 0 ]; then
|
|
ssh -p $borg_port $borg_user@$borg_host "mkdir -p ${borg_directory}"
|
|
result=$?
|
|
case $result in
|
|
0) msgBox "$borg_title: success" "Creation of the remote destination directory was a success!";;
|
|
1) msgBox "$borg_title: error" "Connected successfully to $borg_user@$borg_host, but was unable to create the destination directory, check the directory permissions."
|
|
remote_status=failed;;
|
|
255) msgBox "$borg_title: error" "Failed to connect to $borg_user@$borg_host. Check hostname, username, and password. Also, make sure sshd is running on the destination host."
|
|
remote_status=failed;;
|
|
*) msgBox "$borg_title: error" "Unexpected error."
|
|
remote_status=failed;;
|
|
esac
|
|
fi
|
|
fi
|
|
|
|
[ "$remote_status" = "ok" ] || return 1
|
|
}
|
|
|
|
do_borg_con() {
|
|
echo "Checking for local install of borg"
|
|
which borg
|
|
if [ $? != 0 ]; then
|
|
msgBox "$borg_title: error" "borg executable not found, please install borg ($borg_docs/installation.html)."
|
|
return
|
|
fi
|
|
|
|
if [ "$borg_host" != "localhost" ]; then
|
|
do_borg_ssh_con
|
|
else
|
|
do_borg_local_dir
|
|
fi
|
|
|
|
[ $? = 0 ] || return
|
|
|
|
echo "SUCCESS: Everything looks good!"
|
|
echo "Hit return to continue."
|
|
read
|
|
|
|
_con_done="(DONE)"
|
|
setDefault enc
|
|
}
|
|
|
|
do_borg_prune() {
|
|
radioBox "$borg_title" "pruning (how many backups to keep" \
|
|
"yes" "regularly prune old backups" on \
|
|
"no" "keep all backups" off
|
|
[ $? = 1 ] && return;
|
|
borg_prune="$REPLY"
|
|
|
|
if [ "$borg_prune" = "yes" ]; then
|
|
declare -a tmp_array
|
|
set -o noglob
|
|
REPLY=
|
|
formBegin "$borg_title - keep all backups made within this number of days"
|
|
formItem "keep" "$borg_keep"
|
|
formDisplay
|
|
|
|
[ $? = 0 ] || return
|
|
tmp_array=($REPLY)
|
|
borg_keep=${tmp_array[0]}
|
|
|
|
set +o noglob
|
|
fi
|
|
|
|
_prune_done="(DONE)"
|
|
setDefault finish
|
|
}
|
|
|
|
do_borg_finish() {
|
|
get_next_filename $configdirectory/90.borg
|
|
cat > $next_filename <<EOF
|
|
## for more options see
|
|
## - example.borg
|
|
## - $borg_docs
|
|
|
|
[source]
|
|
EOF
|
|
## includes ##
|
|
set -o noglob
|
|
for ((i=0; i < ${#borg_includes[@]} ; i++)); do
|
|
echo "include = ${borg_includes[$i]}" >> $next_filename
|
|
done
|
|
set +o noglob
|
|
|
|
## excludes ##
|
|
set -o noglob
|
|
for ((i=0; i < ${#borg_excludes[@]} ; i++)); do
|
|
echo exclude = ${borg_excludes[$i]} >> $next_filename
|
|
done
|
|
set +o noglob
|
|
cat >> $next_filename <<EOF
|
|
|
|
## for more info see : borg prune -h
|
|
prune = $borg_prune
|
|
keep = "${borg_keep}d"
|
|
|
|
[dest]
|
|
directory = $borg_directory
|
|
host = $borg_host
|
|
port = $borg_port
|
|
user = $borg_user
|
|
archive = $borg_archive
|
|
compression = $borg_compression
|
|
encryption = $borg_encryption
|
|
passphrase = $borg_passphrase
|
|
EOF
|
|
|
|
chmod 600 $next_filename
|
|
}
|
|
|
|
borg_main_menu() {
|
|
while true; do
|
|
srcitem="choose files to include & exclude $_src_done"
|
|
destitem="configure backup destination $_dest_done"
|
|
conitem="test connection and destination dir $_con_done"
|
|
encitem="configure encryption mode $_enc_done"
|
|
pruneitem="configure pruning (optional) $_prune_done"
|
|
menuBox "$borg_title" "choose a step:" \
|
|
src "$srcitem" \
|
|
dest "$destitem" \
|
|
conn "$conitem" \
|
|
enc "$encitem" \
|
|
prune "$pruneitem" \
|
|
finish "finish and create config file"
|
|
[ $? = 0 ] || return
|
|
result="$REPLY"
|
|
case "$result" in
|
|
"src") do_borg_src;;
|
|
"dest") do_borg_dest;;
|
|
"conn") do_borg_con;;
|
|
"enc") do_borg_enc;;
|
|
"prune") do_borg_prune;;
|
|
"finish")
|
|
if [[ "$_con_done$_dest_done$_enc_done$_src_done" != "(DONE)(DONE)(DONE)(DONE)" ]]; then
|
|
msgBox "$borg_title" "You cannot create the configuration file until mandatory steps are completed."
|
|
else
|
|
do_borg_finish
|
|
return
|
|
fi
|
|
;;
|
|
esac
|
|
done
|
|
}
|
|
|
|
borg_wizard() {
|
|
# Global variables
|
|
borg_title="borg action wizard"
|
|
borg_docs="http://borgbackup.readthedocs.io/en/stable"
|
|
|
|
_src_done=
|
|
_dest_done=
|
|
_enc_done=
|
|
_con_done=
|
|
|
|
borg_directory=/backup/`hostname`
|
|
borg_user=root
|
|
borg_host=localhost
|
|
borg_port=22
|
|
borg_archive='{now:%Y-%m-%dT%H:%M:%S}'
|
|
borg_compression=lz4
|
|
borg_encryption=none
|
|
borg_passphrase=
|
|
borg_keep=30
|
|
|
|
# Global variables whose '*' shall not be expanded
|
|
set -o noglob
|
|
borg_includes=(/var/spool/cron/crontabs /var/backups /etc /root /home /usr/local/*bin)
|
|
borg_excludes=(/home/*/.gnupg /home/*/.local/share/Trash /home/*/.Trash /home/*/.thumbnails)
|
|
set +o noglob
|
|
|
|
borg_main_menu
|
|
}
|