diff options
Diffstat (limited to 'handlers/dup.helper.in')
-rw-r--r-- | handlers/dup.helper.in | 508 |
1 files changed, 508 insertions, 0 deletions
diff --git a/handlers/dup.helper.in b/handlers/dup.helper.in new file mode 100644 index 0000000..eee0256 --- /dev/null +++ b/handlers/dup.helper.in @@ -0,0 +1,508 @@ +# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*- + +HELPERS="$HELPERS dup:incremental_encrypted_remote_filesystem_backup" + +### Functions + +do_dup_host_includes() { + set -o noglob + # choose the files to backup + REPLY= + while [ -z "$REPLY" ]; do + formBegin "$dup_title - host system: includes" + [ -z "$dup_includes" ] && dup_includes="$dup_default_includes" + for i in $dup_includes; do + formItem include "$i" + done + formItem include "" + formItem include "" + formItem include "" + formDisplay + [ $? = 0 ] || return 1 + dup_includes="$REPLY" + done + set +o noglob +} + +do_dup_vserver() { + # choose the vservers to backup (into $selected_vservers) + choose_one_or_more_vservers "$dup_title" + [ $? = 0 ] || return 1 + + set -o noglob + # choose the files to backup + REPLY= + while [ -z "$REPLY" ]; do + formBegin "$dup_title - vservers: vsincludes (backup these directories from every selected vserver)" + [ -z "$dup_vsincludes" ] && dup_vsincludes="$dup_default_includes" + for i in $dup_vsincludes; do + formItem include "$i" + done + formItem include "" + formItem include "" + formItem include "" + formDisplay + [ $? = 0 ] || return 1 + dup_vsincludes="$REPLY" + done + set +o noglob +} + +do_dup_excludes() { + set -o noglob + formBegin "$dup_title: excludes" + [ -z "$dup_excludes" ] && dup_excludes="$dup_default_excludes" + for i in $dup_excludes; do + formItem exclude "$i" + done + formItem exclude "" + formItem exclude "" + formItem exclude "" + formDisplay + [ $? = 0 ] || return 1 + dup_excludes="$REPLY" + set +o noglob +} + +do_dup_src() { + choose_host_or_vservers_or_both "$dup_title" + [ $? = 0 ] || return 1 + case $host_or_vservers in + 'host') + do_dup_host_includes + [ $? = 0 ] || return 1 + ;; + 'vservers') + do_dup_vserver + [ $? = 0 ] || return 1 + ;; + 'both') + do_dup_host_includes + [ $? = 0 ] || return 1 + do_dup_vserver + [ $? = 0 ] || return 1 + ;; + *) + return 1 + ;; + esac + do_dup_excludes + [ $? = 0 ] || return 1 + + _src_done="(DONE)" + setDefault dest +} + +do_dup_dest() { + + local replyconverted + local thereply + + set -o noglob + REPLY= + while [ -z "$REPLY" -o -z "$dup_destdir" -o -z "$dup_desthost" -o -z "$dup_destuser" ]; do + formBegin "$dup_title - destination: first three items are compulsory" + formItem "desthost" "$dup_desthost" + formItem "destuser" "$dup_destuser" + formItem "destdir" "$dup_destdir" + formItem "keep" "$dup_keep" + formItem "incremental" "$dup_incremental" + formItem "bandwidthlimit" "$dup_bandwidth" + formItem "sshoptions" "$dup_sshoptions" + formDisplay + [ $? = 0 ] || return 1 + + IFS=$'' + replyconverted=`echo $REPLY | tr '\n' :` + IFS=$':' + thereply=($replyconverted) + IFS=$' \t\n' + + dup_desthost=${thereply[0]} + dup_destuser=${thereply[1]} + dup_destdir=${thereply[2]} + dup_keep=${thereply[3]} + dup_incremental=${thereply[4]} + dup_bandwidth=${thereply[5]} + dup_sshoptions=${thereply[6]} + + done + set +o noglob + + _dest_done="(DONE)" + setDefault gpg +} + +do_dup_gpg_encryptkey() { + REPLY= + while [ -z "$REPLY" -o -z "$dup_gpg_encryptkey" ]; do + inputBox "$dup_title - GnuPG" "Enter ID of the public GnuPG key to be used to encrypt the backups:" "$dup_gpg_encryptkey" + [ $? = 0 ] || return 1 + dup_gpg_encryptkey="$REPLY" + done +} + +do_dup_gpg_sign() { + # sign ? + booleanBox "$dup_title - GnuPG" "Sign the backups?" "$dup_gpg_sign" + if [ $? = 0 ]; then + dup_gpg_sign=yes + else + dup_gpg_sign=no + fi +} + +do_dup_gpg_signkey() { + # one key pair ? + booleanBox "$dup_title - GnuPG" "Use the same GnuPG key pair for encryption and signing?" "$dup_gpg_onekeypair" + if [ $? = 0 ]; then + dup_gpg_onekeypair=yes + else + dup_gpg_onekeypair=no + fi + + if [ "$dup_gpg_onekeypair" == "no" }; then + # signkey ? + REPLY= + while [ -z "$REPLY" -o -z "$dup_gpg_signkey" ]; do + inputBox "$dup_title - GnuPG" "Enter the ID of the private GnuPG key to be used to sign the backups:" "$dup_gpg_signkey" + [ $? = 0 ] || return 1 + dup_gpg_signkey="$REPLY" + done + fi +} + +do_dup_gpg_passphrase() { + local question="Enter the passphrase needed to unlock the GnuPG key:" + REPLY= + while [ -z "$REPLY" -o -z "$dup_gpg_password" ]; do + passwordBox "$dup_title - GnuPG" "$question" + [ $? = 0 ] || return 1 + dup_gpg_password="$REPLY" + done +} + +do_dup_gpg() { + + # symmetric or public key encryption ? + booleanBox "$dup_title - GnuPG" "Use public key encryption? Otherwise, symmetric encryption will be used, and data signing will be impossible." "$dup_gpg_asymmetric_encryption" + if [ $? = 0 ]; then + dup_gpg_asymmetric_encryption=yes + else + dup_gpg_asymmetric_encryption=no + fi + + # when using public/private key pair encryption, ask for the keys to use + if [ "$dup_gpg_asymmetric_encryption" == yes ]; then + do_dup_gpg_encryptkey ; [ $? = 0 ] || return 1 + do_dup_gpg_sign ; [ $? = 0 ] || return 1 + if [ "$dup_gpg_sign" == yes ]; then + do_dup_gpg_signkey ; [ $? = 0 ] || return 1 + fi + else + dup_gpg_sign=no + fi + + # a passphrase is alway needed + do_dup_gpg_passphrase + + _gpg_done="(DONE)" + setDefault adv + # TODO: replace the above line by the following when do_dup_conn is written + # setDefault conn +} + +# TODO: share rdiff.helper code in some lib, and use it here +do_dup_conn() { + _con_done="(DONE)" + setDefault adv +} + +do_dup_misc_options() { + + set -o noglob + local replyconverted + local thereply + + formBegin "$dup_title - misc. options" + formItem "nicelevel" "$dup_nicelevel" + formItem "testconnect" "$dup_testconnect" + formItem "options" "$dup_options" + formDisplay + [ $? = 0 ] || return 1 + + IFS=$'' + replyconverted=`echo $REPLY | tr '\n' :` + IFS=$':' + thereply=($replyconverted) + IFS=$' \t\n' + + dup_nicelevel=${thereply[0]} + dup_testconnect=${thereply[1]} + dup_options=${thereply[2]} + + set +o noglob +} + +# (rdiff.helper compatible interface... there could be some sode to share, hmmm.) +do_dup_adv() { + do_dup_misc_options + [ $? = 0 ] || return 1 + _adv_done="(DONE)" + setDefault finish +} + +do_dup_finish() { + get_next_filename $configdirectory/90.dup + cat > $next_filename <<EOF +# passed directly to duplicity +#options = --verbosity 8 +options = $dup_options + +# default is 0, but set to 19 if you want to lower the priority. +nicelevel = $dup_nicelevel + +# default is yes. set to no to skip the test if the remote host is alive +testconnect = $dup_testconnect + +###################################################### +## gpg section +## (how to encrypt and optionally sign the backups) +## +## WARNING: old (pre-0.9.4) example.dup used to give wrong information about +## the way the following options are used. Please read the following +## carefully. +## +## If the encryptkey variable is set: +## - data is encrypted with the GnuPG public key specified by the encryptkey +## variable +## - if signing is enabled, data is signed with the GnuPG private +## key specified by the signkey variable +## - the password variable is used to unlock the GnuPG key(s) used +## for encryption and (optionnal) signing +## +## If the encryptkey option is not set: +## - data signing is not possible +## - the password variable is used to encrypt the data with symmetric +## encryption: no GnuPG key pair is needed + +[gpg] + +# when set to yes, encryptkey variable must be set below; if you want to use +# two different keys for encryption and signing, you must also set the signkey +# variable below. +# default is no, for backwards compatibility with backupninja <= 0.5. +sign = $dup_gpg_sign + +# ID of the GnuPG public key used for data encryption. +# if not set, symmetric encryption is used, and data signing is not possible. +encryptkey = $dup_gpg_encryptkey + +# ID of the GnuPG private key used for data signing. +# if not set, encryptkey will be used. +signkey = $dup_gpg_signkey + +# password +# NB: neither quote this, nor should it include any quotes +password = $dup_gpg_password + +###################################################### +## source section +## (where the files to be backed up are coming from) + +[source] + +# A few notes about includes and excludes: +# 1. include, exclude and vsinclude statements support globbing with '*' +# 2. Symlinks are not dereferenced. Moreover, an include line whose path +# contains, at any level, a symlink to a directory, will only have the +# symlink backed-up, not the target directory's content. Yes, you have to +# dereference yourself the symlinks, or to use 'mount --bind' instead. +# Example: let's say /home is a symlink to /mnt/crypt/home ; the following +# line will only backup a "/home" symlink ; neither /home/user nor +# /home/user/Mail will be backed-up : +# include = /home/user/Mail +# A workaround is to 'mount --bind /mnt/crypt/home /home' ; another one is to +# write : +# include = /mnt/crypt/home/user/Mail +# 3. All the excludes come after all the includes. The order is not otherwise +# taken into account. + +# files to include in the backup +EOF + + if [ "$host_or_vservers" == host -o "$host_or_vservers" == both ]; then + set -o noglob + for i in $dup_includes; do + echo "include = $i" >> $next_filename + done + set +o noglob + fi + + cat >> $next_filename <<EOF + +# If vservers = yes in /etc/backupninja.conf then the following variables can +# be used: +# vsnames = all | <vserver1> <vserver2> ... (default = all) +# vsinclude = <path> +# vsinclude = <path> +# ... +# Any path specified in vsinclude is added to the include list for each vserver +# listed in vsnames (or all if vsnames = all, which is the default). +# +# For example, vsinclude = /home will backup the /home directory in every +# vserver listed in vsnames. If you have 'vsnames = foo bar baz', this +# vsinclude will add to the include list /vservers/foo/home, /vservers/bar/home +# and /vservers/baz/home. +# Vservers paths are derived from $VROOTDIR. + +EOF + + if [ "$host_or_vservers" == vservers -o "$host_or_vservers" == both ]; then + set -o noglob + echo -e "vsnames = $selected_vservers\n" >> $next_filename + for i in $dup_vsincludes; do + echo "vsinclude = $i" >> $next_filename + done + set +o noglob + fi + + # excludes + cat >> $next_filename <<EOF + +# files to exclude from the backup +EOF + set -o noglob + for i in $dup_excludes; do + echo "exclude = $i" >> $next_filename + done + set +o noglob + + cat >> $next_filename <<EOF + +###################################################### +## destination section +## (where the files are copied to) + +[dest] + +# perform an incremental backup? (default = yes) +# if incremental = no, perform a full backup in order to start a new backup set +incremental = $dup_incremental + +# how many days of data to keep ; default is 60 days. +# (you can also use the time format of duplicity) +# 'keep = yes' means : do not delete old data, the remote host will take care of this +#keep = 60 +#keep = yes +keep = $dup_keep + +# bandwith limit, in kbit/s ; default is 0, i.e. no limit +#bandwidthlimit = 128 +bandwidthlimit = $dup_bandwidth + +# passed directly to ssh, scp (and sftp in duplicity >=0.4.2) +# warning: sftp does not support all scp options, especially -i; as +# a workaround, you can use "-o <SSHOPTION>" +#sshoptions = -o IdentityFile=/root/.ssh/id_dsa_duplicity +sshoptions = $dup_sshoptions + +# put the backups under this directory +destdir = $dup_destdir + +# the machine which will receive the backups +desthost = $dup_desthost + +# make the files owned by this user +# note: you must be able to ssh backupuser@backhost +# without specifying a password (if type = remote). +destuser = $dup_destuser + +EOF + + chmod 600 $next_filename + +} + +dup_main_menu() { + + while true; do + srcitem="choose files to include & exclude $_src_done" + destitem="configure backup destination $_dest_done" + gpgitem="configure GnuPG encryption/signing $_gpg_done" + conitem="set up ssh keys and test remote connection $_con_done" + advitem="edit advanced settings $_adv_done" + # TODO: add the following to the menu when do_dup_conn is written + # conn "$conitem" \ + menuBox "$dup_title" "choose a step:" \ + src "$srcitem" \ + dest "$destitem" \ + gpg "$gpgitem" \ + adv "$advitem" \ + finish "finish and create config file" + [ $? = 0 ] || return 1 + result="$REPLY" + + case "$result" in + "src") do_dup_src;; + "dest") do_dup_dest;; + "gpg") do_dup_gpg;; + # TODO: enable the following when do_dup_conn is written + # "conn") do_dup_conn;; + "adv") do_dup_adv;; + "finish") + if [[ "$_dest_done$_gpg_done$_src_done" != "(DONE)(DONE)(DONE)" ]]; then + # TODO: replace the previous test by the following when do_dup_conn is written + # if [[ "$_con_done$_dest_done$_gpg_done$_src_done" != "(DONE)(DONE)(DONE)(DONE)" ]]; then + msgBox "$dup_title" "You cannot create the configuration file until the four first steps are completed." + else + do_dup_finish + break + fi + ;; + esac + + done +} + +### Main function + +dup_wizard() { + + require_packages duplicity + + # Global variables + dup_title="Duplicity action wizard" + _src_done= + _dest_done= + _con_done= + _gpg_done= + _adv_done= + dup_includes= + dup_excludes= + dup_vsincludes= + dup_incremental=yes + dup_keep=60 + dup_bandwidth= + dup_sshoptions= + dup_destdir="/backups/`hostname`" + dup_desthost= + dup_destuser= + dup_gpg_asymmetric_encryption="yes" + dup_gpg_encryptkey="" + dup_gpg_sign="yes" + dup_gpg_onekeypair="yes" + dup_gpg_signkey="" + dup_gpg_password="" + dup_nicelevel=19 + dup_testconnect=yes + dup_options= + + # Global variables whose '*' shall not be expanded + set -o noglob + dup_default_includes="/var/spool/cron/crontabs /var/backups /etc /root /home /usr/local/*bin /var/lib/dpkg/status*" + dup_default_excludes="/home/*/.gnupg /home/*/.gnupg /home/*/.local/share/Trash /home/*/.Trash /home/*/.thumbnails /home/*/.beagle /home/*/.aMule /home/*/gtk-gnutella-downloads" + set +o noglob + + dup_main_menu +} |