summaryrefslogtreecommitdiff
path: root/bin/runmirrors
blob: 2cbce588ab7596d2faf7ddde2d7862788a9723a9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
#! /bin/bash

set -e
set -u

# runmirrors script for Debian
# Based losely on existing scripts, written by an unknown number of
# different people over the years.
#
# Copyright (C) 2008 Joerg Jaspert <joerg@debian.org>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; version 2.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

# In case the admin somehow wants to have this script located someplace else,
# he can set BASEDIR, and we will take that. If it is unset we take ${HOME}
BASEDIR=${BASEDIR:-"${HOME}"}

NAME="`basename $0`"

# In case we are called with an argument we look for a different configuration.
CONF=${1:-""}
if [ -n "${CONF}" ]; then
	NAME="${NAME}-${CONF}"
fi

# Read our config file
. "${BASEDIR}/etc/${NAME}.conf"

# Source our common functions
. "${BASEDIR}/etc/common"

# Set sane defaults if the configfile didn't do that for us.
# The directory for our logfiles
LOGDIR=${LOGDIR:-"${BASEDIR}/log"}
# Our own logfile
LOG=${LOG:-"${LOGDIR}/${NAME}.log"}
# Our lockfile directory
LOCKDIR=${LOCKDIR:-"${BASEDIR}/locks"}
# How many logfiles to keep
LOGROTATE=${LOGROTATE:-14}
# Our mirrorfile
MIRRORS=${MIRRORS:-"${BASEDIR}/etc/${NAME}.mirror"}
# used by log()
PROGRAM=${PROGRAM:-"${NAME}-$(hostname -s)"}
# extra ssh options we might want hostwide
SSH_OPTS=${SSH_OPTS:-""}
# Whats our archive name? We will also tell our leafs about it
PUSHARCHIVE=${PUSHARCHIVE:-"${CONF}"}
# How long to wait for mirrors to do stage1 if we have multi-stage syncing
PUSHDELAY=${PUSHDELAY:-240}
# Which ssh key to use?
KEYFILE=${KEYFILE:-".ssh/pushmirror"}
# where to send mails to
if [ "x$(hostname -s)x" != "x${MIRRORNAME%%.debian.org}x" ]; then
	# We are not on a debian.org host
	MAILTO=${MAILTO:-"root"}
else
	# Yay, on a .debian.org host
	MAILTO=${MAILTO:-"mirrorlogs@debian.org"}
fi

if ! [ -f "${BASEDIR}/${KEYFILE}" ]; then
	error "SSH Key ${BASEDIR}/${KEYFILE} does not exist" >> ${LOG}
	exit 5
fi

# Hooks
HOOK1=${HOOK1:-""}
HOOK2=${HOOK2:-""}
HOOK3=${HOOK3:-""}

# Some sane defaults
cd ${BASEDIR}
umask 022

# Make sure we have our log and lock directories
mkdir -p "${LOGDIR}"
mkdir -p "${LOCKDIR}"

trap 'log "Mirrorpush done" >> ${LOG}; savelog "${LOG}" > /dev/null' EXIT

log "Pushing leaf mirrors" >> ${LOG}

HOOK=(
	HOOKNR=1
	HOOKSCR=${HOOK1}
)
hook $HOOK

# From here on we do *NOT* want to exit on errors. We don't want to
# stop pushing mirrors just because we can't reach one of them.
set +e

# Built up our list of 2-stage mirrors.
PUSHLOCKS=""
PUSHLOCKS=$(get2stage)

# In case we have it - remove. It is used to synchronize multi-stage mirroring
rm -f "${LOCKDIR}/all_stage1"

# Now read our mirrorfile and push the mirrors defined in there.
# We use grep to easily sort out all lines having a # in front of them or are empty.
egrep -v '^[[:space:]]*(#|$)' "${MIRRORS}" |
while read MTYPE MLNAME MHOSTNAME MUSER MPROTO MKEYFILE; do
	if [ "x${MTYPE}x" = "xDELAYx" ]; then
		# We should wait a bit.
		if [ -z ${MLNAME} ]; then
			MLNAME=60
		fi
		log "Delay of ${MLNAME} requested, sleeping" >> "${LOG}"
		sleep ${MLNAME}
		continue
	fi

	# Process the two options that can be left blank in the config
	if [ -z ${MPROTO} ]; then
		MPROTO=2
	fi
	if [ -z ${MKEYFILE} ]; then
		MKEYFILE="${BASEDIR}/${KEYFILE}"
	fi
	# Now, people can do stupid things and leave out the protocol, but
	# define a keyfile...
	if [ ${MPROTO} -ne 1 ] && [ ${MPROTO} -ne 2 ]; then
		error "Need a correct ssh protocol version for ${MLNAME}, skipping" >> ${LOG}
		continue
	fi

	# Built our array
	SIGNAL_OPTS=(
		MIRROR="${MLNAME}"
		HOSTNAME="${MHOSTNAME}"
		USERNAME="${MUSER}"
		SSHPROTO="${MPROTO}"
		SSHKEY="${MKEYFILE}"
		PUSHLOCKOWN="${LOCKDIR}/${MLNAME}.stage1"
		PUSHTYPE="${MTYPE}"
		PUSHARCHIVE=${PUSHARCHIVE}
	)

	# And finally, push the mirror
	log "Trigger ${MLNAME}" >> ${LOG}
	signal "${SIGNAL_OPTS}" &
	log "Trigger for ${MLNAME} done" >> ${LOG}

	HOOK=(
		HOOKNR=2
		HOOKSCR=${HOOK2}
	)
	hook $HOOK
	set +e
done

HOOK=(
	HOOKNR=3
	HOOKSCR=${HOOK3}
)
hook $HOOK

exit 0