~svn/ubuntu/raring/subversion/ppa

« back to all changes in this revision

Viewing changes to contrib/server-side/svnmirror.sh

  • Committer: Bazaar Package Importer
  • Author(s): Adam Conrad
  • Date: 2005-12-05 01:26:14 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20051205012614-qom4xfypgtsqc2xq
Tags: 1.2.3dfsg1-3ubuntu1
Merge with the final Debian release of 1.2.3dfsg1-3, bringing in
fixes to the clean target, better documentation of the libdb4.3
upgrade and build fixes to work with swig1.3_1.3.27.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/bin/sh
 
2
#######################################################################
 
3
#
 
4
# svnmirror.sh
 
5
#
 
6
VERSION="0.0.6"
 
7
#
 
8
# This script syncs changes from a developer repository to a
 
9
#             _READONLY_public_repository_
 
10
#
 
11
# It supports pushing or pulling the changes via ssh and svn tools.
 
12
# It is intended to be run manually or from cron.
 
13
#
 
14
#######################################################################
 
15
#
 
16
# Things you have to take care of:
 
17
#
 
18
# 1. You need write access to the directory structure on both boxes
 
19
#    for more see the warning at:
 
20
#    http://svnbook.red-bean.com/html-chunk/ch06s03.html
 
21
#
 
22
# 2. For running it from cron i suggest the use of the ssh agent e.g
 
23
#    via keychain <http://www.gentoo.org/proj/en/keychain.xml>
 
24
#    in general read "man ssh-agent" and "man ssh-keygen".
 
25
#
 
26
# 3. Do NOT run it from post commit scripts it can lead to broken public
 
27
#    repositories!
 
28
#
 
29
# 4. You do not have to be afraid of the public repos. If the pipe is
 
30
#    broken nothing will be committed to it.
 
31
#    21:40:47 <@sussman> tberman:  welcome to atomic commits.
 
32
#
 
33
# 5. For local syncing use "svnadmin hotcopy"
 
34
#    see: "svnadmin help hotcopy"
 
35
#
 
36
#######################################################################
 
37
#
 
38
# Authors:
 
39
#    - Martin Furter <mf@rola.ch>
 
40
#    - Marcus Rückert <darix@irssi.org>
 
41
#    - Joerg Sonnenberger <joerg@bec.de>
 
42
#
 
43
#    with suggestions from:
 
44
#       - tberman (#svn at freenode)
 
45
#         - he actually needed such a script :)
 
46
#       - Erik Huelsmann <e.huelsmann@gmx.net>
 
47
#         - the little if for remote version :)
 
48
#         - status reply
 
49
#       - Ben Collins-Sussman <sussman@collab.net>
 
50
#         - for some help with the svn commands
 
51
#       - Bjørn Magnus Mathisen <epic@generation.no>
 
52
#         - for pointing out i forgot to replace one ssh with $LSSH
 
53
#       - John Belmonte <john@neggie.net>
 
54
#         - for pointing out that we use stderr for a non-error message
 
55
#
 
56
# Users:
 
57
#    our biggest users atm are Mono Project and MonoDevelop
 
58
#    Mono Team currently mirrors the repos every 30 minutes!:)
 
59
#    see http://www.mono-project.com/contributing/anonsvn.html
 
60
#
 
61
# License:
 
62
#    The same as svn itself. for latest version check:
 
63
#    http://svn.collab.net/repos/svn/trunk/subversion/LICENSE
 
64
#
 
65
# Thanks to the subversion team for their great work.
 
66
#
 
67
# Links:
 
68
#    If you do not like our solution check:
 
69
#       - svnpush
 
70
#         + http://svn.collab.net/repos/svn/trunk/contrib/client-side/svn-push/svn-push.c
 
71
#       - svn replicate
 
72
#         + https://open.datacore.ch/read-only/
 
73
#       - SVN::Mirror and SVN::Web
 
74
#         + http://svn.elixus.org/repos/member/clkao/
 
75
#         + http://svn.elixus.org/svnweb/repos/browse/member/clkao/ 
 
76
#
 
77
# Changes:
 
78
#
 
79
#  0.0.6
 
80
#    + print a non-error message to stdout instead of stderr.
 
81
#  0.0.5
 
