tar: Support running on multiple backends.
[matthijs/upstream/backupninja.git] / handlers / wget
1 # -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*-
2 # vim: set filetype=sh sw=3 sts=3 expandtab autoindent:
3 #
4 # backupninja handler to do incremental backups using
5 # wget and hardlinks, based on rsync handler
6 #
7 # feedback: rhatto at riseup.net | gpl
8 #
9 # Config file options
10 # -------------------
11 #
12 #   [general]
13 #   log = wget log file
14 #   partition = partition where the backup lives
15 #   fscheck = set to 1 if fsck should run on $partition after the backup is made
16 #   read_only = set to 1 if $partition is mounted read-only
17 #   mountpoint = backup partition mountpoint or backup main folder
18 #   backupdir = folder relative do $mountpoint where the backup should be stored
19 #   days = number of backup increments (min = 5)
20 #   lockfile = lockfile to be kept during backup execution
21 #   nicelevel = wget command nice level
22 #   enable_mv_timestamp_bug = set to "yes" if your system isnt handling timestamps correctly
23 #   tmp = temp folder
24 #
25 #   [source]
26 #   wget = wget program
27 #   wget_options = wget command options
28 #   url = remote data url
29 #   bandwidthlimit = set a badnwidth limit in kbps (remote source only)
30 #
31 #   [destination]
32 #   folder = local folder
33 #
34 # You can also specify some system comands if you don't want the default system values:
35 #
36 #   [system]
37 #   rm = rm command
38 #   cp = cp command
39 #   touch = touch command
40 #   mv = mv command
41 #   fsck = fsck command
42 #
43 # TODO: Daily, weekly and monthly snapshot rotation (like the one present on maildir handler).
44 #
45
46 # config file evaluation
47
48 setsection system
49 getconf rm rm
50 getconf cp cp
51 getconf touch touch
52 getconf mv mv
53 getconf fsck fsck
54
55 setsection general
56 getconf log /var/log/backup/wget.log
57 getconf partition
58 getconf fscheck
59 getconf read_only
60 getconf mountpoint
61 getconf backupdir
62 getconf rotate
63 getconf days
64 getconf lockfile
65 getconf nicelevel 0
66 getconf enable_mv_timestamp_bug no
67 getconf tmp /tmp
68
69 setsection source
70 getconf wget wget
71 getconf wget_options
72 getconf url
73 getconf bandwidthlimit
74
75 setsection destination
76 getconf folder
77
78 # function definitions
79
80 function rotate {
81
82    if [[ "$2" < 4 ]]; then
83       error "Rotate: minimum of 4 rotations"
84       exit 1
85    fi
86
87    if [ -d $1.$2 ]; then
88       $nice $mv /$1.$2 /$1.tmp
89    fi
90
91    for ((n=`echo "$2 - 1" | bc`; n >= 0; n--)); do
92       if [ -d $1.$n ]; then
93          dest=`echo "$n + 1" | bc`
94          $nice $mv /$1.$n /$1.$dest
95          $touch /$1.$dest
96       fi
97    done
98
99    if [ -d $1.tmp ]; then
100       $nice $mv /$1.tmp /$1.0
101    fi
102
103    if [ -d $1.1 ]; then
104       $nice $cp -alf /$1.1/. /$1.0
105    fi
106
107 }
108
109 function move_files {
110    ref=$tmp/makesnapshot-mymv-$$;
111    $touch -r $1 $ref;
112    $mv $1 $2;
113    $touch -r $ref $2;
114    $rm $ref;
115 }
116
117 backupdir="$mountpoint/$backupdir"
118
119 # does $backupdir exists?
120
121 if [ ! -d "$backupdir" ]; then
122    error "Backupdir $backupdir does not exist"
123    exit 1
124 fi
125
126 # setup number of increments
127
128 if [ -z "$days" ]; then
129    keep="4"
130 else
131    keep="`echo $days - 1 | bc -l`"
132 fi
133
134 # lockfile setup
135
136 if [ ! -z "$lockfile" ]; then
137    $touch $lockfile || warning "Could not create lockfile $lockfile"
138 fi
139
140 # nicelevel setup
141
142 if [ ! -z "$nicelevel" ]; then
143    nice="nice -n $nicelevel"
144 else
145    nice=""
146 fi
147
148 # set mv procedure
149
150 if [ $enable_mv_timestamp_bug == "yes" ]; then
151    mv=move_files
152 fi
153
154 # set excludes
155
156 for path in $exclude; do
157    EXCLUDES="$EXCLUDES --exclude=$path"
158 done
159
160 echo "Starting backup at `date`" >> $log
161
162 # mount backup destination folder as read-write
163
164 if [ "$read_only" == "1" ] || [ "$read_only" == "yes" ]; then
165    if [ -d "$mountpoint" ]; then
166       mount -o remount,rw $mountpoint
167       if (($?)); then
168          error "Could not mount $mountpoint"
169          exit 1
170       fi
171    fi
172 fi
173
174 # the backup procedure
175
176 if [ ! -d "$backupdir/$folder/$folder.0" ]; then
177    mkdir -p $backupdir/$folder/$folder.0
178 fi
179
180 info "Rotating $backupdir/$folder/$folder..."
181 echo "Rotating $backupdir/$folder/$folder..." >> $log
182 rotate $backupdir/$folder/$folder $keep
183 info "Wget'ing $SECTION on $backupdir/$folder/$folder.0..."
184
185 if [ ! -z "$badnwidth" ]; then
186    limit_rate="--limit-rate=$badnwidth""k"
187 fi
188
189 cd $backupdir/$folder/$folder.0
190 wget $wget_options $limit-rate -r -c -N -e robots=off $url
191 cd -
192
193 $touch $backupdir/$folder/$folder.0
194
195 # remount backup destination as read-only
196
197 if [ "$read_only" == "1" ] || [ "$read_only" == "yes" ]; then
198    mount -o remount,ro $mountpoint
199 fi
200
201 # check partition for errors
202
203 if [ "$fscheck" == "1" ] || [ "$fscheck" == "yes" ]; then
204    umount $mountpoint
205    if (($?)); then
206       warning "Could not umount $mountpoint to run fsck"
207    else
208       $nice $fsck -v -y $partition >> $log
209       mount $mountpoint
210    fi
211 fi
212
213 # removes the lockfile
214
215 if [ ! -z "$lockfile" ]; then
216    $rm $lockfile || warning "Could not remove lockfile $lockfile"
217 fi
218
219 echo "Finnishing backup at `date`" >> $log
220