dup: actually allow to backup only VServers, by relaxing $include test
[matthijs/upstream/backupninja.git] / handlers / dup.in
1 # -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*-
2 #
3 # duplicity script for backupninja
4 # requires duplicity
5 #
6
7 getconf options
8 getconf testconnect yes
9 getconf nicelevel 0
10 getconf tmpdir
11
12 setsection gpg
13 getconf password
14 getconf sign no
15 getconf encryptkey
16 getconf signkey
17
18 setsection source
19 getconf include
20 getconf vsnames all
21 getconf vsinclude
22 getconf exclude
23
24 setsection dest
25 getconf incremental yes
26 getconf keep 60
27 getconf desturl
28 getconf sshoptions
29 getconf bandwidthlimit 0
30 getconf desthost
31 getconf destdir
32 getconf destuser
33 destdir=${destdir%/}
34
35 ### SANITY CHECKS ##############################################################
36
37 [ -n "$desturl" -o -n "$destdir" ]  || fatal "The destination directory (destdir) must be set when desturl is not used."
38 [ -n "$include" -o -n "$vsinclude" ]  || fatal "No source includes specified"
39 [ -n "$password" ] || fatal "The password option must be set."
40
41 ### VServers
42 # If vservers are configured, check that the ones listed in $vsnames do exist.
43 local usevserver=no
44 if [ $vservers_are_available = yes ]; then
45    if [ "$vsnames" = all ]; then
46       vsnames="$found_vservers"
47    else
48       if ! vservers_exist "$vsnames" ; then
49             fatal "At least one of the vservers listed in vsnames ($vsnames) does not exist."
50       fi
51    fi
52    if [ -n "$vsinclude" ]; then
53       info "Using vservers '$vsnames'"
54       usevserver=yes
55    fi
56 else
57    [ -z "$vsinclude" ] || warning 'vservers support disabled in backupninja.conf, vsincludes configuration lines will be ignored'
58 fi
59
60 ### See if we can login on $desthost
61 if [ "$testconnect" == "yes" ]; then
62    if [ -n "$desturl" ]; then
63       warning 'testconnect can not be used when desturl is set'
64    else
65       debug "ssh $sshoptions -o PasswordAuthentication=no $desthost -l $destuser 'echo -n 1'"
66       if [ ! $test ]; then
67          result=`ssh $sshoptions -o PasswordAuthentication=no $desthost -l $destuser 'echo -n 1'`
68          if [ "$result" != "1" ]; then
69             fatal "Can't connect to $desthost as $destuser."
70          else
71             debug "Connected to $desthost as $destuser successfully"
72          fi
73       fi
74    fi
75 fi
76
77 ### COMMAND-LINE MANGLING ######################################################
78
79 ### initialize $execstr*
80 execstr_command=
81 execstr_options="$options --no-print-statistics"
82 execstr_source=
83 if [ -n "$desturl" ]; then
84    [ -z "$destuser" ] || warning 'the configured destuser is ignored since desturl is set'
85    [ -z "$desthost" ] || warning 'the configured desthost is ignored since desturl is set'
86    [ -z "$destdir" ] || warning 'the configured destdir is ignored since desturl is set'
87    execstr_serverpart="$desturl"
88 else
89    execstr_serverpart="scp://$destuser@$desthost/$destdir"
90 fi
91
92 ### duplicity version
93 duplicity_version="`duplicity --version | @AWK@ '{print $2}'`"
94 duplicity_major="`echo $duplicity_version | @AWK@ -F '.' '{print $1}'`"
95 duplicity_minor="`echo $duplicity_version | @AWK@ -F '.' '{print $2}'`"
96 duplicity_sub="`echo $duplicity_version | @AWK@ -F '.' '{print $3}'`"
97
98 ### ssh/scp/sftp options
99 # 1. duplicity >= 0.4.2 needs --sftp-command
100 #    (NB: sftp does not support the -l option)
101 # 2. duplicity 0.4.3 to 0.4.9 replace --ssh-command with --ssh-options, which is
102 #    passed to scp and sftp commands by duplicity. We don't use it: since this
103 #    version does not use the ssh command anymore, we keep compatibility with
104 #    our previous config files by passing $sshoptions to --scp-command and
105 #    --sftp-command ourselves
106
107 scpoptions="$sshoptions"
108 if [ "$bandwidthlimit" =! 0 ]; then
109    [ -z "$testurl" ] || warning 'The bandwidthlimit option is not used when desturl is set.'
110    scpoptions="$scpoptions -l $bandwidthlimit"
111 fi
112
113 # < 0.4.2 : only uses ssh and scp
114 if [ "$duplicity_major" -le 0 -a "$duplicity_minor" -le 4 -a "$duplicity_sub" -lt 2 ]; then
115    execstr_options="${execstr_options} --scp-command 'scp $scpoptions' --ssh-command 'ssh $sshoptions'"
116 # >= 0.4.2 : also uses sftp, --sftp-command option is now supported
117 else
118    sftpoptions="$sshoptions"
119    # == 0.4.2 : uses ssh, scp and sftp
120    if [ "$duplicity_major" -eq 0 -a "$duplicity_minor" -eq 4 -a "$duplicity_sub" -eq 2 ]; then
121       execstr_options="${execstr_options} --scp-command 'scp $scpoptions' --sftp-command 'sftp $sftpoptions' --ssh-command 'ssh $sshoptions'"
122    # >= 0.4.3 : uses only scp and sftp, --ssh-command option is not supported anymore
123    else
124       execstr_options="${execstr_options} --scp-command 'scp $scpoptions' --sftp-command 'sftp $sftpoptions'"
125    fi
126 fi
127
128 ### Symmetric or asymmetric (public/private key pair) encryption
129 if [ -n "$encryptkey" ]; then
130    execstr_options="${execstr_options} --encrypt-key $encryptkey"
131    debug "Data will be encrypted with the GnuPG key $encryptkey."
132 else
133    debug "Data will be encrypted using symmetric encryption."
134 fi
135
136 ### Data signing (or not)
137 if [ "$sign" == yes ]; then
138    # duplicity is not able to sign data when using symmetric encryption
139    [ -n "$encryptkey" ] || fatal "The encryptkey option must be set when signing."
140    # if needed, initialize signkey to a value that is not empty (checked above)
141    [ -n "$signkey" ] || signkey="$encryptkey"
142    execstr_options="${execstr_options} --sign-key $signkey"
143    debug "Data will be signed will the GnuPG key $signkey."
144 else
145    debug "Data won't be signed."
146 fi
147
148 ### Incremental or full backup mode
149 # If incremental==yes, use the default duplicity behaviour: perform an
150 # incremental backup if old signatures can be found, else switch to
151 # full backup.
152 # If incremental==no, force a full backup anyway.
153 if [ "$incremental" == "no" ]; then
154    # before 0.4.4, full was an option and not a command
155    if [ "$duplicity_major" -le 0 -a "$duplicity_minor" -le 4 -a "$duplicity_sub" -lt 4 ]; then   
156       execstr_options="${execstr_options} --full"
157    else
158       execstr_command="full"
159    fi
160 fi
161
162 ### Temporary directory
163 precmd=
164 if [ -n "$tmpdir" ]; then
165    if [ ! -d "$tmpdir" ]; then
166       info "Temporary directory ($tmpdir) does not exist, creating it."
167       mkdir -p "$tmpdir"
168       [ $? -eq 0 ] || fatal "Could not create temporary directory ($tmpdir)."
169    fi
170    info "Using $tmpdir as TMPDIR"
171    precmd="${precmd}TMPDIR=$tmpdir "
172 fi
173
174 ### Cleanup old backup sets (or not)
175 if [ "$keep" != "yes" ]; then
176    if [ "`echo $keep | tr -d 0-9`" == "" ]; then
177       keep="${keep}D"
178    fi
179    # before 0.4.4, remove-older-than was an option and not a command
180    if [ "$duplicity_major" -le 0 -a "$duplicity_minor" -le 4 -a "$duplicity_sub" -lt 4 ]; then
181       execstr_options="${execstr_options} --remove-older-than $keep"
182    fi
183 fi
184
185 ### Source
186
187 set -o noglob
188
189 # excludes
190 for i in $exclude; do
191    str="${i//__star__/*}"
192    execstr_source="${execstr_source} --exclude '$str'"
193 done
194
195 # includes
196 for i in $include; do
197    [ "$i" != "/" ] || fatal "Sorry, you cannot use 'include = /'"
198    str="${i//__star__/*}"
199    execstr_source="${execstr_source} --include '$str'"
200 done
201
202 # vsincludes
203 if [ $usevserver = yes ]; then
204    for vserver in $vsnames; do
205       for vi in $vsinclude; do
206          str="${vi//__star__/*}"
207          str="$VROOTDIR/$vserver$str"
208          execstr_source="${execstr_source} --include '$str'"
209       done
210    done
211 fi
212
213 set +o noglob
214
215 ### EXECUTE ####################################################################
216
217 execstr_source=${execstr_source//\\*/\\\\\\*}
218
219 ### Cleanup commands (duplicity >= 0.4.4)
220
221 # cleanup
222 if [ "$duplicity_major" -ge 0 -a "$duplicity_minor" -ge 4 -a "$duplicity_sub" -ge 4 ]; then
223    debug "$precmd duplicity cleanup $execstr_options $execstr_serverpart"
224    if [ ! $test ]; then
225       export PASSPHRASE=$password
226       output=`nice -n $nicelevel \
227          su -c \
228          "$precmd duplicity cleanup $execstr_options $execstr_serverpart 2>&1"`
229       exit_code=$?
230       if [ $exit_code -eq 0 ]; then
231          debug $output
232          info "Duplicity cleanup finished successfully."
233       else
234          debug $output
235          warning "Duplicity cleanup failed."
236       fi
237    fi
238 fi
239
240 # remove-older-than
241 if [ "$keep" != "yes" ]; then
242    if [ "$duplicity_major" -ge 0 -a "$duplicity_minor" -ge 4 -a "$duplicity_sub" -ge 4 ]; then
243       debug "$precmd duplicity remove-older-than $keep $execstr_options $execstr_serverpart"
244       if [ ! $test ]; then
245          export PASSPHRASE=$password
246          output=`nice -n $nicelevel \
247                    su -c \
248                       "$precmd duplicity remove-older-than $keep $execstr_options $execstr_serverpart 2>&1"`
249          exit_code=$?
250          if [ $exit_code -eq 0 ]; then
251             debug $output
252             info "Duplicity remove-older-than finished successfully."
253          else
254             debug $output
255             warning "Duplicity remove-older-than failed."
256          fi
257       fi
258    fi
259 fi
260
261 ### Backup command
262 debug "$precmd duplicity $execstr_command $execstr_options $execstr_source --exclude '**' / $execstr_serverpart"
263 if [ ! $test ]; then
264    export PASSPHRASE=$password
265    output=`nice -n $nicelevel \
266              su -c \
267                 "$precmd duplicity $execstr_command $execstr_options $execstr_source --exclude '**' / $execstr_serverpart 2>&1"`
268    exit_code=$?
269    if [ $exit_code -eq 0 ]; then
270       debug $output
271       info "Duplicity finished successfully."
272    else
273       debug $output
274       fatal "Duplicity failed."
275    fi
276 fi
277
278 return 0