]> git.decadent.org.uk Git - dak.git/blob - config/debian/cron.dinstall
dinstall
[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 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 # make sure to only use defined variables
31 set -u
32 # ERR traps should be inherited from functions too. (And command
33 # substitutions and subshells and whatnot, but for us the functions is
34 # the important part here)
35 set -E
36
37 # import the general variable set.
38 export SCRIPTVARS=/srv/ftp.debian.org/dak/config/debian/vars
39 . $SCRIPTVARS
40
41 ########################################################################
42 # Functions                                                            #
43 ########################################################################
44 # common functions are "outsourced"
45 . "${configdir}/common"
46
47 # Timestamp. Used for dinstall stat graphs
48 function ts() {
49         echo "Archive maintenance timestamp ($1): $(date +%H:%M:%S)"
50 }
51
52 # Cleanup actions
53 function cleanup() {
54         rm -f ${LOCK_DAILY}
55         rm -f ${LOCK_ACCEPTED}
56 }
57
58 # If we error out this one is called, *FOLLOWED* by cleanup above
59 function onerror() {
60     ERRDATE=$(date "+%Y.%m.%d-%H:%M:%S")
61
62     subject="ATTENTION ATTENTION!"
63     if [ "${error}" = "false" ]; then
64         subject="${subject} (continued)"
65     else
66         subject="${subject} (interrupted)"
67     fi
68     subject="${subject} dinstall error at ${ERRDATE} in ${STAGEFILE} - (Be quiet, Brain, or I'll stab you with a Q-tip)"
69
70     cat "${STAGEFILE}.log" | mail -s "${subject}" -a "X-Debian: DAK" cron@ftp-master.debian.org
71 }
72
73 ########################################################################
74 # the actual dinstall functions follow                                 #
75 ########################################################################
76
77 # pushing merkels QA user, part one
78 function merkel1() {
79     log "Telling merkels QA user that we start dinstall"
80     ssh -2 -i ~dak/.ssh/push_merkel_qa  -o BatchMode=yes -o SetupTimeOut=90 -o ConnectTimeout=90 qa@merkel.debian.org sleep 1
81 }
82
83 # Create the postgres dump files
84 function pgdump_pre() {
85     log "Creating pre-daily-cron-job backup of projectb database..."
86     pg_dump projectb > $base/backup/dump_pre_$(date +%Y.%m.%d-%H:%M:%S)
87 }
88
89 function pgdump_post() {
90     log "Creating post-daily-cron-job backup of projectb database..."
91     cd $base/backup
92     POSTDUMP=$(date +%Y.%m.%d-%H:%M:%S)
93     pg_dump projectb > $base/backup/dump_$POSTDUMP
94     pg_dumpall --globals-only > $base/backup/dumpall_$POSTDUMP
95     ln -sf $base/backup/dump_$POSTDUMP current
96     ln -sf $base/backup/dumpall_$POSTDUMP currentall
97 }
98
99 # Load the dak-dev projectb
100 function pgdakdev() {
101     cd $base/backup
102     echo "drop database projectb" | psql -p 5433 template1
103         cat currentall | psql -p 5433 template1
104     createdb -p 5433 -T template0 projectb
105     fgrep -v '\connect' current | psql -p 5433 projectb
106 }
107
108 # Updating various files
109 function updates() {
110     log "Updating Bugs docu, Mirror list and mailing-lists.txt"
111     cd $configdir
112     $scriptsdir/update-bugdoctxt
113     $scriptsdir/update-mirrorlists
114     $scriptsdir/update-mailingliststxt
115     $scriptsdir/update-pseudopackages.sh
116 }
117
118 # Process (oldstable)-proposed-updates "NEW" queue
119 function punew_do() {
120     cd "${queuedir}/${1}"
121     date -u -R >> REPORT
122     dak process-new -a -C COMMENTS >> REPORT || true
123     echo >> REPORT
124 }
125 function punew() {
126     log "Doing automated p-u-new processing"
127     punew_do "$1"
128 }
129 function opunew() {
130     log "Doing automated o-p-u-new processing"
131     punew_do "$1"
132 }
133
134 # The first i18n one, syncing new descriptions
135 function i18n1() {
136     log "Synchronizing i18n package descriptions"
137     # First sync their newest data
138     cd ${scriptdir}/i18nsync
139     rsync -aq --delete --delete-after ddtp-sync:/does/not/matter . || true
140
141     # Now check if we still know about the packages for which they created the files
142     # is the timestamp signed by us?
143     if $(gpgv --keyring /srv/ftp.debian.org/s3kr1t/dot-gnupg/pubring.gpg timestamp.gpg timestamp); then
144         # now read it. As its signed by us we are sure the content is what we expect, no need
145         # to do more here. And we only test -d a directory on it anyway.
146         TSTAMP=$(cat timestamp)
147         # do we have the dir still?
148         if [ -d ${scriptdir}/i18n/${TSTAMP} ]; then
149             # Lets check!
150             if ${scriptsdir}/ddtp-i18n-check.sh . ${scriptdir}/i18n/${TSTAMP}; then
151                 # Yay, worked, lets copy around
152                 for dir in squeeze sid; do
153                     if [ -d dists/${dir}/ ]; then
154                         cd dists/${dir}/main/i18n
155                         rsync -aq --delete --delete-after  . ${ftpdir}/dists/${dir}/main/i18n/.
156                     fi
157                     cd ${scriptdir}/i18nsync
158                 done
159             else
160                 echo "ARRRR, bad guys, wrong files, ARRR"
161                 echo "Arf, Arf, Arf, bad guys, wrong files, arf, arf, arf" | mail -s "Don't you kids take anything. I'm watching you. I've got eye implants in the back of my head." debian-l10n-devel@lists.alioth.debian.org
162             fi
163         else
164             echo "ARRRR, missing the timestamp ${TSTAMP} directory, not updating i18n, ARRR"
165             echo "Arf, Arf, Arf, missing the timestamp ${TSTAMP} directory, not updating i18n, arf, arf, arf" | mail -s "Lisa, if you don't like your job you don't strike. You just go in every day and do it really half-assed. That's the American way." debian-l10n-devel@lists.alioth.debian.org
166         fi
167     else
168         echo "ARRRRRRR, could not verify our timestamp signature, ARRR. Don't mess with our files, i18n guys, ARRRRR."
169         echo "Arf, Arf, Arf, could not verify our timestamp signature, arf. Don't mess with our files, i18n guys, arf, arf, arf" | mail -s "You can't keep blaming yourself. Just blame yourself once, and move on." debian-l10n-devel@lists.alioth.debian.org
170     fi
171 }
172
173 # Process the accepted queue
174 function accepted() {
175     log "Processing queue/accepted"
176     rm -f "$accepted/REPORT"
177     dak process-accepted -pa -d "$accepted" > "$accepted/REPORT"
178     cat "$accepted/REPORT" | mail -s "Install for $(date +"%D - %R")" ftpmaster@ftp-master.debian.org
179     chgrp debadmin "$accepted/REPORT"
180     chmod 664 "$accepted/REPORT"
181 }
182
183 function cruft() {
184     log "Checking for cruft in overrides"
185     dak check-overrides
186 }
187
188 function msfl() {
189     log "Generating suite file lists for apt-ftparchive"
190     dak make-suite-file-list
191 }
192
193 function fingerprints() {
194     log "Updating fingerprints"
195     dak import-keyring -L /srv/keyring.debian.org/keyrings/debian-keyring.gpg
196
197     OUTFILE=$(mktemp)
198     dak import-keyring --generate-users "%s" /srv/keyring.debian.org/keyrings/debian-maintainers.gpg >"${OUTFILE}"
199
200     if [ -s "${OUTFILE}" ]; then
201         /usr/sbin/sendmail -odq -oi -t -f envelope@ftp-master.debian.org <<EOF
202 From: Debian FTP Masters <ftpmaster@ftp-master.debian.org>
203 To: <debian-project@lists.debian.org>
204 Subject: Debian Maintainers Keyring changes
205 Content-Type: text/plain; charset=utf-8
206 MIME-Version: 1.0
207
208 The following changes to the debian-maintainers keyring have just been activated:
209
210 $(cat $OUTFILE)
211
212 Debian distribution maintenance software,
213 on behalf of the Keyring maintainers
214
215 EOF
216     fi
217     rm -f "$OUTFILE"
218 }
219
220 function overrides() {
221     log "Writing overrides into text files"
222     cd $overridedir
223     dak make-overrides
224
225     # FIXME
226     rm -f override.sid.all3
227     for i in main contrib non-free main.debian-installer; do cat override.sid.$i >> override.sid.all3; done
228 }
229
230 function mpfm() {
231     log "Generating package / file mapping"
232     dak make-pkg-file-mapping | bzip2 -9 > $base/ftp/indices/package-file.map.bz2
233 }
234
235 function packages() {
236     log "Generating Packages and Sources files"
237     cd $configdir
238     GZIP='--rsyncable' ; export GZIP
239     apt-ftparchive generate apt.conf
240 }
241
242 function pdiff() {
243     log "Generating pdiff files"
244     dak generate-index-diffs
245 }
246
247 function release() {
248     log "Generating Release files"
249     dak generate-releases
250 }
251
252 function dakcleanup() {
253     log "Cleanup old packages/files"
254     dak clean-suites -m 10000
255     dak clean-queues
256 }
257
258 function buildd() {
259     # Needs to be rebuilt, as files have moved.  Due to unaccepts, we need to
260     # update this before wanna-build is updated.
261     log "Regenerating wanna-build/buildd information"
262     psql projectb -A -t -q -c "SELECT filename FROM queue_build WHERE suite = 5 AND queue = 0 AND in_queue = true AND filename ~ 'd(sc|eb)$'" > $dbdir/dists/unstable_accepted.list
263     symlinks -d /srv/incoming.debian.org/buildd > /dev/null
264     apt-ftparchive generate apt.conf.buildd
265 }
266
267 function buildd_dir() {
268     # Rebuilt the buildd dir to avoid long times of 403
269     log "Regenerating the buildd incoming dir"
270     STAMP=$(date "+%Y%m%d%H%M")
271     make_buildd_dir
272 }
273
274 function mklslar() {
275     cd $ftpdir
276
277     FILENAME=ls-lR
278
279     log "Removing any core files ..."
280     find -type f -name core -print0 | xargs -0r rm -v
281
282     log "Checking permissions on files in the FTP tree ..."
283     find -type f \( \! -perm -444 -o -perm +002 \) -ls
284     find -type d \( \! -perm -555 -o -perm +002 \) -ls
285
286     log "Checking symlinks ..."
287     symlinks -rd .
288
289     log "Creating recursive directory listing ... "
290     rm -f .${FILENAME}.new
291     TZ=UTC ls -lR > .${FILENAME}.new
292
293     if [ -r ${FILENAME}.gz ] ; then
294         mv -f ${FILENAME}.gz ${FILENAME}.old.gz
295         mv -f .${FILENAME}.new ${FILENAME}
296         rm -f ${FILENAME}.patch.gz
297         zcat ${FILENAME}.old.gz | diff -u - ${FILENAME} | gzip --rsyncable -9cfn - >${FILENAME}.patch.gz
298         rm -f ${FILENAME}.old.gz
299     else
300         mv -f .${FILENAME}.new ${FILENAME}
301     fi
302
303     gzip --rsyncable -9cfN ${FILENAME} >${FILENAME}.gz
304     rm -f ${FILENAME}
305 }
306
307 function mkmaintainers() {
308     log -n 'Creating Maintainers index ... '
309
310     cd $indices
311     dak make-maintainers ${scriptdir}/masterfiles/pseudo-packages.maintainers | \
312         sed -e "s/~[^  ]*\([   ]\)/\1/"  | awk '{printf "%-20s ", $1; for (i=2; i<=NF; i++) printf "%s ", $i; printf "\n";}' > .new-maintainers
313
314     set +e
315     cmp .new-maintainers Maintainers >/dev/null
316     rc=$?
317     set -e
318     if [ $rc = 1 ] || [ ! -f Maintainers ] ; then
319             log -n "installing Maintainers ... "
320             mv -f .new-maintainers Maintainers
321             gzip --rsyncable -9v <Maintainers >.new-maintainers.gz
322             mv -f .new-maintainers.gz Maintainers.gz
323     elif [ $rc = 0 ] ; then
324             log '(same as before)'
325             rm -f .new-maintainers
326     else
327             log cmp returned $rc
328             false
329     fi
330 }
331
332 function copyoverrides() {
333     log 'Copying override files into public view ...'
334
335     for f in $copyoverrides ; do
336             cd $overridedir
337             chmod g+w override.$f
338
339             cd $indices
340             rm -f .newover-$f.gz
341             pc="`gzip 2>&1 -9nv <$overridedir/override.$f >.newover-$f.gz`"
342             set +e
343             nf=override.$f.gz
344             cmp -s .newover-$f.gz $nf
345             rc=$?
346             set -e
347         if [ $rc = 0 ]; then
348                     rm -f .newover-$f.gz
349             elif [ $rc = 1 -o ! -f $nf ]; then
350                     echo "   installing new $nf $pc"
351                     mv -f .newover-$f.gz $nf
352                     chmod g+w $nf
353             else
354                     echo $? $pc
355                     exit 1
356             fi
357     done
358 }
359
360 function mkfilesindices() {
361     umask 002
362     cd $base/ftp/indices/files/components
363
364     ARCHLIST=$(tempfile)
365
366     echo "Querying projectb..."
367     echo 'SELECT l.path, f.filename, a.arch_string FROM location l JOIN files f ON (f.location = l.id) LEFT OUTER JOIN (binaries b JOIN architecture a ON (b.architecture = a.id)) ON (f.id = b.file)' | psql projectb -At | sed 's/|//;s,^/srv/ftp.debian.org/ftp,.,' | sort >$ARCHLIST
368
369     includedirs () {
370         perl -ne 'print; while (m,/[^/]+$,) { $_=$`; print $_ . "\n" unless $d{$_}++; }'
371     }
372     poolfirst () {
373         perl -e '@nonpool=(); while (<>) { if (m,^\./pool/,) { print; } else { push @nonpool, $_; } } print for (@nonpool);'
374     }
375
376     echo "Generating sources list..."
377     (
378         sed -n 's/|$//p' $ARCHLIST
379         cd $base/ftp
380         find ./dists -maxdepth 1 \! -type d
381         find ./dists \! -type d | grep "/source/"
382     ) | sort -u | gzip --rsyncable -9 > source.list.gz
383
384     echo "Generating arch lists..."
385
386     ARCHES=$( (<$ARCHLIST sed -n 's/^.*|//p'; echo amd64) | grep . | grep -v all | sort -u)
387     for a in $ARCHES; do
388         (sed -n "s/|$a$//p" $ARCHLIST
389             sed -n 's/|all$//p' $ARCHLIST
390
391             cd $base/ftp
392             find ./dists -maxdepth 1 \! -type d
393             find ./dists \! -type d | grep -E "(proposed-updates.*_$a.changes$|/main/disks-$a/|/main/installer-$a/|/Contents-$a|/binary-$a/)"
394         ) | sort -u | gzip --rsyncable -9 > arch-$a.list.gz
395     done
396
397     echo "Generating suite lists..."
398
399     suite_list () {
400         printf 'SELECT DISTINCT l.path, f.filename FROM (SELECT sa.source AS source FROM src_associations sa WHERE sa.suite = %d UNION SELECT b.source AS source FROM bin_associations ba JOIN binaries b ON (ba.bin = b.id) WHERE ba.suite = %d) s JOIN dsc_files df ON (s.source = df.source) JOIN files f ON (df.file = f.id) JOIN location l ON (f.location = l.id)\n' $1 $1 | psql -F' ' -A -t projectb
401
402         printf 'SELECT l.path, f.filename FROM bin_associations ba JOIN binaries b ON (ba.bin = b.id) JOIN files f ON (b.file = f.id) JOIN location l ON (f.location = l.id) WHERE ba.suite = %d\n' $1 | psql -F' ' -A -t projectb
403     }
404
405     printf 'SELECT id, suite_name FROM suite\n' | psql -F' ' -At projectb |
406     while read id suite; do
407         [ -e $base/ftp/dists/$suite ] || continue
408         (
409             (cd $base/ftp
410                 distname=$(cd dists; readlink $suite || echo $suite)
411                 find ./dists/$distname \! -type d
412                 for distdir in ./dists/*; do
413                     [ "$(readlink $distdir)" != "$distname" ] || echo $distdir
414                 done
415             )
416             suite_list $id | tr -d ' ' | sed 's,^/srv/ftp.debian.org/ftp,.,'
417         ) | sort -u | gzip --rsyncable -9 > suite-${suite}.list.gz
418     done
419
420     echo "Finding everything on the ftp site to generate sundries $(date +"%X")..."
421
422     (cd $base/ftp; find . \! -type d \! -name 'Archive_Maintenance_In_Progress' | sort) >$ARCHLIST
423
424     rm -f sundries.list
425     zcat *.list.gz | cat - *.list | sort -u |
426     diff - $ARCHLIST | sed -n 's/^> //p' > sundries.list
427
428     echo "Generating files list $(date +"%X")..."
429
430     for a in $ARCHES; do
431         (echo ./project/trace; zcat arch-$a.list.gz source.list.gz) |
432         cat - sundries.list dists.list project.list docs.list indices.list |
433         sort -u | poolfirst > ../arch-$a.files
434     done
435
436     (cd $base/ftp/
437             for dist in sid squeeze; do
438                     find ./dists/$dist/main/i18n/ \! -type d | sort -u | gzip --rsyncable -9 > $base/ftp/indices/files/components/translation-$dist.list.gz
439             done
440     )
441
442     (cat ../arch-i386.files ../arch-amd64.files; zcat suite-oldstable.list.gz suite-proposed-updates.list.gz ; zcat translation-sid.list.gz ; zcat translation-squeeze.list.gz) |
443     sort -u | poolfirst > ../typical.files
444
445     rm -f $ARCHLIST
446     echo "Done!"
447 }
448
449 function mkchecksums() {
450     dsynclist=$dbdir/dsync.list
451     md5list=$indices/md5sums
452
453     log -n "Creating md5 / dsync index file ... "
454
455     cd "$ftpdir"
456     ${bindir}/dsync-flist -q generate $dsynclist --exclude $dsynclist --md5
457     ${bindir}/dsync-flist -q md5sums $dsynclist | gzip -9n --rsyncable > ${md5list}.gz
458     ${bindir}/dsync-flist -q link-dups $dsynclist || true
459 }
460
461 function scripts() {
462     log "Running various scripts from $scriptsdir"
463     cd $scriptsdir
464     mkmaintainers
465     copyoverrides
466     mklslar
467     mkfilesindices
468     mkchecksums
469 }
470
471 function mirror() {
472     echo "Regenerating \"public\" mirror/ hardlink fun"
473     cd ${mirrordir}
474     rsync -aH --link-dest ${ftpdir} --delete --delete-after --ignore-errors ${ftpdir}/. .
475 }
476
477 function wb() {
478     log "Trigger daily wanna-build run"
479     ssh -o BatchMode=yes -o SetupTimeOut=90 -o ConnectTimeout=90 wbadm@buildd /org/wanna-build/trigger.daily || echo "W-B trigger.daily failed" | mail -s "W-B Daily trigger failed" ftpmaster@ftp-master.debian.org
480 }
481
482 function expire() {
483     log "Expiring old database dumps..."
484     cd $base/backup
485     $scriptsdir/expire_dumps -d . -p -f "dump_*"
486 }
487
488 function transitionsclean() {
489     log "Removing out of date transitions..."
490     cd $base
491     dak transitions -c -a
492 }
493
494 function reports() {
495     # Send a report on NEW/BYHAND packages
496     log "Nagging ftpteam about NEW/BYHAND packages"
497     dak queue-report | mail -e -s "NEW and BYHAND on $(date +%D)" ftpmaster@ftp-master.debian.org
498     # and one on crufty packages
499     log "Sending information about crufty packages"
500     dak cruft-report > $webdir/cruft-report-daily.txt
501     dak cruft-report -s experimental >> $webdir/cruft-report-daily.txt
502     cat $webdir/cruft-report-daily.txt | mail -e -s "Debian archive cruft report for $(date +%D)" ftpmaster@ftp-master.debian.org
503 }
504
505 function dm() {
506     log "Updating DM html page"
507     $scriptsdir/dm-monitor >$webdir/dm-uploaders.html
508 }
509
510 function bts() {
511     log "Categorizing uncategorized bugs filed against ftp.debian.org"
512     dak bts-categorize
513 }
514
515 function merkel2() {
516     # Push dak@merkel so it syncs the projectb there. Returns immediately, the sync runs detached
517     log "Trigger merkel/flotows projectb sync"
518     ssh -2 -o BatchMode=yes -o SetupTimeOut=30 -o ConnectTimeout=30 -i ~/.ssh/push_merkel_projectb dak@merkel.debian.org sleep 1
519     # Also trigger flotow, the ftpmaster test box
520     ssh -2 -o BatchMode=yes -o SetupTimeOut=30 -o ConnectTimeout=30 -i ~/.ssh/push_flotow_projectb dak@flotow.debconf.org sleep 1
521 }
522
523 function merkel3() {
524     # Push dak@merkel to tell it to sync the dd accessible parts. Returns immediately, the sync runs detached
525     log "Trigger merkels dd accessible parts sync"
526     ssh -2 -o BatchMode=yes -o SetupTimeOut=30 -o ConnectTimeout=30 -i ~/.ssh/push_merkel_ddaccess dak@merkel.debian.org sleep 1
527 }
528
529 function mirrorpush() {
530     log "Starting the mirrorpush"
531     date -u > /srv/ftp.debian.org/web/mirrorstart
532     echo "Using dak v1" >> /srv/ftp.debian.org/web/mirrorstart
533     echo "Running on host $(hostname -f)" >> /srv/ftp.debian.org/web/mirrorstart
534     sudo -H -u archvsync /home/archvsync/runmirrors > ~dak/runmirrors.log 2>&1 &
535 }
536
537 function i18n2() {
538     log "Exporting package data foo for i18n project"
539     STAMP=$(date "+%Y%m%d%H%M")
540     mkdir -p ${scriptdir}/i18n/${STAMP}
541     cd ${scriptdir}/i18n/${STAMP}
542     dak control-suite -l stable > lenny
543     dak control-suite -l testing > squeeze
544     dak control-suite -l unstable > sid
545     echo "${STAMP}" > timestamp
546     gpg --secret-keyring /srv/ftp.debian.org/s3kr1t/dot-gnupg/secring.gpg --keyring /srv/ftp.debian.org/s3kr1t/dot-gnupg/pubring.gpg --no-options --batch --no-tty --armour --default-key 55BE302B --detach-sign -o timestamp.gpg timestamp
547     rm -f md5sum
548     md5sum * > md5sum
549     cd ${webdir}/
550     ln -sfT ${scriptdir}/i18n/${STAMP} i18n
551
552     cd ${scriptdir}
553     find ./i18n -mindepth 1 -maxdepth 1 -mtime +2 -not -name "${STAMP}" -type d -print0 | xargs --no-run-if-empty -0 rm -rf
554 }
555
556 function stats() {
557     log "Updating stats data"
558     cd $configdir
559     $scriptsdir/update-ftpstats $base/log/* > $base/misc/ftpstats.data
560     R --slave --vanilla < $base/misc/ftpstats.R
561     dak stats arch-space > $webdir/arch-space
562     dak stats pkg-nums > $webdir/pkg-nums
563 }
564
565 function aptftpcleanup() {
566     log "Clean up apt-ftparchive's databases"
567     cd $configdir
568     apt-ftparchive -q clean apt.conf
569 }
570
571 function compress() {
572     log "Compress old psql backups"
573     cd $base/backup/
574     find -maxdepth 1 -mindepth 1 -type f -name 'dump_pre_*' -mtime +2 -print0 | xargs -0 --no-run-if-empty rm
575
576     find -maxdepth 1 -mindepth 1 -type f -name 'dump_*' \! -name '*.bz2' \! -name '*.gz' -mmin +720 |
577     while read dumpname; do
578         echo "Compressing $dumpname"
579         bzip2 -9fv "$dumpname"
580     done
581     find -maxdepth 1 -mindepth 1 -type f -name "dumpall_*" \! -name '*.bz2' \! -name '*.gz' -mmin +720 |
582     while read dumpname; do
583         echo "Compressing $dumpname"
584         bzip2 -9fv "$dumpname"
585     done
586     finddup -l -d $base/backup
587 }
588
589 function logstats() {
590     $masterdir/tools/logs.py "$1"
591 }
592
593 # save timestamp when we start
594 function savetimestamp() {
595         NOW=`date "+%Y.%m.%d-%H:%M:%S"`
596         echo ${NOW} > "${dbdir}/dinstallstart"
597 }
598
599 function maillogfile() {
600     cat "$LOGFILE" | mail -s "Log for dinstall run of ${NOW}" cron@ftp-master.debian.org
601 }
602
603 function renamelogfile() {
604     if [ -f "${dbdir}/dinstallstart" ]; then
605         NOW=$(cat "${dbdir}/dinstallstart")
606 #        maillogfile
607         mv "$LOGFILE" "$logdir/dinstall_${NOW}.log"
608         logstats "$logdir/dinstall_${NOW}.log"
609         bzip2 -9 "$logdir/dinstall_${NOW}.log"
610     else
611         error "Problem, I don't know when dinstall started, unable to do log statistics."
612         NOW=`date "+%Y.%m.%d-%H:%M:%S"`
613 #        maillogfile
614         mv "$LOGFILE" "$logdir/dinstall_${NOW}.log"
615         bzip2 -9 "$logdir/dinstall_${NOW}.log"
616     fi
617 }
618
619 function testingsourcelist() {
620     dak ls -s testing -f heidi -r .| egrep 'source$' > ${webdir}/testing.list
621 }
622
623 # do a last run of process-unchecked before dinstall is on.
624 function process_unchecked() {
625     log "Processing the unchecked queue"
626     acceptnew
627     UNCHECKED_WITHOUT_LOCK="-p"
628     do_unchecked
629     sync_debbugs
630 }
631
632 ########################################################################
633 ########################################################################
634
635 # Function to save which stage we are in, so we can restart an interrupted
636 # dinstall. Or even run actions in parallel, if we dare to, by simply
637 # backgrounding the call to this function. But that should only really be
638 # done for things we don't care much about.
639 #
640 # This should be called with the first argument being an array, with the
641 # members
642 #  - FUNC - the function name to call
643 #  - ARGS - Possible arguments to hand to the function. Can be the empty string
644 #  - TIME - The timestamp name. Can be the empty string
645 #  - ERR  - if this is the string false, then the call will be surrounded by
646 #           set +e ... set -e calls, so errors in the function do not exit
647 #           dinstall. Can be the empty string, meaning true.
648 #
649 # MAKE SURE TO KEEP THIS THE LAST FUNCTION, AFTER ALL THE VARIOUS ONES
650 # ADDED FOR DINSTALL FEATURES!
651 function stage() {
652     ARGS='GO[@]'
653     local "${!ARGS}"
654
655     error=${ERR:-"true"}
656
657     STAGEFILE="${stagedir}/${FUNC}"
658     if [ -f "${STAGEFILE}" ]; then
659         stamptime=$(/usr/bin/stat -c %Z "${STAGEFILE}")
660         unixtime=$(date +%s)
661         difference=$(( $unixtime - $stamptime ))
662         if [ ${difference} -ge 14400 ]; then
663             log_error "Did already run ${FUNC}, stagefile exists, but that was ${difference} seconds ago. Please check."
664         else
665             log "Did already run ${FUNC}, not calling again..."
666         fi
667         return
668     fi
669
670     debug "Now calling function ${FUNC}. Arguments: ${ARGS}. Timestamp: ${TIME}"
671
672     # Make sure we are always at the same place. If a function wants to be elsewhere,
673     # it has to cd first!
674     cd ${configdir}
675
676     # Now redirect the output into $STAGEFILE.log. In case it errors out somewhere our
677     # errorhandler trap can then mail the contents of $STAGEFILE.log only, instead of a whole
678     # dinstall logfile. Short error mails ftw!
679     exec >> "${STAGEFILE}.log" 2>&1
680
681     if [ -f "${LOCK_STOP}" ]; then
682         log "${LOCK_STOP} exists, exiting immediately"
683         exit 42
684     fi
685
686     if [ "${error}" = "false" ]; then
687         set +e
688     fi
689     ${FUNC} ${ARGS}
690
691     # No matter what happened in the function, we make sure we have set -e default state back
692     set -e
693
694     # Make sure we are always at the same place.
695     cd ${configdir}
696
697     # We always use the same umask. If a function wants to do different, fine, but we reset.
698     umask 022
699
700     touch "${STAGEFILE}"
701
702     if [ -n "${TIME}" ]; then
703         ts "${TIME}"
704     fi
705
706     # And the output goes back to the normal logfile
707     exec >> "$LOGFILE" 2>&1
708
709     # Now we should make sure that we have a usable dinstall.log, so append the $STAGEFILE.log
710     # to it.
711     cat "${STAGEFILE}.log" >> "${LOGFILE}"
712     rm -f "${STAGEFILE}.log"
713
714     if [ -f "${LOCK_STOP}" ]; then
715         log "${LOCK_STOP} exists, exiting immediately"
716         exit 42
717     fi
718 }
719
720 ########################################################################
721
722 # We need logs.
723 LOGFILE="$logdir/dinstall.log"
724
725 exec >> "$LOGFILE" 2>&1
726
727 # usually we are not using debug logs. Set to 1 if you want them.
728 DEBUG=0
729
730 # our name
731 PROGRAM="dinstall"
732
733 # where do we want mails to go? For example log entries made with error()
734 if [ "x$(hostname -s)x" != "xriesx" ]; then
735     # Not our ftpmaster host
736     MAILTO=${MAILTO:-"root"}
737 else
738     # Yay, ftpmaster
739     MAILTO=${MAILTO:-"ftpmaster@debian.org"}
740 fi
741
742 # Make sure we start out with a sane umask setting
743 umask 022
744
745 # And use one locale, no matter what the caller has set
746 export LANG=C
747 export LC_ALL=C
748
749 # How many logfiles to keep
750 LOGROTATE=${LOGROTATE:-400}
751
752 # Marker for dinstall start
753 DINSTALLSTART="${lockdir}/dinstallstart"
754 # Marker for dinstall end
755 DINSTALLEND="${lockdir}/dinstallend"
756
757 touch "${DINSTALLSTART}"
758 ts "startup"
759
760 # lock cron.unchecked (it immediately exits when this exists)
761 LOCK_DAILY="$lockdir/daily.lock"
762
763 # Lock cron.unchecked from doing work
764 LOCK_ACCEPTED="$lockdir/unchecked.lock"
765
766 # Lock process-new from doing work
767 LOCK_NEW="$lockdir/processnew.lock"
768
769 # This file is simply used to indicate to britney whether or not
770 # the Packages file updates completed sucessfully.  It's not a lock
771 # from our point of view
772 LOCK_BRITNEY="$lockdir/britney.lock"
773
774 # If this file exists we exit immediately after the currently running
775 # function is done
776 LOCK_STOP="$lockdir/archive.stop"
777
778 lockfile -l 3600 "${LOCK_DAILY}"
779 trap onerror ERR
780 trap cleanup EXIT TERM HUP INT QUIT
781
782 touch "${LOCK_BRITNEY}"
783
784 GO=(
785     FUNC="savetimestamp"
786     TIME=""
787     ARGS=""
788     ERR="false"
789 )
790 stage $GO
791
792 GO=(
793     FUNC="notice"
794     TIME=""
795     ARGS=""
796     ERR="false"
797 )
798 stage $GO
799
800 GO=(
801     FUNC="merkel1"
802     TIME="init"
803     ARGS=""
804     ERR="false"
805 )
806 stage $GO &
807
808 GO=(
809     FUNC="pgdump_pre"
810     TIME="pg_dump1"
811     ARGS=""
812     ERR=""
813 )
814 stage $GO
815
816 GO=(
817     FUNC="updates"
818     TIME="External Updates"
819     ARGS=""
820     ERR="false"
821 )
822 stage $GO &
823
824 GO=(
825     FUNC="punew"
826     TIME="p-u-new"
827     ARGS="p-u-new"
828     ERR=""
829 )
830 stage $GO
831
832 GO=(
833     FUNC="opunew"
834     TIME="o-p-u-new"
835     ARGS="o-p-u-new"
836     ERR=""
837 )
838 stage $GO
839
840 GO=(
841     FUNC="i18n1"
842     TIME="i18n 1"
843     ARGS=""
844     ERR="false"
845 )
846 stage $GO &
847
848 lockfile "$LOCK_ACCEPTED"
849 lockfile "$LOCK_NEW"
850
851 GO=(
852     FUNC="process_unchecked"
853     TIME=""
854     ARGS=""
855     ERR=""
856 )
857 stage $GO
858
859
860 GO=(
861     FUNC="accepted"
862     TIME="accepted"
863     ARGS=""
864     ERR=""
865 )
866 stage $GO
867
868 GO=(
869     FUNC="buildd_dir"
870     TIME="buildd_dir"
871     ARGS=""
872     ERR="false"
873 )
874 stage $GO
875
876 GO=(
877     FUNC="cruft"
878     TIME="cruft"
879     ARGS=""
880     ERR=""
881 )
882 stage $GO
883
884 rm -f "$LOCK_ACCEPTED"
885 rm -f "$LOCK_NEW"
886
887 GO=(
888     FUNC="msfl"
889     TIME="make-suite-file-list"
890     ARGS=""
891     ERR=""
892 )
893 stage $GO
894
895 GO=(
896     FUNC="fingerprints"
897     TIME="import-keyring"
898     ARGS=""
899     ERR="false"
900 )
901 stage $GO &
902
903 GO=(
904     FUNC="overrides"
905     TIME="overrides"
906     ARGS=""
907     ERR=""
908 )
909 stage $GO
910
911 GO=(
912     FUNC="mpfm"
913     TIME="pkg-file-mapping"
914     ARGS=""
915     ERR="false"
916 )
917 stage $GO
918
919 GO=(
920     FUNC="packages"
921     TIME="apt-ftparchive"
922     ARGS=""
923     ERR=""
924 )
925 stage $GO
926
927 GO=(
928     FUNC="pdiff"
929     TIME="pdiff"
930     ARGS=""
931     ERR=""
932 )
933 stage $GO
934
935 GO=(
936     FUNC="release"
937     TIME="release files"
938     ARGS=""
939     ERR=""
940 )
941 stage $GO
942
943 GO=(
944     FUNC="dakcleanup"
945     TIME="cleanup"
946     ARGS=""
947     ERR=""
948 )
949 stage $GO
950
951 GO=(
952     FUNC="buildd"
953     TIME="buildd"
954     ARGS=""
955     ERR=""
956 )
957 stage $GO
958
959 GO=(
960     FUNC="scripts"
961     TIME="scripts"
962     ARGS=""
963     ERR=""
964 )
965 stage $GO
966
967 GO=(
968     FUNC="mirror"
969     TIME="mirror hardlinks"
970     ARGS=""
971     ERR=""
972 )
973 stage $GO
974
975 GO=(
976     FUNC="wb"
977     TIME="w-b"
978     ARGS=""
979     ERR=""
980 )
981 stage $GO &
982
983 rm -f "${LOCK_DAILY}"
984
985 ts "locked part finished"
986
987 GO=(
988     FUNC="pgdump_post"
989     TIME="pg_dump2"
990     ARGS=""
991     ERR=""
992 )
993 stage $GO &
994
995 GO=(
996     FUNC="expire"
997     TIME="expire_dumps"
998     ARGS=""
999     ERR=""
1000 )
1001 stage $GO &
1002
1003 GO=(
1004     FUNC="transitionsclean"
1005     TIME="transitionsclean"
1006     ARGS=""
1007     ERR=""
1008 )
1009 stage $GO &
1010
1011 GO=(
1012     FUNC="reports"
1013     TIME="reports"
1014     ARGS=""
1015     ERR=""
1016 )
1017 stage $GO &
1018
1019 GO=(
1020     FUNC="dm"
1021     TIME=""
1022     ARGS=""
1023     ERR=""
1024 )
1025 stage $GO &
1026
1027 GO=(
1028     FUNC="bts"
1029     TIME=""
1030     ARGS=""
1031     ERR="false"
1032 )
1033 stage $GO &
1034
1035 GO=(
1036     FUNC="merkel2"
1037     TIME="merkel projectb push"
1038     ARGS=""
1039     ERR="false"
1040 )
1041 stage $GO &
1042
1043 GO=(
1044     FUNC="mirrorpush"
1045     TIME="mirrorpush"
1046     ARGS=""
1047     ERR="false"
1048 )
1049 stage $GO
1050
1051 GO=(
1052     FUNC="i18n2"
1053     TIME="i18n 2"
1054     ARGS=""
1055     ERR="false"
1056 )
1057 stage $GO
1058
1059 GO=(
1060     FUNC="stats"
1061     TIME="stats"
1062     ARGS=""
1063     ERR="false"
1064 )
1065 stage $GO &
1066
1067 GO=(
1068     FUNC="testingsourcelist"
1069     TIME=""
1070     ARGS=""
1071     ERR="false"
1072 )
1073 stage $GO
1074
1075 rm -f ${LOCK_BRITNEY}
1076
1077 GO=(
1078     FUNC="pgdakdev"
1079     TIME="dak-dev db"
1080     ARGS=""
1081     ERR="false"
1082 )
1083 stage $GO &
1084
1085 GO=(
1086     FUNC="merkel3"
1087     TIME="merkel ddaccessible sync"
1088     ARGS=""
1089     ERR="false"
1090 )
1091 stage $GO &
1092
1093 GO=(
1094     FUNC="compress"
1095     TIME="compress"
1096     ARGS=""
1097     ERR=""
1098 )
1099 stage $GO &
1100
1101 GO=(
1102     FUNC="aptftpcleanup"
1103     TIME="apt-ftparchive cleanup"
1104     ARGS=""
1105     ERR="false"
1106 )
1107 stage $GO
1108
1109 log "Daily cron scripts successful, all done"
1110
1111 exec > "$logdir/afterdinstall.log" 2>&1
1112
1113 GO=(
1114     FUNC="renamelogfile"
1115     TIME=""
1116     ARGS=""
1117     ERR="false"
1118 )
1119 stage $GO
1120
1121
1122 # Now, at the very (successful) end of dinstall, make sure we remove
1123 # our stage files, so the next dinstall run will do it all again.
1124 rm -f ${stagedir}/*
1125 touch "${DINSTALLEND}"