Use shorter options (e.g. -r vs --recursive)
[public/mirror.git] / csc-sync-debian
1 #! /bin/bash
2
3 if [[ $# < 3 ]]; then
4   echo 'Usage: sync local_dir rsync_host rsync_dir [trace_host [trace_dir]]'
5   exit 1
6 fi
7
8 RSYNC="nice rsync"
9
10 set -e
11
12 TOP_DIR=/mirror
13 TO=$TOP_DIR/root/$1
14 RSYNC_HOST=$2
15 RSYNC_DIR=$3
16 if [ $# = 4 ]; then
17     TRACE_HOST=$4
18 fi
19 TRACE_DIR=project/trace
20 if [ $# = 5 ]; then
21     TRACE_DIR=$5
22 fi
23 LOGDIR=/var/log/mirror/$1_$2
24 ADDRESS=129.97.134.71
25
26 mkdir -p $LOGDIR
27
28 # This script originates from http://www.debian.org/mirror/anonftpsync
29
30 # CVS: cvs.debian.org:/cvs/webwml - webwml/english/mirror/anonftpsync
31 # Version: $Id: anonftpsync,v 1.33 2007/09/12 15:19:03 joy Exp $ 
32
33 # Note: You MUST have rsync 2.6.4 or newer, which is available in sarge
34 # and all newer Debian releases, or at http://rsync.samba.org/
35
36 # Don't forget:
37 # chmod u+x anonftpsync
38
39 # Set the variables below to fit your site. You can then use cron to have
40 # this script run daily to automatically update your copy of the archive.
41
42 # TO is the destination for the base of the Debian mirror directory
43 # (the dir that holds dists/ and ls-lR).
44 # (mandatory)
45
46 #TO=
47
48 # RSYNC_HOST is the site you have chosen from the mirrors file.
49 # (http://www.debian.org/mirror/list-full)
50 # (mandatory)
51
52 #RSYNC_HOST=
53
54 # RSYNC_DIR is the directory given in the "Packages over rsync:" line of
55 # the mirrors file for the site you have chosen to mirror.
56 # (mandatory)
57
58 #RSYNC_DIR=
59
60 # LOGDIR is the directory where the logs will be written to
61 # (mandatory)
62
63 #LOGDIR=
64
65 # ARCH_EXCLUDE can be used to exclude a complete architecture from
66 # mirrorring. Please use as space seperated list.
67 # Possible values are:
68 # alpha, amd64, arm, hppa, hurd-i386, i386, ia64, m68k, mipsel, mips, powerpc, s390, sh and sparc
69 #
70 # There is one special value: source
71 # This is not an architecture but will exclude all source code in /pool
72 #
73 # eg.
74 # ARCH_EXCLUDE="alpha arm hppa hurd-i386 ia64 m68k mipsel mips s390 sparc"
75
76 # With a blank ARCH_EXCLUDE you will mirror all available architectures
77 # (optional)
78
79 # EXCLUDE is a list of parameters listing patterns that rsync will exclude, in
80 # addition to the architectures excluded by ARCH_EXCLUDE.
81 #
82 # Use ARCH_EXCLUDE to exclude specific architectures or all sources
83 #
84 # --exclude stable, testing, unstable options DON'T remove the packages of
85 # the given distribution. If you want do so, use debmirror instead.
86 #
87 # The following example would exclude mostly everything:
88 #EXCLUDE="\
89 #  --exclude stable/ --exclude testing/ --exclude unstable/ \
90 #  --exclude source/ \
91 #  --exclude *.orig.tar.gz --exclude *.diff.gz --exclude *.dsc \
92 #  --exclude /contrib/ --exclude /non-free/ \
93 # "
94
95 # With a blank EXCLUDE you will mirror the entire archive, except the
96 # architectures excluded by ARCH_EXCLUDE.
97 # (optional)
98
99 EXCLUDE=
100
101 # LOCK_TIMEOUT is a timeout in minutes.  Defaults to 360 (6 hours).
102 # This program creates a lock to ensure that only one copy
103 # of it is mirroring any one archive at any one time.
104 # Locks held for longer than the timeout are broken, unless
105 # a running rsync process appears to be connected to $RSYNC_HOST.
106
107 LOCK_TIMEOUT=360
108
109 # There should be no need to edit anything below this point, unless there
110 # are problems.
111
112 #-----------------------------------------------------------------------------#
113
114 # If you are accessing a rsync server/module which is password-protected,
115 # uncomment the following lines (and edit the other file).
116
117 # . ftpsync.conf
118 # export RSYNC_PASSWORD
119 # RSYNC_HOST=$RSYNC_USER@$RSYNC_HOST
120
121 #-----------------------------------------------------------------------------#
122
123 # Check for some environment variables
124 if [ -z $TO ] || [ -z $RSYNC_HOST ] || [ -z $RSYNC_DIR ] || [ -z $LOGDIR ]; then
125         echo "One of the following variables seems to be empty:"
126         echo "TO, RSYNC_HOST, RSYNC_DIR or LOGDIR"
127         exit 2
128 fi
129
130 if ! [ -d ${TO}/${TRACE_DIR} ]; then
131         # we are running mirror script for the first time
132         umask 002
133         mkdir -p ${TO}/${TRACE_DIR}
134 fi
135
136 # Note: on some non-Debian systems, hostname doesn't accept -f option.
137 # If that's the case on your system, make sure hostname prints the full
138 # hostname, and remove the -f option. If there's no hostname command,
139 # explicitly replace `hostname -f` with the hostname.
140
141 HOSTNAME=`hostname -f`
142
143 # The hostname must match the "Site" field written in the list of mirrors.
144 # If hostname doesn't returns the correct value, fill and uncomment below 
145 HOSTNAME=mirror.csclub.uwaterloo.ca
146  
147 LOCK="${TO}/Archive-Update-in-Progress-${HOSTNAME}"
148
149 # The temp directory used by rsync --delay-updates is not
150 # world-readable remotely. It must be excluded to avoid errors. 
151 TMP_EXCLUDE="--exclude .~tmp~/"
152
153 # Exclude architectures defined in $ARCH_EXCLUDE
154 for ARCH in $ARCH_EXCLUDE; do
155         EXCLUDE=$EXCLUDE"\
156                 --exclude binary-$ARCH/ \
157                 --exclude disks-$ARCH/ \
158                 --exclude installer-$ARCH/ \
159                 --exclude Contents-$ARCH.gz \
160                 --exclude Contents-$ARCH.diff/ \
161                 --exclude arch-$ARCH.files \
162                 --exclude arch-$ARCH.list.gz \
163                 --exclude *_$ARCH.deb \
164                 --exclude *_$ARCH.udeb "
165         if [ "$ARCH" == "source" ]; then
166                 SOURCE_EXCLUDE="\
167                 --exclude source/ \
168                 --exclude *.tar.gz \
169                 --exclude *.diff.gz \
170                 --exclude *.dsc "
171         fi
172 done
173
174 # Logfile
175 LOGFILE=$LOGDIR/mirror.log
176
177 # Get in the right directory and set the umask to be group writable
178
179 cd $HOME
180 umask 002
181
182 # Check to see if another sync is in progress
183 if [ -f "$LOCK" ]; then
184 # Note: this requires the findutils find; for other finds, adjust as necessary
185   if [ "`find $LOCK -maxdepth 1 -amin -$LOCK_TIMEOUT`" = "" ]; then
186 # Note: this requires the procps ps; for other ps', adjust as necessary
187     if ps ax | grep '[r]'sync | grep -q $RSYNC_HOST; then
188       echo "stale lock found, but a rsync is still running, aiee!" > /dev/stderr
189       exit 1
190     else
191       echo "stale lock found (not accessed in the last $LOCK_TIMEOUT minutes), forcing update!"
192       rm -f $LOCK
193     fi
194   else
195     echo "current lock file exists, unable to start rsync!"
196     exit 1
197   fi
198 fi
199
200 touch $LOCK
201 # Note: on some non-Debian systems, trap doesn't accept "exit" as signal
202 # specification. If that's the case on your system, try using "0".
203 trap "rm -f $LOCK" exit
204
205 set +e
206
207 # check if we need to sync
208 if [[ "$TRACE_HOST" != "" ]]; then
209     TRACE_OLD_TIME=`stat -c%Y $TO/$TRACE_DIR/$TRACE_HOST 2> /dev/null`
210     TRACE_NEW_FILE=/tmp/$RSYNC_HOST_$RSYNC_DIR_$RANDOM
211     $RSYNC -tv --address=$ADDRESS \
212         $RSYNC_HOST::$RSYNC_DIR/$TRACE_DIR/$TRACE_HOST \
213         $TRACE_NEW_FILE >> $LOGFILE 2>&1
214     TRACE_NEW_TIME=`stat -c%Y $TRACE_NEW_FILE`
215     rm -f $TRACE_NEW_FILE
216     if [ "$TRACE_OLD_TIME" = "$TRACE_NEW_TIME" ]; then
217         echo 'Trace file for' $RSYNC_HOST::$RSYNC_DIR \
218             'unchanged, not rsyncing.' >> $LOGFILE
219         exit 0
220     fi
221 fi
222
223 # First sync /pool
224 $RSYNC -rlHtv \
225      $TMP_EXCLUDE $EXCLUDE $SOURCE_EXCLUDE \
226      --address=$ADDRESS \
227      $RSYNC_HOST::$RSYNC_DIR/pool/ $TO/pool/ >> $LOGFILE 2>&1
228 result=$?
229
230 if [ 0 = $result ]; then
231         # Now sync the remaining stuff
232         $RSYNC -rlHtv --delay-updates --delete-after \
233              --exclude "Archive-Update-in-Progress-${HOSTNAME}" \
234              --exclude "${TRACE_DIR}/${HOSTNAME}" \
235              --address=$ADDRESS \
236              $TMP_EXCLUDE $EXCLUDE $SOURCE_EXCLUDE \
237              $RSYNC_HOST::$RSYNC_DIR $TO >> $LOGFILE 2>&1
238
239         mkdir -p ${TO}/${TRACE_DIR}
240         LANG=C date -u > "${TO}/${TRACE_DIR}/${HOSTNAME}"
241 else
242         echo "ERROR: Help, something weird happened" | tee -a $LOGFILE
243         echo "mirroring /pool exited with exitcode" $result | tee -a $LOGFILE
244 fi
245
246 savelog $LOGFILE >/dev/null
247
248 rm $LOCK