82
#    + added DUMPPARAMS to specify the params for the svnadmin dump call
 
83
#    + added note about svnadmin 1.1 and "--deltas" cmdline option
 
84
#    * made the script POSIX sh-compatible
 
85
#      (zsh in native-mode does not work atm!)
 
86
#    * changed handling of default settings
 
87
#    * created config file has all lines commented out now
 
88
#    + check if necessary values are set
 
89
#    + added note about current users
 
90
#    * fixed documentation in the default config
 
91
#
 
92
#  0.0.4
 
93
#    + added comandline switch -v which shows the version.
 
94
#    + using markers now to find the config so it's not twice in this script
 
95
#    + added/changed some more documentation
 
96
#
 
97
#  0.0.3
 
98
#    + added comandline switches: -C (create config) -f (read config file)
 
99
#      -h (help) -q (quiet).
 
100
#
 
101
#  0.0.2
 
102
#    * initial version
 
103
#
 
104
#######################################################################
 
105
#
 
106
# uncomment this line for debugging
 
107
# set -x
 
108
#
 
109
#_CONFIG_START_MARKER
 
110
#######################################################################
 
111
#
 
112
# svnmirror default config
 
113
#
 
114
# Everything starting with "R" refers to the remote host
 
115
# with "L" to the local host
 
116
#
 
117
# the required variables are LREPOS, RREPOS and RHOST
 
118
#
 
119
#######################################################################
 
120
#
 
121
# Mode:
 
122
#
 
123
# push == Mirror from local repository to remote (readonly) repository
 
124
# pull == Mirror from remote repository to local (readonly) repository
 
125
#
 
126
DFLT_MODE="push"
 
127
 
 
128
#
 
129
# keychain = path to keychain sh file
 
130
# If the variable is not set, the script tries to read
 
131
# "$HOME/.keychain/`uname -n`-sh", if it is readable.
 
132
#
 
133
DFLT_KEYCHAIN=""
 
134
 
 
135
#
 
136
# DUMPPARMS
 
137
#
 
138
# see "svnadmin help dump" for it.
 
139
# default is "--incremental"
 
140
 
141
# if you use svn 1.1 on both you should add "--deltas"
 
142
# it should speed up the transfer on slow lines.
 
143
#
 
144
DFLT_DUMPPARAMS="--incremental"
 
145
 
 
146
# Absolute path of svnlook on the local host.
 
147
DFLT_LSVNLOOK="/usr/bin/svnlook"
 
148
 
 
149
# Absolute path of svnadmin on the local host.
 
150
DFLT_LSVNADMIN="/usr/bin/svnadmin"
 
151
 
 
152
# Absolute path to the repository on the local host.
 
153
# REQUIRED
 
154
DFLT_LREPOS="/path/to/repos"
 
155
 
 
156
# Absolute path of ssh on the local host.
 
157
#   '-c blowfish -C' to speed up the transfer a bit :)
 
158
DFLT_LSSH="/usr/bin/ssh -c blowfish -C"
 
159
 
 
160
# Name or IP of the remote host.
 
161
# REQUIRED
 
162
DFLT_RHOST="host"
 
163
 
 
164
# UNIX username on the remote host.
 
165
# defaults to the local username.
 
166
DFLT_RUSER="user"
 
167
 
 
168
# Absolute path of svnlook on the remote host.
 
169
DFLT_RSVNLOOK="/usr/bin/svnlook"
 
170
 
 
171
# Absolute path of svnadmin on the remote host.
 
172
DFLT_RSVNADMIN="/usr/bin/svnadmin"
 
173
 
 
174
# Absolute path to the repository on the remote host.
 
175
# REQUIRED
 
176
DFLT_RREPOS="/path/to/repos"
 
177
 
 
178
# Additional commands you want to run before loading the dump in to the repos
 
179
# e.g. setting umask or change group via newgrp.
 
180
#
 
181
# Make sure the last char is a ";".
 
182
#
 
183
DFLT_LADDITIONAL=""
 
184
DFLT_RADDITIONAL=""
 
185
 
 
186
#_CONFIG_END_MARKER
 
187
#######################################################################
 
188
#
 
189
# create a config file
 
190
#
 
191
#######################################################################
 
192
 
 
193
create_config()
 
