bugfixes + introduced cipher, added hannah config
[outofuni/backup.git] / bin / backup
1 #!/bin/bash
2
3 function log {
4         conf=`basename $config | sed 's/\.conf$//'`
5         [ "$dolog" = "1" ] && echo "`date` - $@" >> $logdir/${conf}.log
6 }
7
8 if [ -z "$1" ]; then
9         echo usage: $0 configfile
10         exit -1
11 fi
12
13 if [ ! -f $1 ]; then
14         echo configfile $1 is not a file
15         exit -2
16 fi
17
18 config=$1
19
20 host=`grep ^host $config | cut -d ' ' -f 2`
21 aliases="`grep ^aliases $config | cut -d ' ' -f 2-`"
22 user=`grep ^user $config | cut -d ' ' -f 2`
23 homedirs="` grep ^homedirs $config | cut -d ' ' -f 2-`"
24 extradirs="`grep ^extradirs $config | cut -d ' ' -f 2-`" 
25 replicas=`grep ^replicas $config | cut -d ' ' -f 2`
26 oldest=`grep ^oldest $config | cut -d ' ' -f 2`
27 data=`grep ^data $config | cut -d ' ' -f 2`
28 bandwidth=`grep ^bandwidth $config | cut -d ' ' -f 2`
29 bwconn="`grep ^bandwidth $config | cut -d ' ' -f 3-`"
30 compression=`grep ^compression $config | cut -d ' ' -f 2`
31 compconn="`grep ^compression $config | cut -d ' ' -f 3-`"
32 cipher=`grep ^cipher $config | cut -d ' ' -f 2`
33 ciconn=`grep ^cipher $config | cut -d ' ' -f 3-`
34 logdir=`grep ^logdir $config | cut -d ' ' -f 2`
35
36 dolog=0
37 if [ ! -z "$logdir" ]; then
38         mkdir -p $logdir
39         [ -d $logdir ] && dolog=1
40 fi
41
42 hit=0
43 for conn in $host $aliases; do
44         ping -c1 $conn > /dev/null 2>&1
45         ret=$?
46         if [ "$ret" = "0" ]; then
47                 remote=$conn
48                 break
49         fi
50 done
51 if [ -z "$remote" ]; then
52         log "host $host ($aliases) unreachable ..."
53         exit -3
54 else
55         log "host $host (via $remote) is online ..."
56 fi
57
58 comp=6
59 if [ ! -z "$compression" ]; then
60         comp=$compression
61         for cpair in "$compconn"; do
62                 ch=`echo $cpair | cut -d ':' -f 1`
63                 if [[ "$remote" == "$ch"* ]]; then
64                         cl=`echo $cpair | cut -d ':' -f 2`
65                         [[ "$cl" == [0-9] ]] && comp=$cl
66                 fi
67         done
68 fi
69 rcomp="-z --compress-level $comp"
70 log using compression level $comp ...
71
72 bw=0
73 if [ ! -z "$bandwidth" ]; then
74         bw=$bandwidth
75         for bwpair in "$bwconn"; do
76                 ch=`echo $bwpair | cut -d ':' -f 1`
77                 if [[ "$remote" == "$ch"* ]]; then
78                         bwl=`echo $cpair | cut -d ':' -f 2`
79                         [ ! -z "$bwl" ] && bw=$bwl
80                 fi
81         done
82 fi
83 rbw="--bwlimit=$bw"
84 log applying bandwidth of $bw ...
85
86 ciph=""
87 if [ ! -z "$cipher" ]; then
88         ciph=$cipher
89         for cipair in "$ciconn"; do
90                 ch=`echo $cipair | cut -d ':' -f 1`
91                 if [[ "$remote" == "$ch"* ]]; then
92                         cl=`echo $cipair | cut -d ':' -f 2`
93                         [ ! -z "$cl" ] && ciph=$cl
94                 fi
95         done
96 fi
97 if [ ! -z "$ciph" ]; then
98         log using cipher $ciph ...
99 fi
100
101 if [ ! -d $data ]; then
102         log no data directory ...
103         exit -4
104 fi
105 log backing up to $data ...
106
107 today=`date -I`
108 backupdir=$data/${user}_at_${host}
109 cbd=$backupdir/$today
110
111 ob=""
112 lpb=""
113 for pb in $backupdir/[0-9]*; do
114         [ ! -d $pb ] && continue
115         bdd=`basename $pb`
116         if [ ! -f $backupdir/.$bdd ]; then
117                 if [ "$pb" != "$cbd" ]; then
118                         rm -rf $cbd
119                         mv $pb $cbd
120                         log continuing $pb as $cbd ...
121                 fi
122         else
123                 lpb=$pb
124                 ob="$ob $pb"
125         fi
126 done
127
128
129 if [ ! -d $cbd ]; then
130         if [ ! -z "$lpb" ]; then
131                 cp -r $lpb $cbd
132                 log starting backup $today from $lpb ...
133         else
134                 mkdir -p $cbd
135                 log starting backup $today from scratch ...
136         fi
137 fi
138
139 if [ ! -f $backupdir/.$today ]; then
140         rsrc=""
141         for dir in $homedirs; do
142                 rsrc="$rsrc :/home/$user/$dir"
143         done
144         rsrc="`echo $rsrc | sed 's/^\ //'`"
145         for dir in $extradirs; do
146                 rsrc="$rsrc :$dir"
147         done
148         [ ! -z "$homedirs" ] && \
149                 log backing up home directories $homedirs ...
150         [ ! -z "$extradirs" ] && \
151                 log backing up directories $extradirs ...
152
153         if [ -z "$ciph" ]; then
154                 rsync=(rsync -aR $rcomp --delete $rbw $user@$remote$rsrc $cbd)
155         else
156                 rsync=(rsync -aR -e "ssh -c $ciph" $rcomp --delete)
157                 rsync+=($rbw $user@$remote$rsrc $cbd)
158         fi
159         "${rsync[@]}"
160
161         ret=$?
162         if [ "$ret" != "0" ]; then
163                 log backup terminated before completion ...
164                 exit -50
165         fi
166         
167         touch $backupdir/.$today
168         log "backup $today completed :)"
169 else
170         log backup $bdd found completed ...
171 fi
172
173 [ -z "$replicas" ] && replicas=3
174 [ -z "$oldest" ] && oldest=0
175
176 cob=`echo $ob | wc -w`
177 if [ $cob -gt $replicas ]; then
178         ((numdel=cob-replicas))
179         todel="`echo $ob | cut -d ' ' -f 1-${numdel}`"
180         for dirdel in $todel; do
181                 past=`basename $dirdel`
182                 ns=`date --date="$today" +%s`
183                 ps=`date --date="$past" +%s`
184                 ((delta=(ns-ps)/86400))
185                 if [ $delta -gt $oldest ]; then
186                         log "deleting $dirdel ($delta days old) ..."
187                         bdd=`basename $dirdel`
188                         rm -r $dirdel
189                         rm $backupdir/.$bdd
190                 else
191                         log "keeping $dirdel ($delta days old) ..."
192                 fi
193         done
194 fi
195
196 exit 0