fixed configuration files permission check
[matthijs/upstream/backupninja.git] / handlers / rsnap
1 # -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*-
2 #
3 # rsync backup handler for backupninja
4 # requires rsync and optional freedups 
5 #
6 # freedups:
7 # http://www.stearns.org/freedups/
8 # http://freshmeat.net/projects/freedups/
9 #
10 # rsync:
11 # http://samba.anu.edu.au/rsync/
12
13 # exit on error
14 #set -e 
15
16 # System commands used by this script 
17 # replace with absolute path's if neccecary
18 getconf rm rm
19 getconf cp cp
20 getconf touch touch
21 getconf mv mv
22 getconf ssh ssh
23 getconf tr tr
24 getconf rsync $RSYNC
25
26 setsection options
27 getconf options
28 getconf label
29 getconf nicelevel 0
30 getconf keep 60
31
32 setsection source
33 getconf testconnect no
34 getconf srchost localhost
35 getconf compress 1
36 getconf sshoptions
37 getconf bandwidthlimit 1000
38 getconf remote_rsync rsync
39 getconf numericids 1
40 getconf include
41 getconf vsnames all
42 getconf vsinclude
43 getconf include
44 getconf exclude
45
46 setsection dest
47 getconf directory
48 getconf enable_mv_timestamp_bug no
49 getconf freedups freedups
50 getconf enable_freedups no
51 getconf incremental yes
52
53 # Apparently, a bug in some Linux kernels between 2.4.4 and 2.4.9 causes mv to update timestamps; 
54 # this may result in inaccurate timestamps on the snapshot directories. 
55 # Set enable_mv_timestamp_bug=1 to enable this workaround 
56 if [ $enable_mv_timestamp_bug == "yes" ]; then
57         mv=my_mv 
58 fi;
59
60 function my_mv() {
61    ref=/tmp/makesnapshot-mymv-$$;
62    $touch -r $1 $ref;
63    $mv $1 $2;
64    $touch -r $ref $2;
65    $rm $ref;
66 }
67
68 if [ $enable_freedups == "yes" ]; then
69         # $freedups
70         debug "Not implemented yet!"
71 fi;
72
73
74 [ "$directory" != "" ] || fatal "Destination directory not set"
75 [ "$include" != "" ] || fatal "No source includes specified"
76
77 ### vservers stuff ###
78
79 # If vservers are configured, check that the ones listed in $vsnames do exist.
80 local usevserver=no
81 if [ $vservers_are_available = yes ]; then
82    if [ "$vsnames" = all ]; then
83       vsnames="$found_vservers"
84    else
85       if ! vservers_exist "$vsnames" ; then
86             fatal "At least one of the vservers listed in vsnames ($vsnames) does not exist."
87       fi
88    fi
89    if [ -n "$vsinclude" ]; then
90       info "Using vservers '$vsnames'"
91       usevserver=yes
92    fi
93 else
94    [ -z "$vsinclude" ] || warning 'vservers support disabled in backupninja.conf, vsincludes configuration lines will be ignored'
95    [ -z "$vsnames" ] || warning 'vservers support disabled in backupninja.conf, vsnames configuration line will be ignored'   
96 fi
97
98 ### see if we can login ###
99
100 if [ "$testconnect" == "yes" ]; then
101     debug "$ssh $sshoptions -o PasswordAuthentication=no $srchost  'echo -n 1'"
102     if [ ! $test ]; then
103         result=`ssh $sshoptions -o PasswordAuthentication=no $srchost  'echo -n 1'`
104         if [ "$result" != "1" ]; then
105             fatal "Can't connect to $srchost."
106         else
107             debug "Connected to $srchost successfully"
108         fi
109     fi
110 fi
111
112 ### COMMAND-LINE MANGLING ###
113
114 [ "$bandwidthlimit" == 1000 ]    || options="$options --bwlimit=$bandwidthlimit"
115 [ "$numericids"     == 1 ]       || options="$options --numeric-ids "
116 [ "$compress"       == 1 ]       || options="$options --compress "
117 [ "$remote_rsync"   == "rsync" ] || options="$options --rsync-path=$remote_rsync"
118
119 if [ "$nicelevel" -ne 0 ]; then 
120         nice="nice -n $nicelevel" ;
121 else 
122         nice="";
123 fi
124
125 execstr="$options --exclude '/' --delete-during --delete-excluded  --archive $sshoptions "
126
127 if [ "$incremental" == "no" ]; then
128     execstr="${execstr} --whole-file "
129 fi
130
131 execstr_serverpart="$srchost:/"
132
133
134 ### SOURCE ###
135
136 set -o noglob
137
138 # excludes
139 for i in $exclude; do
140         str="${i//__star__/*}"
141         #execstr="${execstr}--exclude '$str' "
142         execstr="${execstr}--exclude $str "
143 done
144         
145 # includes 
146 for i in $include; do
147         str="${i//__star__/*}"
148         #execstr="${execstr}--include '$str' "
149         execstr="${execstr}--include $str "
150 done
151
152 # vsincludes
153 if [ $usevserver = yes ]; then
154     for vserver in $vsnames; do
155         for vi in $vsinclude; do
156             str="${vi//__star__/*}"
157             execstr="${execstr}--include '$label/$vserver$str' "
158         done
159     done
160 fi
161
162
163 ### SNAPSHOT ROTATION ###
164
165 if [ "$incremental" == "yes" ]; then
166         debug "starting to rotate the old dirs"
167         # rotating snapshots 
168         # delete the oldest snapshot, if it exists:
169         debug "does $directory/$label/$keep exist?"
170         if [ -d "$directory/$label/$keep" ] ; then
171                 debug "$rm -rf $directory/$label/$keep" 
172                 if [ !$test ]; then 
173                         #$rm -rf "$directory/$label/$keep" ;
174                         debug "$rm -rf $directory/$label/$keep";
175                 fi;
176         fi;
177
178         # shift the snapshots(s) back by one, if they exist
179         for (( i=$keep; $i>=0; i--)) ; do 
180                 debug "does $directory/$label/$i exist?"
181                 if [ -d "$directory/$label/$i" ] ; then
182                         debug "$mv $directory/$label/$i $directory/$label/$(($i + 1))"
183                         if [ !$test ]; then 
184                                 $mv "$directory/$label/$i" "$directory/$label/$(($i + 1))"
185                         fi;
186                 fi;
187         done
188
189         # make a hard-link-only (except for dirs) copy of
190         # assuming that exists, into the new dir
191         if [ -d "$directory/$label/1" ]; then   
192                 debug "$cp -al $directory/$label/1 $directory/$label/0"
193                 if [ !$test ]; then 
194                         $cp -al $directory/$label/1 $directory/$label/0 ;
195                 fi;
196         fi;
197
198 fi
199
200
201 set +o noglob
202
203 ### EXECUTE ###
204
205 # exclude everything else, start with root
206 #execstr="${execstr}--exclude '*' "
207                 
208 # include client-part and server-part
209 #execstr="$execstr $execstr_serverpart"
210
211 execstr=${execstr//\\*/\\\\\\*}
212
213 if [ "$debug" == "1" ]; then 
214         execstr=" --verbose $execstr";
215         # execstr=" --verbose --dry-run $execstr";
216 else 
217         execstr=" --quiet $execstr";
218 fi;
219
220 debug "$rsync $execstr $execstr_serverpart  $directory/$label/0"
221
222
223 # rsync from the system into the latest snapshot (notice that
224 # rsync behaves like cp --remove-destination by default, so the destination
225 # is unlinked first.  If it were not so, this would copy over the other
226 # snapshot(s) too!
227 output=`$nice $rsync $execstr $execstr_serverpart $directory/$label/0 2>&1`
228 code=$?
229
230 # update the mtime of the 0 dir to reflect the snapshot time
231 $touch $directory/$label/0 
232
233 if [ $code -eq 0 ]; then
234         debug $output
235         info "rsync finished successfully.";
236 else
237         debug "returncode $code : $output "
238         #fatal "rsync failed.";
239         warning "rsync failed.";
240 fi;
241
242
243 return 0;
244