194
{
 
195
    CFGFILE="$1"
 
196
    if [ -f "${CFGFILE}" ]; then
 
197
        echo "config file '${CFGFILE}' already exists." >&2
 
198
        exit 1
 
199
    fi
 
200
    SVNMIRROR="$0"
 
201
    if [ ! -f "$0" ]; then
 
202
        SVNMIRROR=`which "$0"`
 
203
        if [ $? -ne 0 ]; then
 
204
            echo "could not locate $0" >&2
 
205
            exit 1
 
206
        fi
 
207
    fi
 
208
    STARTLINE=`grep -n "^#_CONFIG_START_MARKER" "$SVNMIRROR" | sed 's/:.*$//'`
 
209
    ENDLINE=`grep -n "^#_CONFIG_END_MARKER" "$SVNMIRROR" | sed 's/:.*$//'`
 
210
    ENDLINE=`expr ${ENDLINE} - 1`
 
211
    LINECOUNT=`expr ${ENDLINE} - ${STARTLINE}`
 
212
    head -n ${ENDLINE} "$SVNMIRROR" | tail -$LINECOUNT | sed -e 's/^#/##/' -e 's/^DFLT_/# /g' | \
 
213
        sed 's/default config/config/' > "$CFGFILE"
 
214
}
 
215
 
 
216
#######################################################################
 
217
#
 
218
# parse the commandline
 
219
#
 
220
#######################################################################
 
221
#
 
222
 
223
 
 
224
show_help()
 
225
{
 
226
    echo ""
 
227
    echo "usage:"
 
228
    echo "  svnmirror.sh [-f configfile] [-h] [-q] [-v]"
 
229
    echo "  svnmirror.sh -C configfile"
 
230
    echo ""
 
231
    echo "  -C configfile   create a config file"
 
232
    echo "  -f configfile   read config from the specified file"
 
233
    echo "  -h              show this help"
 
234
    echo "  -q              quiet (-q -q for really quiet)"
 
235
    echo "  -v              show version"
 
236
    echo ""
 
237
    echo "Note: For -f, configfile is relative to the current PATH settings"
 
238
    echo ""
 
239
}
 
240
 
 
241
CONFIGREAD=false
 
242
QUIET=""
 
243
VERBOSE=true
 
244
while getopts C:f:hqv OPTION; do
 
245
    case "$OPTION" in
 
246
        C)
 
247
            create_config "${OPTARG}"
 
248
            exit 0
 
249
            ;;
 
250
        f)
 
251
            if [ ${CONFIGREAD} = true ]; then
 
252
                echo "config already read" >&2
 
253
                exit 1
 
254
            elif [ ! -r "${OPTARG}" ]; then
 
255
                echo "cannot read config file '${OPTARG}'" >&2
 
256
                exit 1
 
257
            else
 
258
                . ${OPTARG}
 
259
            fi
 
260
            ;;
 
261
        h)
 
262
            show_help
 
263
            exit 0
 
264
            ;;
 
265
        q)
 
266
            if [ -z "${QUIET}" ]; then
 
267
                QUIET="-q"
 
268
            else
 
269
                VERBOSE=false
 
270
            fi
 
271
            ;;
 
272
        v)
 
273
            echo "svnmirror.sh $VERSION"
 
274
            exit 0
 
275
            ;;
 
276
        \?)
 
277
            echo "  for help use $0 -h"
 
278
            exit 1
 
279
            ;;
 
280
    esac
 
281
done
 
282
 
 
283
#######################################################################
 
284
#
 
285
# add default values
 
286
#
 
287
#######################################################################
 
288
MODE="${MODE:-$DFLT_MODE}"
 
289
DUMPPARAMS="${DUMPPARAMS:-$DFLT_DUMPPARAMS}"
 
290
LSVNLOOK="${LSVNLOOK:-$DFLT_LSVNLOOK}"
 
291
LSVNADMIN="${LSVNADMIN:-$DFLT_LSVNADMIN}"
 
292
LSSH="${LSSH:-$DFLT_LSSH}"
 
293
RUSER="${RUSER:-$USER}"
 
294
RSVNLOOK="${RSVNLOOK:-$DFLT_RSVNLOOK}"
 
