r3566@krups: intrigeri | 2005-11-17 21:59:38 +0100
[matthijs/upstream/backupninja.git] / handlers / dup.helper
1 HELPERS="$HELPERS dup:incremental_encrypted_remote_filesystem_backup"
2
3 ### Functions
4
5 do_dup_host_includes() {
6    set -o noglob
7    # choose the files to backup
8    REPLY=
9    while [ -z "$REPLY" ]; do
10       formBegin "$dup_title - host system: includes"
11          for ((i=0; i < ${#dup_default_includes[@]} ; i++)); do
12             formItem include ${dup_default_includes[$i]}
13          done
14          formItem include ""
15          formItem include ""
16          formItem include ""
17          formDisplay
18       [ $? = 0 ] || return 1
19       dup_includes=($REPLY)
20    done
21    set +o noglob
22 }
23
24 do_dup_vserver() {
25    # choose the vservers to backup (into $selected_vservers)
26    choose_one_or_more_vservers "$dup_title"
27    [ $? = 0 ] || return 1
28
29    set -o noglob
30    # choose the files to backup
31    REPLY=
32    while [ -z "$REPLY" ]; do
33       formBegin "$dup_title - vservers: includes"
34          for ((i=0; i < ${#dup_default_includes[@]} ; i++)); do
35             formItem include ${dup_default_includes[$i]}
36          done
37          formItem include ""
38          formItem include ""
39          formItem include ""
40       formDisplay
41       [ $? = 0 ] || return 1
42       dup_vsincludes=($REPLY)
43    done
44    set +o noglob
45 }
46
47 do_dup_excludes() {
48    set -o noglob
49    formBegin "$dup_title: excludes"
50      for ((i=0; i < ${#dup_default_excludes[@]} ; i++)); do
51         formItem exclude ${dup_default_excludes[$i]}
52      done
53      formItem exclude ""
54      formItem exclude ""
55      formItem exclude ""
56    formDisplay
57    [ $? = 0 ] || return 1
58    dup_excludes=($REPLY)
59    set +o noglob
60 }
61
62 do_dup_src() {
63    choose_host_or_vservers_or_both "$dup_title"
64    [ $? = 0 ] || return 1
65    case $host_or_vservers in
66       'host')
67          do_dup_host_includes
68          [ $? = 0 ] || return 1
69          ;;
70       'vservers')
71          do_dup_vserver
72          [ $? = 0 ] || return 1
73          ;;
74       'both')
75          do_dup_host_includes
76          [ $? = 0 ] || return 1
77          do_dup_vserver
78          [ $? = 0 ] || return 1
79          ;;
80       *)
81          return 1
82          ;;
83    esac
84    do_dup_excludes
85    [ $? = 0 ] || return 1
86    
87    _src_done="(DONE)"
88    setDefault dest
89 }
90
91 do_dup_dest() {
92
93    local replyconverted
94    local thereply
95
96    set -o noglob
97    REPLY=
98    while [ -z "$REPLY" -o -z "$dup_destdir" -o -z "$dup_desthost" -o -z "$dup_destuser" ]; do
99       formBegin "$dup_title - destination: last three items are compulsory"
100         formItem "desthost" "$dup_desthost"
101         formItem "destuser" "$dup_destuser"
102         formItem "destdir" "$dup_destdir"
103         formItem "keep" "$dup_keep"
104         formItem "incremental" "$dup_incremental"
105         formItem "bandwidthlimit" "$dup_bandwidth"
106         formItem "sshoptions" "$dup_sshoptions"
107       formDisplay
108       [ $? = 0 ] || return 1
109
110       IFS=$''
111       replyconverted=`echo $REPLY | tr '\n' :`
112       IFS=$':'
113       thereply=($replyconverted)
114       IFS=$' \t\n'
115       
116       dup_desthost=${thereply[0]}
117       dup_destuser=${thereply[1]}
118       dup_destdir=${thereply[2]}
119       dup_keep=${thereply[3]}
120       dup_incremental=${thereply[4]}
121       dup_bandwidth=${thereply[5]}
122       dup_sshoptions=${thereply[6]}
123
124    done
125    set +o noglob
126
127    _dest_done="(DONE)"
128    setDefault gpg
129 }
130
131 do_dup_gpg() {
132    
133    set -o noglob
134
135    # encryptkey ?
136    REPLY=
137    while [ -z "$REPLY" -o -z "$dup_gpg_encryptkey" ]; do
138       inputBox "$dup_title - GnuPG" "Enter the GnuPG key ID to be used to encrypt the backups:" "$dup_gpg_encryptkey"
139       [ $? = 0 ] || return 1
140       dup_gpg_encryptkey="$REPLY"
141    done
142
143    # passphrase ?
144    REPLY=
145    while [ -z "$REPLY" -o -z "$dup_gpg_password" ]; do
146       passwordBox "$dup_title - GnuPG" "Enter the passphrase needed to unlock the key 0x$dup_gpg_encryptkey"
147       [ $? = 0 ] || return 1
148       dup_gpg_password="$REPLY"
149    done
150
151    # sign ?
152    booleanBox "$dup_title - GnuPG" "Sign the backups?" "$dup_gpg_sign"
153    if [ $? = 0 ]; then
154       dup_gpg_sign=yes
155    else
156       dup_gpg_sign=no
157    fi
158
159    set +o noglob
160    _gpg_done="(DONE)"
161    setDefault adv
162    # TODO: replace the above line by the following when do_dup_conn is written
163    # setDefault conn
164 }
165
166 # TODO: share rdiff.helper code in some lib, and use it here
167 do_dup_conn() {
168    _con_done="(DONE)"
169    setDefault adv
170 }
171
172 do_dup_misc_options() {
173
174    set -o noglob
175    local replyconverted
176    local thereply
177
178    formBegin "$dup_title - misc. options"
179      formItem "nicelevel" "$dup_nicelevel"
180      formItem "testconnect" "$dup_testconnect"
181      formItem "options" "$dup_options"
182    formDisplay
183    [ $? = 0 ] || return 1
184
185    IFS=$''
186    replyconverted=`echo $REPLY | tr '\n' :`
187    IFS=$':'
188    thereply=($replyconverted)
189    IFS=$' \t\n'
190
191    dup_nicelevel=${thereply[0]}
192    dup_testconnect=${thereply[1]}
193    dup_options=${thereply[2]}
194
195    set +o noglob
196 }
197
198 # (rdiff.helper compatible interface... there could be some sode to share, hmmm.)
199 do_dup_adv() {
200    do_dup_misc_options
201    [ $? = 0 ] || return 1
202    _adv_done="(DONE)"
203    setDefault finish
204 }
205
206 do_dup_finish() {
207    get_next_filename $configdirectory/90.dup
208    cat > $next_filename <<EOF
209 # passed directly to duplicity
210 #options = --verbosity 8
211 options = $dup_options
212
213 # default is 0, but set to 19 if you want to lower the priority.
214 nicelevel = $dup_nicelevel
215
216 # default is yes. set to no to skip the test if the remote host is alive
217 testconnect = $dup_testconnect
218
219 ######################################################
220 ## gpg section
221 ## (how to encrypt and optionnally sign the backups)
222
223 [gpg]
224
225 # passphrase needed to unlock the GnuPG key
226 # NB: do not quote it, and it should not contain any quote
227 password = $dup_gpg_password
228
229 # default is no, for backward compatibility with backupninja <= 0.5.
230 # when set to yes, encryptkey option must be set below.
231 sign = $dup_gpg_sign
232
233 # key ID used for data encryption and, optionnally, signing.
234 # if not set, local root's default gpg key is used.
235 encryptkey = $dup_gpg_encryptkey
236
237 ######################################################
238 ## source section
239 ## (where the files to be backed up are coming from)
240
241 [source]
242
243 # files to include in the backup
244 # (supports globbing with '*')
245 # BIG FAT WARNING
246 # Symlinks are not dereferenced. Moreover, an include line whose path
247 # contains, at any level, a symlink to a directory, will only have the
248 # symlink backed-up, not the target directory's content. Yes, you have
249 # to dereference yourself the symlinks, or to use 'mount --bind'
250 # instead.
251 # EXAMPLE
252 # Let's say /home is a symlink to /mnt/crypt/home ; the following line
253 # will only backup a "/home" symlink ; neither /home/user nor
254 # /home/user/Mail will be backed-up :
255 #   include = /home/user/Mail
256 # A workaround is to 'mount --bind /mnt/crypt/home /home' ; another
257 # one is to write :
258 #   include = /mnt/crypt/home/user/Mail
259 EOF
260
261    if [ "$host_or_vservers" == host -o "$host_or_vservers" == both ]; then
262       set -o noglob
263       for ((i=0; i < ${#dup_includes[@]} ; i++)); do
264          echo "include = ${dup_includes[$i]}" >> $next_filename
265       done
266       set +o noglob
267    fi
268
269    cat >> $next_filename <<EOF
270
271 # If vservers = yes in /etc/backupninja.conf then the following variables can
272 # be used:
273 # vsnames = all | <vserver1> <vserver2> ... (default = all)
274 # vsinclude = <path>
275 # Any path specified in vsinclude is added to the include list for each vserver
276 # listed in vsnames (or all if vsnames = all).
277 # E.g. vsinclude = /home will backup the /home partition in every vserver
278 # listed in vsnames. If you have vsnames = "foo bar baz", this vsinclude will
279 # add to the include list /vservers/foo/home, /vservers/bar/home and
280 # /vservers/baz/home.
281 # Vservers paths are derived from $VROOTDIR.
282
283 EOF
284
285    if [ "$host_or_vservers" == vservers -o "$host_or_vservers" == both ]; then
286       set -o noglob
287       echo -e "vsnames = \"$selected_vservers\"\n" >> $next_filename
288       for ((i=0; i < ${#dup_vsincludes[@]} ; i++)); do
289          echo "vsinclude = ${dup_vsincludes[$i]}" >> $next_filename
290       done
291       set +o noglob
292    fi
293
294    # excludes
295    cat >> $next_filename <<EOF
296
297 # rdiff-backup specific comment, TO ADAPT
298 # files to exclude from the backup
299 # (supports globbing with '*')
300 EOF
301     set -o noglob
302     for ((i=0; i < ${#dup_excludes[@]} ; i++)); do
303         echo exclude = ${dup_excludes[$i]} >> $next_filename
304     done
305     set +o noglob
306
307     cat >> $next_filename <<EOF
308
309 ######################################################
310 ## destination section
311 ## (where the files are copied to)
312
313 [dest]
314
315 # perform an incremental backup? (default = yes)
316 # if incremental = no, perform a full backup in order to start a new backup set
317 incremental = $dup_incremental
318
319 # how many days of data to keep ; default is 60 days.
320 # (you can also use the time format of duplicity)
321 # 'keep = yes' means : do not delete old data, the remote host will take care of this
322 #keep = 60
323 #keep = yes
324 keep = $dup_keep
325
326 # bandwith limit, in kbit/s ; default is 0, i.e. no limit
327 #bandwidthlimit = 128
328 bandwidthlimit = $dup_bandwidth
329
330 # passed directly to ssh and scp
331 #sshoptions = -i /root/.ssh/id_dsa_duplicity
332 sshoptions = $dup_sshoptions
333
334 # put the backups under this directory
335 destdir = $dup_destdir
336
337 # the machine which will receive the backups
338 desthost = $dup_desthost
339
340 # make the files owned by this user
341 # note: you must be able to ssh backupuser@backhost
342 # without specifying a password (if type = remote).
343 destuser = $dup_destuser
344
345 EOF
346
347     chmod 600 $next_filename
348
349 }
350
351 dup_main_menu() {
352
353   while true; do
354      srcitem="choose files to include & exclude $_src_done"
355      destitem="configure backup destination $_dest_done"
356      gpgitem="configure GnuPG encryption/signing $_gpg_done"
357      conitem="set up ssh keys and test remote connection $_con_done"
358      advitem="edit advanced settings $_adv_done"
359      # TODO: add the following to the menu when do_dup_conn is written
360      # conn "$conitem" \
361      menuBox "$dup_title" "choose a step:" \
362         src "$srcitem" \
363         dest "$destitem" \
364         gpg "$gpgitem" \
365         adv "$advitem" \
366         finish "finish and create config file"
367      [ $? = 0 ] || return 1
368      result="$REPLY"
369
370      case "$result" in
371         "src") do_dup_src;;
372         "dest") do_dup_dest;;
373         "gpg") do_dup_gpg;;
374         # TODO: enable the following when do_dup_conn is written
375         # "conn") do_dup_conn;;
376         "adv") do_dup_adv;;
377         "finish")
378            if [[ "$_dest_done$_gpg_done$_src_done" != "(DONE)(DONE)(DONE)" ]]; then
379            # TODO: replace the previous test by the following when do_dup_conn is written
380            # if [[ "$_con_done$_dest_done$_gpg_done$_src_done" != "(DONE)(DONE)(DONE)(DONE)" ]]; then
381               msgBox "$dup_title" "You cannot create the configuration file until the four first steps are completed."
382            else
383               do_dup_finish
384               break
385            fi
386            ;;
387      esac
388
389   done
390 }
391
392 ### Main function
393
394 dup_wizard() {
395    
396    require_packages duplicity
397
398    # Global variables
399    dup_title="Duplicity action wizard"
400    _src_done=
401    _dest_done=
402    _con_done=
403    _gpg_done=
404    _adv_done=
405    declare -a dup_default_includes
406    declare -a dup_default_excludes
407    declare -a dup_includes
408    declare -a dup_excludes
409    declare -a dup_vsincludes
410    dup_incremental=yes
411    dup_keep=60
412    dup_bandwidth=
413    dup_sshoptions=
414    dup_destdir="/backups/`hostname`"
415    dup_desthost=
416    dup_destuser=
417    dup_gpg_sign="yes"
418    dup_gpg_encryptkey=""
419    dup_gpg_password=""
420    dup_nicelevel=19
421    dup_testconnect=yes
422    dup_options=
423
424    # Global variables whose '*' shall not be expanded
425    set -o noglob
426    dup_default_includes=(/var/spool/cron/crontabs /var/backups /etc /root /home /usr/local/*bin /var/lib/dpkg/status*)
427    dup_default_excludes=(/home/*/.gnupg)
428    set +o noglob
429
430    dup_main_menu
431 }