b4a7c9db3bc722bb15c5ff58007a89d3e02e3e72
[matthijs/upstream/backupninja.git] / handlers / dup
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 >= 0.4.2 needs --sftp-command (NB: sftp does not support the -l option)
74 duplicity_version="`duplicity --version | awk '{print $2}'`"
75 duplicity_major="`echo $duplicity_version | awk -F '.' '{print $1}'`"
76 duplicity_minor="`echo $duplicity_version | awk -F '.' '{print $2}'`"
77 duplicity_sub="`echo $duplicity_version | awk -F '.' '{print $3}'`"
78 if [ "$duplicity_major" -ge 0 -a "$duplicity_minor" -ge 4 -a "$duplicity_sub" -ge 2 ]; then
79    sftpoptions="$sshoptions"
80 fi
81
82 scpoptions="$sshoptions"
83 [ "$bandwidthlimit" == 0 ] || scpoptions="$scpoptions -l $bandwidthlimit"
84
85 if [ -z "$sftpoptions" ]; then
86    execstr="$options --no-print-statistics --scp-command 'scp $scpoptions' --ssh-command 'ssh $sshoptions' "
87 else
88    execstr="$options --no-print-statistics --scp-command 'scp $scpoptions' --sftp-command 'sftp $sftpoptions' --ssh-command 'ssh $sshoptions' "
89 fi
90
91 # deal with symmetric or asymmetric (public/private key pair) encryption
92 if [ -n "$encryptkey" ]; then
93     execstr="${execstr}--encrypt-key $encryptkey "
94     debug "Data will be encrypted with the GnuPG key $encryptkey."
95 else
96     debug "Data will be encrypted using symmetric encryption."
97 fi
98
99 # deal with data signing
100 if [ "$sign" == yes ]; then
101     # duplicity is not able to sign data when using symmetric encryption
102     [ -n "$encryptkey" ] || fatal "The encryptkey option must be set when signing."
103     # if needed, initialize signkey to a value that is not empty (checked above)
104     [ -n "$signkey" ] || signkey="$encryptkey"
105     execstr="${execstr}--sign-key $signkey "
106     debug "Data will be signed will the GnuPG key $signkey."
107 else
108     debug "Data won't be signed."
109 fi
110
111 # deal with GnuPG passphrase
112 [ -n "$password" ] || fatal "The password option must be set."
113
114 if [ "$keep" != "yes" ]; then
115     if [ "`echo $keep | tr -d 0-9`" == "" ]; then
116         keep="${keep}D"
117     fi
118     execstr="${execstr}--remove-older-than $keep "
119 fi
120
121 if [ "$incremental" == "no" ]; then
122     execstr="${execstr}--full "
123 fi
124
125 execstr_serverpart="scp://$destuser@$desthost/$destdir"
126 execstr_clientpart="/"
127
128 ### SOURCE ###
129
130 set -o noglob
131
132 symlinks_warning="Maybe you have mixed symlinks and '*' in this statement, which is not supported."
133
134 # excludes
135 for i in $exclude; do
136    str="${i//__star__/*}"
137    str=`readlink -f $str`
138    if [ -n "$str" ]; then
139       execstr="${execstr}--exclude '$str' "
140    else
141       warning "exclude statement '${i//__star__/*}' will be ignored. $symlinks_warning"
142    fi
143 done
144         
145 # includes 
146 for i in $include; do
147    [ "$i" != "/" ] || fatal "Sorry, you cannot use 'include = /'"
148    str="${i//__star__/*}"
149    str=`readlink -f $str`
150    if [ -n "$str" ]; then
151       execstr="${execstr}--include '$str' "
152    else
153       warning "include statement '${i//__star__/*}' will be ignored. $symlinks_warning"
154    fi
155 done
156
157 # vsincludes
158 if [ $usevserver = yes ]; then
159    for vserver in $vsnames; do
160       for vi in $vsinclude; do
161          str="${vi//__star__/*}"
162          str=`readlink -f $VROOTDIR/$vserver$str`
163          if [ -n "$str" ]; then
164             execstr="${execstr}--include '$str' "
165          else
166             warning "vsinclude statement '${vi//__star__/*}' will be ignored for VServer $vserver. $symlinks_warning"
167          fi
168       done
169    done
170 fi
171
172 set +o noglob
173
174 ### EXECUTE ###
175
176 execstr=${execstr//\\*/\\\\\\*}
177
178 debug "duplicity $execstr --exclude '**' / $execstr_serverpart"
179 if [ ! $test ]; then
180         export PASSPHRASE=$password
181         output=`nice -n $nicelevel \
182                   su -c \
183                     "duplicity $execstr --exclude '**' / $execstr_serverpart 2>&1"`
184         code=$?
185         if [ $code -eq 0 ]; then
186                 debug $output
187                 info "Duplicity finished successfully."
188         else
189                 debug $output
190                 fatal "Duplicity failed."
191         fi
192 fi      
193
194 return 0