mirror of
https://0xacab.org/liberate/backupninja.git
synced 2024-11-08 20:02:32 +01:00
f43c85662d
The effect of "keep*" options is not straightforward to understand, so replacing it with a simpler "keep" option, which replicates the functionality of other backupninja handlers. This also simplifies the helper, as the use is then only asked how many days of backups to keep. At the same time, we add "prune_options" which allows for the use of the "keep*" options as well as other useful prune options, like "--prefix".
390 lines
12 KiB
Bash
390 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_user" -o -z "$borg_archive" -o -z "$borg_compression" ]
|
|
do
|
|
formBegin "$borg_title - destination"
|
|
formItem "directory" "$borg_directory"
|
|
formItem "host" "$borg_host"
|
|
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_user=${tmp_array[2]}
|
|
borg_archive=${tmp_array[3]}
|
|
borg_compression=${tmp_array[4]}
|
|
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 -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]} $borg_user@$borg_host; then
|
|
echo "FAILED: Couldn't copy root's public ssh key to authorized_keys of $borg_user@$borg_host."
|
|
ssh $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 $borg_user@$borg_host "test -d ${borg_directory}"
|
|
if [ $? = 0 ]; then
|
|
ssh $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 $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
|
|
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_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
|
|
}
|