Support duplicity >= 0.4.3 invocation syntax
[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
11 setsection gpg
12 getconf password
13 getconf sign no
14 getconf encryptkey
15 getconf signkey
16
17 setsection source
18 getconf include
19 getconf vsnames all
20 getconf vsinclude
21 getconf exclude
22
23 setsection dest
24 getconf incremental yes
25 getconf keep 60
26 getconf sshoptions
27 getconf bandwidthlimit 0
28 getconf desthost
29 getconf destdir
30 getconf destuser
31 destdir=${destdir%/}
32
33 [ "$destdir" != "" ] || fatal "Destination directory not set"
34 [ "$include" != "" ] || fatal "No source includes specified"
35
36 ### vservers stuff ###
37
38 # If vservers are configured, check that the ones listed in $vsnames do exist.
39 local usevserver=no
40 if [ $vservers_are_available = yes ]; then
41    if [ "$vsnames" = all ]; then
42       vsnames="$found_vservers"
43    else
44       if ! vservers_exist "$vsnames" ; then
45             fatal "At least one of the vservers listed in vsnames ($vsnames) does not exist."
46       fi
47    fi
48    if [ -n "$vsinclude" ]; then
49       info "Using vservers '$vsnames'"
50       usevserver=yes
51    fi
52 else
53    [ -z "$vsinclude" ] || warning 'vservers support disabled in backupninja.conf, vsincludes configuration lines will be ignored'
54 fi
55
56
57 ### see if we can login ###
58
59 if [ "$testconnect" == "yes" ]; then
60     debug "ssh $sshoptions -o PasswordAuthentication=no $desthost -l $destuser 'echo -n 1'"
61     if [ ! $test ]; then
62         result=`ssh $sshoptions -o PasswordAuthentication=no $desthost -l $destuser 'echo -n 1'`
63         if [ "$result" != "1" ]; then
64             fatal "Can't connect to $desthost as $destuser."
65         else
66             debug "Connected to $desthost as $destuser successfully"
67         fi
68     fi
69 fi
70
71 ### COMMAND-LINE MANGLING ###
72
73 duplicity_version="`duplicity --version | @AWK@ '{print $2}'`"
74 duplicity_major="`echo $duplicity_version | @AWK@ -F '.' '{print $1}'`"
75 duplicity_minor="`echo $duplicity_version | @AWK@ -F '.' '{print $2}'`"
76 duplicity_sub="`echo $duplicity_version | @AWK@ -F '.' '{print $3}'`"
77
78 # 1. duplicity >= 0.4.2 needs --sftp-command (NB: sftp does not support the -l option)
79 # 2. duplicity >= 0.4.3 replaces --ssh-command with --ssh-options, which:
80 #      - is passed to scp and sftp commands by duplicity
81 #      - has a special syntax we can not feed the command line with
82 #    so we don't use it: since this version does not use the ssh command anymore,
83 #    we keep compatibility with our previous config files by passing $sshoptions to
84 #    --scp-command and --sftp-command ourselves
85
86 scpoptions="$sshoptions"
87 [ "$bandwidthlimit" == 0 ] || scpoptions="$scpoptions -l $bandwidthlimit"
88
89 execstr="$options --no-print-statistics "
90
91 # < 0.4.2 : only uses ssh and scp
92 if [ "$duplicity_major" -le 0 -a "$duplicity_minor" -le 4 -a "$duplicity_sub" -le 2 ]; then
93    execstr="$execstr --scp-command 'scp $scpoptions' --ssh-command 'ssh $sshoptions' "
94 # >= 0.4.2 : also uses sftp, --sftp-command option is now supported
95 else
96    sftpoptions="$sshoptions"
97    # == 0.4.2 : uses ssh, scp and sftp
98    if [ "$duplicity_major" -eq 0 -a "$duplicity_minor" -eq 4 -a "$duplicity_sub" -eq 2 ]; then
99       execstr="$execstr --scp-command 'scp $scpoptions' --sftp-command 'sftp $sftpoptions' --ssh-command 'ssh $sshoptions' "
100    # >= 0.4.3 : uses only scp and sftp, --ssh-command option is not supported anymore
101    else
102       execstr="$execstr --scp-command 'scp $scpoptions' --sftp-command 'sftp $sftpoptions' "
103    fi
104 fi
105
106 # deal with symmetric or asymmetric (public/private key pair) encryption
107 if [ -n "$encryptkey" ]; then
108     execstr="${execstr}--encrypt-key $encryptkey "
109     debug "Data will be encrypted with the GnuPG key $encryptkey."
110 else
111     debug "Data will be encrypted using symmetric encryption."
112 fi
113
114 # deal with data signing
115 if [ "$sign" == yes ]; then
116     # duplicity is not able to sign data when using symmetric encryption
117     [ -n "$encryptkey" ] || fatal "The encryptkey option must be set when signing."
118     # if needed, initialize signkey to a value that is not empty (checked above)
119     [ -n "$signkey" ] || signkey="$encryptkey"
120     execstr="${execstr}--sign-key $signkey "
121     debug "Data will be signed will the GnuPG key $signkey."
122 else
123     debug "Data won't be signed."
124 fi
125
126 # deal with GnuPG passphrase
127 [ -n "$password" ] || fatal "The password option must be set."
128
129 if [ "$keep" != "yes" ]; then
130     if [ "`echo $keep | tr -d 0-9`" == "" ]; then
131         keep="${keep}D"
132     fi
133     execstr="${execstr}--remove-older-than $keep "
134 fi
135
136 if [ "$incremental" == "no" ]; then
137     execstr="${execstr}--full "
138 fi
139
140 execstr_serverpart="scp://$destuser@$desthost/$destdir"
141 execstr_clientpart="/"
142
143 ### SOURCE ###
144
145 set -o noglob
146
147 # excludes
148 for i in $exclude; do
149    str="${i//__star__/*}"
150    execstr="${execstr}--exclude '$str' "
151 done
152         
153 # includes 
154 for i in $include; do
155    [ "$i" != "/" ] || fatal "Sorry, you cannot use 'include = /'"
156    str="${i//__star__/*}"
157    execstr="${execstr}--include '$str' "
158 done
159
160 # vsincludes
161 if [ $usevserver = yes ]; then
162    for vserver in $vsnames; do
163       for vi in $vsinclude; do
164          str="${vi//__star__/*}"
165          str="$VROOTDIR/$vserver$str"
166          execstr="${execstr}--include '$str' "
167       done
168    done
169 fi
170
171 set +o noglob
172
173 ### EXECUTE ###
174
175 execstr=${execstr//\\*/\\\\\\*}
176
177 debug "duplicity $execstr --exclude '**' / $execstr_serverpart"
178 if [ ! $test ]; then
179         export PASSPHRASE=$password
180         output=`nice -n $nicelevel \
181                   su -c \
182                     "duplicity $execstr --exclude '**' / $execstr_serverpart 2>&1"`
183         code=$?
184         if [ $code -eq 0 ]; then
185                 debug $output
186                 info "Duplicity finished successfully."
187         else
188                 debug $output
189                 fatal "Duplicity failed."
190         fi
191 fi      
192
193 return 0