typo in backupninja.1
[matthijs/upstream/backupninja.git] / handlers / dup.helper
index 7c172f066f1bc45e0ca039512a622a55f5c72f8b..eee025666b562a9fa10b6242a097e8b25be78e39 100644 (file)
@@ -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 | <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).
-# 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 <<EOF
 
-# rdiff-backup specific comment, TO ADAPT
 # files to exclude from the backup
-# (supports globbing with '*')
 EOF
     set -o noglob
-    for ((i=0; i < ${#dup_excludes[@]} ; i++)); do
-        echo exclude = ${dup_excludes[$i]} >> $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 <SSHOPTION>"
+#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