summaryrefslogtreecommitdiff
path: root/bin/runmirrors
blob: d9e7bf137b25b625ed775c4c8232967d06b96324 (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
#! /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.
if [ -n "$1" ]; then
	NAME="${NAME}-$1"
fi

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

# Make sure some variables are always in the environment
export HOME LOGNAME USER PATH BASEDIR

# 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 to rotate the log
SAVELOG=${SAVELOG:-"savelog -t -c 14"}
# Amount of delay between mirrors if the mirror file contains a DELAY
DELAY=${DELAY:-"60"}
# 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:-""}

# 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}

if [ -n "${HOOK1}" ]; then
	log "Running hook1: ${HOOK1}" >> ${LOG}
	${HOOK1}
	result=$?
	log "Back from hook1, got returncode ${result}" >> ${LOG}
fi

# 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=""
egrep '^staged' ${MIRRORS} |
while read MTYPE MLNAME MHOSTNAME MUSER MPROTO MKEYFILE; do
	PUSHLOCKS="${PUSHLOCKS} ${LOCKDIR}/${MLNAME}.stage1"
done

# 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.
		log "Delay of ${DELAY} seconds requested, sleeping" >> ${LOG}
		sleep ${DELAY}
		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}"
	)

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

	if [ -n "${HOOK2}" ]; then
		log "Running hook2: ${HOOK2}" >> ${LOG}
		${HOOK1}
		result=$?
		log "Back from hook2, got returncode ${result}" >> ${LOG}
	fi
done

if [ -n "${HOOK3}" ]; then
	log "Running hook3: ${HOOK3}" >> ${LOG}
	${HOOK3}
	result=$?
	log "Back from hook3, got returncode ${result}" >> ${LOG}
fi

exit 0