]> git.decadent.org.uk Git - dak.git/blob - config/debian/cron.dinstall
Get rid of lots of repetitions calling stage
[dak.git] / config / debian / cron.dinstall
1 #!/bin/bash
2 # No way I try to deal with a crippled sh just for POSIX foo.
3
4 # Copyright (C) 2009-2012 Joerg Jaspert <joerg@debian.org>
5 #
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.
9 #
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.
14 #
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.
18
19 # Homer: Are you saying you're never going to eat any animal again? What
20 #        about bacon?
21 # Lisa: No.
22 # Homer: Ham?
23 # Lisa: No.
24 # Homer: Pork chops?
25 # Lisa: Dad, those all come from the same animal.
26 # Homer: Heh heh heh. Ooh, yeah, right, Lisa. A wonderful, magical animal.
27
28 # exit on errors
29 set -e
30 set -o pipefail
31 # make sure to only use defined variables
32 set -u
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)
36 set -E
37
38 # import the general variable set.
39 export SCRIPTVARS=/srv/ftp-master.debian.org/dak/config/debian/vars
40 . $SCRIPTVARS
41
42 ########################################################################
43 # Functions                                                            #
44 ########################################################################
45 # common functions are "outsourced"
46 . "${configdir}/common"
47
48 # source the dinstall functions
49 . "${configdir}/dinstall.functions"
50
51 ########################################################################
52 ########################################################################
53
54 # Function to save which stage we are in, so we can restart an interrupted
55 # dinstall. Or even run actions in parallel, if we dare to, by simply
56 # backgrounding the call to this function. But that should only really be
57 # done for things we don't care much about.
58 #
59 # This should be called with the first argument being an array, with the
60 # members
61 #  - FUNC - the function name to call
62 #  - ARGS - Possible arguments to hand to the function. Can be the empty string
63 #  - TIME - The timestamp name. Can be the empty string
64 #  - ERR  - if this is the string false, then the call will be surrounded by
65 #           set +e ... set -e calls, so errors in the function do not exit
66 #           dinstall. Can be the empty string, meaning true.
67 #
68 # MAKE SURE TO KEEP THIS THE LAST FUNCTION, AFTER ALL THE VARIOUS ONES
69 # ADDED FOR DINSTALL FEATURES!
70 function stage() {
71     ARGS='GO[@]'
72     local "${!ARGS}"
73
74     error=${ERR:-"true"}
75
76     ARGS=${ARGS:-""}
77
78     log "########## DINSTALL BEGIN: ${FUNC} ${ARGS} ##########"
79     STAGEFILE="${stagedir}/${FUNC}_${ARGS}"
80     STAGEFILE=${STAGEFILE// /_}
81     if [ -f "${STAGEFILE}" ]; then
82         stamptime=$(/usr/bin/stat -c %Z "${STAGEFILE}")
83         unixtime=$(date +%s)
84         difference=$(( $unixtime - $stamptime ))
85         if [ ${difference} -ge 14400 ]; then
86             log_error "Did already run ${FUNC}, stagefile exists, but that was ${difference} seconds ago. Please check."
87         else
88             log "Did already run ${FUNC}, not calling again..."
89         fi
90         return
91     fi
92
93     debug "Now calling function ${FUNC}. Arguments: ${ARGS}. Timestamp: ${TIME}"
94
95     # Make sure we are always at the same place. If a function wants to be elsewhere,
96     # it has to cd first!
97     cd ${configdir}
98
99     # Now redirect the output into $STAGEFILE.log. In case it errors out somewhere our
100     # errorhandler trap can then mail the contents of $STAGEFILE.log only, instead of a whole
101     # dinstall logfile. Short error mails ftw!
102     exec >> "${STAGEFILE}.log" 2>&1
103
104     if [ -f "${LOCK_STOP}" ]; then
105         log "${LOCK_STOP} exists, exiting immediately"
106         exit 42
107     fi
108
109     if [ "${error}" = "false" ]; then
110         set +e
111     fi
112     ${FUNC} ${ARGS}
113
114     # No matter what happened in the function, we make sure we have set -e default state back
115     set -e
116
117     # Make sure we are always at the same place.
118     cd ${configdir}
119
120     # We always use the same umask. If a function wants to do different, fine, but we reset.
121     umask 022
122
123     touch "${STAGEFILE}"
124
125     if [ -n "${TIME}" ]; then
126         ts "${TIME}"
127     fi
128
129     # And the output goes back to the normal logfile
130     exec >> "$LOGFILE" 2>&1
131
132     # Now we should make sure that we have a usable dinstall.log, so append the $STAGEFILE.log
133     # to it.
134     cat "${STAGEFILE}.log" >> "${LOGFILE}"
135     rm -f "${STAGEFILE}.log"
136
137     log "########## DINSTALL END: ${FUNC} ##########"
138
139     if [ -f "${LOCK_STOP}" ]; then
140         log "${LOCK_STOP} exists, exiting immediately"
141         exit 42
142     fi
143 }
144
145 ########################################################################
146
147 # We need logs.
148 LOGFILE="$logdir/dinstall.log"
149
150 exec >> "$LOGFILE" 2>&1
151
152 # And now source our default config
153 . "${configdir}/dinstall.variables"
154
155 # Make sure we start out with a sane umask setting
156 umask 022
157
158 # And use one locale, no matter what the caller has set
159 export LANG=C
160 export LC_ALL=C
161
162 touch "${DINSTALLSTART}"
163 ts "startup"
164 DINSTALLBEGIN="$(date -u +"%a %b %d %T %Z %Y (%s)")"
165 state "Startup"
166
167 lockfile -l 3600 "${LOCK_DAILY}"
168 trap onerror ERR
169 trap remove_daily_lock EXIT TERM HUP INT QUIT
170
171 touch "${LOCK_BRITNEY}"
172
173 # This loop simply wants to be fed by a list of values (see below)
174 # which consists of 5 values currently.
175 # The first four are the array values for the stage function, the
176 # fifths tells us if we should background the stage call.
177 #
178 #  - FUNC - the function name to call
179 #  - ARGS - Possible arguments to hand to the function. Can be the empty string
180 #  - TIME - The timestamp name. Can be the empty string
181 #  - ERR  - if this is the string false, then the call will be surrounded by
182 #           set +e ... set -e calls, so errors in the function do not exit
183 #           dinstall. Can be the empty string, meaning true.
184 #  - BG   - Background the function stage?
185 #
186 # ATTENTION: Spaces in arguments or timestamp names need to be escaped by \
187 #
188 # ATTENTION: There are two special values for the first column (FUNC).
189 #            STATE   - do not call stage function, call the state
190 #                      function to update the public statefile "where is dinstall"
191 #            NOSTAGE - do not call stage function, call the command directly.
192 while read FUNC ARGS TIME ERR BACKGROUND; do
193     debug "FUNC: $FUNC ARGS: $ARGS TIME: $TIME ERR: $ERR BG: $BACKGROUND"
194
195     # Empty values in the value list are the string "none" (or the
196     # while read loop won't work). Here we ensure that variables that
197     # can be empty, are empty if the string none is set for them.
198     for var in ARGS TIME; do
199         if [[ ${!var} == none ]]; then
200             typeset ${var}=''
201         fi
202     done
203
204     case ${FUNC} in
205         STATE)
206             state ${ARGS}
207         ;;
208         NOSTAGE)
209             ${ARGS}
210         ;;
211         *)
212             GO=(
213                 FUNC=${FUNC}
214                 TIME=${TIME}
215                 ARGS=${ARGS}
216                 ERR=${ERR}
217             )
218             if [[ ${BACKGROUND} == true ]]; then
219                 stage $GO &
220             else
221                 stage $GO
222             fi
223         ;;
224     esac
225 done < <(cat - <<EOF
226 savetimestamp         none                  none           false              false
227 qa1                   init                  none           false              true
228 pg_timestamp          pg_dump1              predinstall    false              false
229 updates               External\ Updates     none           false              false
230 i18n1                 i18n\ 1               none           false              false
231 dep11                 dep11\ 1              none           false              false
232 NOSTAGE               lockaccepted          none           false              false
233 punew                 p-u-new               stable-new     false              false
234 opunew                o-p-u-new             oldstable-new  false              false
235 backports_policy      backports-policy      none           false              false
236 cruft                 cruft                 none           false              false
237 STATE                 indices               none           false              false
238 dominate              dominate              none           false              false
239 autocruft             autocruft             unstable\ experimental false      false
240 fingerprints          import-keyring        none           false              false
241 overrides             overrides             none           false              false
242 mpfm                  pkg-file-mapping      none           false              false
243 STATE                 packages/contents     none           false              false
244 packages              apt-ftparchive        none           false              false
245 STATE                 dists/                none           false              false
246 pdiff                 pdiff                 none           false              false
247 release               release\ files        none           false              false
248 dakcleanup            cleanup               none           false              false
249 STATE                 scripts               none           false              false
250 mkmaintainers         mkmaintainers         none           false              false
251 copyoverrides         copyoverrides         none           false              false
252 mklslar               mklslar               none           false              false
253 mkfilesindices        mkfilesindices        none           false              false
254 mkchecksums           mkchecksums           none           false              false
255 mirror                mirror\ hardlinks     none           false              false
256 ddaccess              ddaccessible\ sync    none           false              false
257 NOSTAGE               remove_locks          none           false              false
258 STATE                 postlock              none           false              false
259 changelogs            changelogs            none           false              true
260 pg_timestamp          pg_dump2              postdinstall   false              false
261 expire                expire_dumps          none           false              true
262 transitionsclean      transitionsclean      none           false              true
263 dm                    none                  none           false              true
264 bts                   none                  none           false              true
265 mirrorpush            mirrorpush            none           false              true
266 mirrorpush-backports  mirrorpush-backports  none           false              true
267 i18n2                 i18n\ 2               none           false              true
268 stats                 stats                 none           false              true
269 testingsourcelist     none                  none           false              true
270 NOSTAGE               rm\ -f\ "\${LOCK_BRITNEY}" none      false              false
271 cleantransactions     none                  none           false              false
272 EOF
273         )
274
275 # we need to wait for the background processes before the end of dinstall
276 wait
277
278 log "Daily cron scripts successful, all done"
279
280 exec > "$logdir/afterdinstall.log" 2>&1
281
282 GO=(
283     FUNC="renamelogfile"
284     TIME=""
285     ARGS=""
286     ERR="false"
287 )
288 stage $GO
289 state "all done"
290
291
292 # Now, at the very (successful) end of dinstall, make sure we remove
293 # our stage files, so the next dinstall run will do it all again.
294 rm -f ${stagedir}/*
295 touch "${DINSTALLEND}"