X-Git-Url: https://git.stderr.nl/gitweb?p=matthijs%2Fupstream%2Fbackupninja.git;a=blobdiff_plain;f=handlers%2Fdup.helper;h=eee025666b562a9fa10b6242a097e8b25be78e39;hp=7c172f066f1bc45e0ca039512a622a55f5c72f8b;hb=be75e4e6c536882c14db9a41c61585e7a9c045f6;hpb=280fdac2bc2146a73282b47b2c7ce66c19a0d3f2 diff --git a/handlers/dup.helper b/handlers/dup.helper index 7c172f0..eee0256 100644 --- a/handlers/dup.helper +++ b/handlers/dup.helper @@ -1,3 +1,5 @@ +# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*- + HELPERS="$HELPERS dup:incremental_encrypted_remote_filesystem_backup" ### Functions @@ -8,39 +10,40 @@ do_dup_host_includes() { REPLY= while [ -z "$REPLY" ]; do formBegin "$dup_title - host system: includes" - for ((i=0; i < ${#dup_default_includes[@]} ; i++)); do - formItem include ${dup_default_includes[$i]} + [ -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) + dup_includes="$REPLY" done set +o noglob } do_dup_vserver() { - # choose the vservers to backup - vservers_chooser "$dup_title" + # choose the vservers to backup (into $selected_vservers) + choose_one_or_more_vservers "$dup_title" [ $? = 0 ] || return 1 - dup_vsnames="$vservers_chooser_vsnames" set -o noglob # choose the files to backup REPLY= while [ -z "$REPLY" ]; do - formBegin "$dup_title - vservers: includes" - for ((i=0; i < ${#dup_default_includes[@]} ; i++)); do - formItem include ${dup_default_includes[$i]} + 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) + dup_vsincludes="$REPLY" done set +o noglob } @@ -48,20 +51,21 @@ do_dup_vserver() { do_dup_excludes() { set -o noglob formBegin "$dup_title: excludes" - for ((i=0; i < ${#dup_default_excludes[@]} ; i++)); do - formItem exclude ${dup_default_excludes[$i]} + [ -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) + dup_excludes="$REPLY" set +o noglob } do_dup_src() { - host_or_vservers_chooser + choose_host_or_vservers_or_both "$dup_title" [ $? = 0 ] || return 1 case $host_or_vservers in 'host') @@ -97,7 +101,7 @@ do_dup_dest() { set -o noglob REPLY= while [ -z "$REPLY" -o -z "$dup_destdir" -o -z "$dup_desthost" -o -z "$dup_destuser" ]; do - formBegin "$dup_title - destination: last three items are compulsory" + formBegin "$dup_title - destination: first three items are compulsory" formItem "desthost" "$dup_desthost" formItem "destuser" "$dup_destuser" formItem "destdir" "$dup_destdir" @@ -129,39 +133,86 @@ do_dup_dest() { setDefault gpg } -do_dup_gpg() { - - set -o noglob - - # encryptkey ? +do_dup_gpg_encryptkey() { REPLY= while [ -z "$REPLY" -o -z "$dup_gpg_encryptkey" ]; do - inputBox "$dup_title - GnuPG" "Enter the GnuPG key ID to be used to encrypt the backups:" "$dup_gpg_encryptkey" + 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 +} - # passphrase ? +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" "Enter the passphrase needed to unlock the key 0x$dup_gpg_encryptkey" + passwordBox "$dup_title - GnuPG" "$question" [ $? = 0 ] || return 1 dup_gpg_password="$REPLY" done +} - # sign ? - booleanBox "$dup_title - GnuPG" "Sign the backups?" "$dup_gpg_sign" +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_sign=yes + 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 - set +o noglob + # a passphrase is alway needed + do_dup_gpg_passphrase + _gpg_done="(DONE)" - setDefault conn + 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 @@ -216,50 +267,74 @@ testconnect = $dup_testconnect ###################################################### ## gpg section -## (how to encrypt and optionnally sign the backups) +## (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] -# passphrase needed to unlock the GnuPG key -# NB: do not quote it, and it should not contain any quote -password = $dup_gpg_password - -# default is no, for backward compatibility with backupninja <= 0.5. -# when set to yes, encryptkey option must be set below. +# 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 -# key ID used for data encryption and, optionnally, signing. -# if not set, local root's default gpg key is used. +# 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 -# (supports globbing with '*') -# BIG FAT WARNING -# 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 EOF - if [ "$host_or_vservers" == 'host' -o "$host_or_vservers" == 'both' ]; then + if [ "$host_or_vservers" == host -o "$host_or_vservers" == both ]; then set -o noglob - for ((i=0; i < ${#dup_includes[@]} ; i++)); do - echo "include = ${dup_includes[$i]}" >> $next_filename + for i in $dup_includes; do + echo "include = $i" >> $next_filename done set +o noglob fi @@ -270,21 +345,24 @@ EOF # be used: # vsnames = all | ... (default = all) # vsinclude = +# vsinclude = +# ... # Any path specified in vsinclude is added to the include list for each vserver -# listed in vsnames (or all if vsnames = all). -# E.g. vsinclude = /home will backup the /home partition 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. +# 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 + if [ "$host_or_vservers" == vservers -o "$host_or_vservers" == both ]; then set -o noglob - echo "vsnames = \"$dup_vsnames\"\n" >> $next_filename - for ((i=0; i < ${#dup_vsincludes[@]} ; i++)); do - echo "vsinclude = ${dup_vsincludes[$i]}" >> $next_filename + echo -e "vsnames = $selected_vservers\n" >> $next_filename + for i in $dup_vsincludes; do + echo "vsinclude = $i" >> $next_filename done set +o noglob fi @@ -292,13 +370,11 @@ EOF # excludes cat >> $next_filename <> $next_filename + for i in $dup_excludes; do + echo "exclude = $i" >> $next_filename done set +o noglob @@ -325,8 +401,10 @@ keep = $dup_keep #bandwidthlimit = 128 bandwidthlimit = $dup_bandwidth -# passed directly to ssh and scp -#sshoptions = -i /root/.ssh/id_dsa_duplicity +# 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 " +#sshoptions = -o IdentityFile=/root/.ssh/id_dsa_duplicity sshoptions = $dup_sshoptions # put the backups under this directory @@ -354,11 +432,12 @@ dup_main_menu() { 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" \ - conn "$conitem" \ adv "$advitem" \ finish "finish and create config file" [ $? = 0 ] || return 1 @@ -368,10 +447,13 @@ dup_main_menu() { "src") do_dup_src;; "dest") do_dup_dest;; "gpg") do_dup_gpg;; - "conn") do_dup_conn;; + # TODO: enable the following when do_dup_conn is written + # "conn") do_dup_conn;; "adv") do_dup_adv;; "finish") - if [[ "$_con_done$_dest_done$_gpg_done$_src_done" != "(DONE)(DONE)(DONE)(DONE)" ]]; then + 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 @@ -396,12 +478,9 @@ dup_wizard() { _con_done= _gpg_done= _adv_done= - declare -a dup_default_includes - declare -a dup_default_excludes - declare -a dup_includes - declare -a dup_excludes - declare -a dup_vsincludes - dup_vsnames= + dup_includes= + dup_excludes= + dup_vsincludes= dup_incremental=yes dup_keep=60 dup_bandwidth= @@ -409,8 +488,11 @@ dup_wizard() { dup_destdir="/backups/`hostname`" dup_desthost= dup_destuser= - dup_gpg_sign="yes" + 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 @@ -418,8 +500,8 @@ dup_wizard() { # 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) + 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