]> oss.titaniummirror.com Git - tinyos-utils.git/blob - tinyos-mirror.sh
Added some new features to slice up the import from remote CVS via local CVS
[tinyos-utils.git] / tinyos-mirror.sh
1 #!/bin/bash
2 # tinyos-mirror.sh - Maintain a local git mirror of the tinyos CVS repository.
3 #
4 # This utility allows updating a local mirror of the TinyOS CVS modules as
5 # a set of three git repositories, one per notable CVS module:
6 # tinyos-1.x -> tinyos-1.x.git
7 # tinyos-2.x -> tinyos-2.x.git
8 # tinyos-2.x-contrib -> tinyos-2.x-contrib.git
9 #
10 # The utility actually allows both for creation and update of the local
11 # repos, with no pre-setup work other than ensuring proper permissions.
12 #
13 # The directories used by tinyos-mirror.sh must already exist and be owned by
14 # the user who runs tinyos-mirror.sh, and the directories must have their group
15 # set to that user's primary group, like so:
16 #
17 # drwxr-sr-x 5 sysadmin repo 60 2009-04-08 14:14 /var/lib/cvs
18 # drwxr-xr-x 7 sysadmin repo 112 2009-04-05 15:05 /var/lib/git
19 #
20 # Please note the permissions on the above directories. Also please note that
21 # any user or program wanting to access this information must be a member of
22 # the group 'repo', or whatever group is used in your installation.
23 #
24 # Configuration:
25 #
26 # 1. Decide on the user and group to use. The user to use must have its
27 # primary group set to the group selected.
28 #
29 # 2. Create /var/lib/cvs and /var/lib/git, owned by the selected group and
30 # user, and with the above permissions.
31 #
32 # 3. Verify the contents of the variables below which define the location of
33 # the upstream sources, the modules to mirror, etc.
34 #
35 # Usage:
36 #
37 # tinyos-mirror.sh [--cvslocal|--cvsdirect|--localonly|--rsynconly] [module [module ...]]
38 # No --xxx option implies update from upstream git.
39 # No module(s) implies update of all as defined in $MODULES.
40 #
41 # 1. To create or update the local git repos from the upstream git source,
42 # which is BY FAR the fastest option, run tinyos-mirror.sh with no arguments.
43 #
44 # 2. To create or update the local git repos from the upstream CVS source,
45 # which may be more definitive but much slower, run tinyos-mirror.sh with
46 # the --cvslocal option.
47 # --rsynconly does only the rsync update of the remote CVS to local CVS.
48 # --localonly does everything of --cvslocal except the rsync.
49 #
50 # 3. To update (not create!) the local git repos from the upstream CVS source
51 # directly via pserver (see the UPCVSROOT variable), then run the
52 # tinyos-mirror.sh script with the --cvsdirect option. This strategy is
53 # perhaps faster than option #2 above if relatively few changesets have
54 # been added upstream since the last invocation of tinyos-mirror.sh.
55 #
56 # It should be possible to invoke tinyos-mirror.sh using different update
57 # methods without creating problems. We have tested creating and initially
58 # populating the local git repos using --cvslocal and then following with
59 # periodic invocations using --cvsdirect. Other combinations have not been
60 # tested.
61 #
62 # By far the fastest and most resource friendly option is to use an upstream
63 # git server.
64
65 # Ensure these variables are correct for your installation
66
67 MODULES="tinyos-1.x tinyos-2.x tinyos-2.x-contrib"
68 GITBASE=/var/lib/git
69 UPGITBASE=git://hinrg.cs.hju.edu/git
70 CVSBASE=/var/lib/cvs
71 UPCVSROOT=:pserver:anonymous@tinyos.cvs.sourceforge.net:/cvsroot/tinyos
72 UPCVSRSYNC=rsync://tinyos.cvs.sourceforge.net/cvsroot/tinyos/
73
74 # There should be no need to change anything below this line
75
76 do_rsync()
77 {
78 echo "Update local CVS mirror via rsync"
79 links=""
80 if [ -d $CVSBASE/tinyos ]; then
81 if [ -d $CVSBASE/tinyos.backup ]; then
82 if [ -d $CVSBASE/tinyos.backup2 ]; then
83 echo "Mv $CVSBASE/tinyos.backup2 $CVSBASE/tinyos.backup3"
84 mv $CVSBASE/tinyos.backup2 $CVSBASE/tinyos.backup3
85 fi
86 echo "Mv $CVSBASE/tinyos.backup $CVSBASE/tinyos.backup2"
87 mv $CVSBASE/tinyos.backup $CVSBASE/tinyos.backup2
88 links="--link-dest=$CVSBASE/tinyos.backup2 $links"
89 fi
90 echo "Mv $CVSBASE/tinyos -> $CVSBASE/tinyos.backup"
91 mv $CVSBASE/tinyos $CVSBASE/tinyos.backup
92 links="--link-dest=$CVSBASE/tinyos.backup $links"
93 if [ -d $CVSBASE/tinyos.backup3 ]; then
94 echo "Mv $CVSBASE/tinyos.backup3 -> $CVSBASE/tinyos"
95 mv $CVSBASE/tinyos.backup3 $CVSBASE/tinyos
96 fi
97 else
98 echo "Cp $CVSBASE/tinyos.backup3 $CVSBASE/tinyos.backup"
99 cp -al $CVSBASE/tinyos.backup $CVS/tinyos # ok to fail
100 fi
101 echo "Rsync from sourceforge -> $CVSBASE/tinyos"
102 echo " links: $links"
103 rsync -avz --delete --no-g --chmod=Dg+s,Du+w $links \
104 --exclude "CVSROOT/CVS" \
105 $UPCVSRSYNC $CVSBASE/tinyos/
106 if [ $? -ne 0 ]; then
107 echo "rsync failed"
108 exit 1
109 fi
110 }
111
112 locks_present()
113 {
114 lines=$(find . -name "#cvs*" | wc -l)
115 if [ $lines -gt 0 ]; then
116 return 0 # locks are present
117 else
118 return 1 # no locks present
119 fi
120 }
121
122 do_bare()
123 {
124 # Ensure the bare repos are present
125 cd $GITBASE
126 for i in $MODULES; do
127 if [ ! -d $i.git ]; then
128 echo "Create shared repo $i.git"
129 rm -rf $i.git
130 mkdir $i.git
131 git --git-dir=$i.git init --bare
132 if [ $? -ne 0 ]; then
133 echo "git init failed"
134 exit 1
135 fi
136 echo "Mirror of the $i CVS module" > $i.git/description
137
138 # This line allows us to do cvsimport directly into this git repo,
139 # as git-cvsimport doesn't know how to work with bare repos.
140 ln -s ../$i.git $i.git/.git
141 fi
142 done
143 }
144
145 do_import()
146 {
147 # Now, do the imports. We limit the number of commits to prevent memory
148 # leaks from taking out the VE. This command is incremental, just adding
149 # new commits since the last run.
150 if [ ! -d $GITBASE/cvsimports ]; then
151 rm -rf $GITBASE/cvsimports
152 mkdir $GITBASE/cvsimports
153 chgrp repo $GITBASE/cvsimports
154 chmod 755 $GITBASE/cvsimports
155 chmod g+s $GITBASE/cvsimports
156 fi
157 cd $GITBASE/cvsimports
158 for i in $MODULES; do
159 echo "Import cvs module $i -> git"
160 git cvsimport -v -o master -d $CVSBASE/tinyos -C $i-import -i -k $i
161 if [ $? -ne 0 ]; then
162 echo "cvsimport failed"
163 exit 1
164 fi
165 if [ ! -f $i-import/.git/description ]; then
166 echo "Mirror of the $i CVS module" > $i.git/description
167 fi
168 done
169 }
170
171 do_push()
172 {
173 # Now we need to push the new commits in each of the import repos into the
174 # bare repos which are the pseudo-centralized shared repos.
175 cd $GITBASE/cvsimports
176 for i in $MODULES; do
177 echo "Push git import module cvsimports/$i-import -> $i.git"
178 git --git-dir=$i-import/.git push --mirror ../$i.git/
179 if [ $? -ne 0 ]; then
180 echo "git push failed"
181 exit 1
182 fi
183 done
184 }
185
186 do_import_cvsdirect()
187 {
188 # Do the imports, but directly with the sf.net CVS server. The
189 # sysadmin user must have first done a cvs login, and this script must
190 # run as the sysadmin user. We limit the number of commits to prevent
191 # memory leaks from taking out the VE. This command is incremental, just
192 # adding new commits since the last run.
193
194 cd $GITBASE
195 for i in $MODULES; do
196 echo "Update from CVS module DIRECT $i -> git"
197 git cvsimport -v -o master -d $UPCVSROOT -C $i.git -i -k -L2000 $i
198 if [ $? -ne 0 ]; then
199 echo "cvsimport failed"
200 exit 1
201 fi
202 done
203 }
204
205 do_import_localonly()
206 {
207 # Do the cvs-gitimports from the local CVS.
208
209 if locks_present; then
210 echo "Locks present in the CVS upstream. We won't import this time."
211 else
212 do_bare
213 do_import
214 do_push
215 fi
216 }
217
218 do_import_cvslocal()
219 {
220 # Do the imports by first using rsync to sync a local CVS from sf.net,
221 # then do cvs-gitimports from the local CVS.
222
223 do_rsync
224 do_import_localonly
225 }
226
227 do_import_git()
228 {
229 # Update from the git repos at hinrg. As of 4/8/09, only the tinyos-2.x
230 # repository seems to be being updated from the upstream sf.net CVS module.
231 # tinyos-1.x is 14 months old when the last update was 3/17/09, and
232 # tinyos-2.x-contrib.git is 5 months old when the last update was 4/7/09.
233
234 fail=0
235 cd $GITBASE
236 for i in $MODULES; do
237 if [ ! -d $i.git ]; then
238 rm -rf $i.git
239 echo "Clone gitupstream -> $i.git"
240 git clone --bare $UPGITBASE/$i.git
241 if [ $? -ne 0 ]; then
242 echo "git clone failed"
243 fail=$(($fail + 1))
244 fi
245
246 # This line allows us to do cvsimport directly into this git repo,
247 # as git-cvsimport doesn't know how to work with bare repos.
248 ln -s ../$i.git $i.git/.git
249 else
250 echo "Pull gitupstream -> $i.git"
251 git --git-dir=$i.git fetch $UPGITBASE/$i.git master:master
252 if [ $? -ne 0 ]; then
253 echo "git fetch failed"
254 fail=$(($fail + 1))
255 fi
256 fi
257 done
258 if [ $fail -gt 0 ]; then
259 echo "git import from git failed"
260 exit $fail
261 fi
262 }
263
264 # MAIN
265
266 unset option
267 unset opt_modules
268 while [ -n "$1" ]; do
269 if echo "$1" | grep -q -- "--"; then
270 if [ "$1" = "--cvslocal" -o "$1" = "--cvsdirect" -o "$1" = "--localonly" -o "$1" = "--rsynconly" ]; then
271 if [ -z "$option" ]; then
272 option=$1
273 fi
274 else
275 echo "$0: invalid option $1" >&2
276 exit 1
277 fi
278 else
279 opt_modules="$opt_modules $1"
280 fi
281 shift
282 done
283 if [ -n "$opt_modules" ]; then
284 MODULES="$opt_modules"
285 fi
286 echo "Updating modules $MODULES"
287
288 if [ "$option" = "--cvsdirect" ]; then
289 do_import_cvsdirect
290 elif [ "$option" = "--cvslocal" ]; then
291 do_import_cvslocal
292 elif [ "$option" = "--localonly" ]; then
293 do_import_localonly
294 elif [ "$option" = "--rsynconly" ]; then
295 do_rsync
296 else
297 do_import_git
298 fi
299 exit 0