295
RSVNADMIN="${RSVNADMIN:-$DFLT_RSVNADMIN}"
 
296
LADDITIONAL="${LADDITIONAL:-$DFLT_LADDITIONAL}"
 
297
RADDITIONAL="${RADDITIONAL:-$DFLT_RADDITIONAL}"
 
298
 
 
299
echo "${LREPOS:?Required variable LREPOS is not set in config file}" > /dev/null
 
300
echo "${RREPOS:?Required variable RREPOS is not set in config file}" > /dev/null
 
301
echo "${RHOST:?Required variable RHOST is not set in config file}" > /dev/null
 
302
 
 
303
KEYCHAIN="${KEYCHAIN:-$HOME/.keychain/`uname -n`-sh}"
 
304
[ -n "${KEYCHAIN}" -a -r "${KEYCHAIN}" ] && . ${KEYCHAIN}
 
305
 
 
306
#######################################################################
 
307
#
 
308
# the actual script
 
309
#
 
310
#######################################################################
 
311
#
 
312
 
 
313
#
 
314
# getting version of the remote repository
 
315
#
 
316
RVERSION=`${LSSH} ${RUSER}@${RHOST} ${RSVNLOOK} youngest ${RREPOS}`
 
317
if [ -z "${RVERSION}" ] ; then
 
318
    echo "getting version of remote repository failed" >&2
 
319
    exit 1
 
320
fi
 
321
 
 
322
#
 
323
# getting version of the local repository
 
324
#
 
325
${LADDITIONAL}
 
326
LVERSION=`${LSVNLOOK} youngest ${LREPOS}`
 
327
if [ -z "${LVERSION}" ] ; then
 
328
    echo "getting version of local repository failed" >&2
 
329
    exit 1
 
330
fi
 
331
 
 
332
#
 
333
# compare revision numbers
 
334
#
 
335
if [ ${RVERSION} -eq ${LVERSION} ] ; then
 
336
    [ ${VERBOSE} = true ] && \
 
337
        echo "both repositories are already at ${LVERSION}"
 
338
    exit 0
 
339
fi
 
340
 
 
341
#
 
342
# syncing
 
343
#
 
344
RC=0
 
345
if [ ${MODE} = "push" ] ; then
 
346
    if [ ${RVERSION} -gt ${LVERSION} ] ; then
 
347
        echo "revision of remote repos is higher than local one" >&2
 
348
        exit 1
 
349
    fi
 
350
    REVRANGE="`expr ${RVERSION} + 1`:${LVERSION}"
 
351
    [ ${VERBOSE} = true ] && \
 
352
        echo -n "syncing r${REVRANGE} to ${RHOST} ";
 
353
    ${LSVNADMIN} dump ${QUIET} ${DUMPPARAMS} -r${REVRANGE} ${LREPOS} | \
 
354
    ${LSSH} ${RUSER}@${RHOST} "${RADDITIONAL} ${RSVNADMIN} load ${QUIET} ${RREPOS}" || \
 
355
    RC=1
 
356
elif [ ${MODE} = "pull" ] ; then
 
357
    if [ ${LVERSION} -gt ${RVERSION} ] ; then
 
358
        echo "revision of local repos is higher than remote one" >&2
 
359
        exit 1
 
360
    fi
 
361
    REVRANGE="`expr ${LVERSION} + 1`:${RVERSION}"
 
362
    [ ${VERBOSE} = true ] && \
 
363
        echo -n "syncing r${REVRANGE} from ${RHOST} ";
 
364
    ${LSSH} ${RUSER}@${RHOST} \
 
365
    "${RADDITIONAL} ${RSVNADMIN} dump ${QUIET} ${DUMPPARAMS} -r${REVRANGE} ${RREPOS}" | \
 
366
    ${LSVNADMIN} load ${QUIET} ${LREPOS} || \
 
367
    RC=1
 
368
else
 
369
    echo "invalid mode \"${MODE}\" specified!" >&2
 
370
    exit 1
 
371
fi
 
372
if [ ${RC} -ne 0 ]; then
 
373
    echo "failed" >&2
 
374
else
 
375
    [ ${VERBOSE} = true ] && \
 
376
        echo "successfull completed."
 
377
fi
 
378
exit ${RC}
 
379
 
 
380
 
 
381