2 # No way I try to deal with a crippled sh just for POSIX foo.
4 # Copyright (C) 2009-2015 Joerg Jaspert <joerg@debian.org>
6 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License as
8 # published by the Free Software Foundation; version 2.
10 # This program is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 # General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 # Homer: Are you saying you're never going to eat any animal again? What
25 # Lisa: Dad, those all come from the same animal.
26 # Homer: Heh heh heh. Ooh, yeah, right, Lisa. A wonderful, magical animal.
31 # make sure to only use defined variables
33 # ERR traps should be inherited from functions too. (And command
34 # substitutions and subshells and whatnot, but for us the functions is
35 # the important part here)
38 # And use one locale, no matter what the caller has set
44 # set DEBUG if you want to see a little more logs (needs to be used more)
47 # While this check can be done in the following case, some assumptions
48 # down there are easier if we sorted out calls without an arg before.
49 if [[ ${ARG} == meh ]]; then
51 This is the FTPMaster cronscript. It needs an argument or it won't do
54 Currently accepted Arguments:
56 unchecked - Process the unchecked queue
57 dinstall - Run a dinstall
58 hourly, daily, weekly - Run that part
64 # Make sure we start out with a sane umask setting
67 # import the general variable set.
68 export SCRIPTVARS=/srv/ftp-master.debian.org/dak/config/debian/vars
71 # common functions are "outsourced"
72 . "${configdir}/common"
74 # program name is the (lower cased) first argument.
77 # Timestamp when we started
78 NOW=$(date "+%Y.%m.%d-%H:%M:%S")
80 # Which list of tasks should we run?
81 TASKLIST="${configdir}/${PROGRAM}.tasks"
83 # A logfile for every cron script
84 LOGFILE="${logdir}/${PROGRAM}_${NOW}.log"
86 # Each "cronscript" may have a variables and a functions file
88 for what in variables functions; do
89 if [[ -f ${configdir}/${PROGRAM}.${what} ]]; then
90 . ${configdir}/${PROGRAM}.${what}
94 # Get rid of tempfiles at the end
95 trap cleanup EXIT TERM HUP INT QUIT
99 # Do not run during dinstall
100 if [[ -e ${LOCK_DAILY} ]]; then
103 # only run one cron.unchecked and also lock against hourly (newoverview)
104 if ! lockfile -r8 ${LOCK_UNCHECKED} 2> /dev/null; then
105 # log "aborting cron.unchecked because $LOCK_UNCHECKED has already been locked"
108 TMPFILES="${TMPFILES} ${LOCK_UNCHECKED}"
113 # Only one of me should ever run.
114 FLOCKER=${FLOCKER:-""}
115 [ "${FLOCKER}" != "${configdir}/${PROGRAM}.variables" ] && exec env FLOCKER="${configdir}/${PROGRAM}.variables" flock -E 0 -en "${configdir}/${PROGRAM}.variables" "$0" "$@" || :
124 error "Unknown arg ${ARG}"
129 # An easy access by name for the current log
130 ln -sf ${LOGFILE} ${logdir}/${PROGRAM}
132 # And from here, all output to the log please
133 exec >> "$LOGFILE" 2>&1
135 # The stage function uses this directory
136 # This amends the stagedir variable from "vars"
137 stagedir="${stagedir}/${PROGRAM}"
138 # Ensure the dir exists
141 # This loop simply wants to be fed by a list of values (see below)
142 # made out of 5 columns.
143 # The first four are the array values for the stage function, the
144 # fifth tells us if we should background the stage call.
146 # - FUNC - the function name to call
147 # - ARGS - Possible arguments to hand to the function. Can be the empty string
148 # - TIME - The timestamp name. Can be the empty string
149 # - ERR - if this is the string false, then the call will be surrounded by
150 # set +e ... set -e calls, so errors in the function do not exit
151 # dinstall. Can be the empty string, meaning true.
152 # - BG - Background the function stage?
154 # ATTENTION: Spaces in arguments or timestamp names need to be escaped by \
156 # NOTE 1: There are two special values for the first column (FUNC).
157 # STATE - do not call stage function, call the state
158 # function to update the public statefile "where is dinstall"
159 # NOSTAGE - do not call stage function, call the command directly.
161 # Note 2: If you want to hand an empty value to the stage function,
162 # use the word "none" in the list below.
163 while read FUNC ARGS TIME ERR BACKGROUND; do
164 debug "FUNC: $FUNC ARGS: $ARGS TIME: $TIME ERR: $ERR BG: $BACKGROUND"
166 # Empty values in the value list are the string "none" (or the
167 # while read loop won't work). Here we ensure that variables that
168 # can be empty, are empty if the string none is set for them.
169 for var in ARGS TIME; do
170 if [[ ${!var} == none ]]; then
175 # ERR/BACKGROUND are boolean, check that they are.
176 for var in ERR BACKGROUND; do
177 if [[ ${!var} != false ]] && [[ ${!var} != true ]]; then
178 error "Illegal value ${!var} for ${var} (should be true or false), line for function ${FUNC}"
196 if [[ ${BACKGROUND} == true ]]; then
203 done < <(grep -v '^#' ${TASKLIST} )
205 # we need to wait for the background processes before the end of the cron script
209 # Common to all cron scripts
210 log "Cron script successful, all done"
211 # Redirect output to another file, as we want to compress our logfile
212 # and ensure its no longer used
213 exec > "$logdir/after${PROGRAM}.log" 2>&1
221 touch "${DINSTALLEND}"
233 # Now, at the very (successful) end of this run, make sure we remove
234 # our stage files, so the next dinstall run will do it all again.
237 # FIXME: Mail the log when its non-empty
238 [[ -s "${logdir}/after${PROGRAM}.log" ]] || rm "${logdir}/after${PROGRAM}.log"