2 # No way I try to deal with a crippled sh just for POSIX foo.
4 # Copyright (C) 2009 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.
21 # make sure to only use defined variables
24 # import the general variable set.
25 export SCRIPTVARS=/srv/ftp.debian.org/dak/config/debian/vars
28 ########################################################################
30 ########################################################################
34 count=${2:-${LOGROTATE}}
35 while [ ${count} -gt 0 ]; do
37 if [ -e "${torotate}.${prev}" ]; then
38 mv "${torotate}.${prev}" "${torotate}.${count}"
42 mv "${torotate}" "${torotate}.0"
45 # log something (basically echo it together with a timestamp)
47 # Set $PROGRAM to a string to have it added to the output.
49 if [ -z "${PROGRAM}" ]; then
50 echo "$(date +"%b %d %H:%M:%S") $(hostname -s) [$$] $@"
52 echo "$(date +"%b %d %H:%M:%S") $(hostname -s) ${PROGRAM}[$$]: $@"
56 # log the message using log() but then also send a mail
57 # to the address configured in MAILTO (if non-empty)
60 if [ -z "${MAILTO}" ]; then
61 echo "$@" | mail -e -s "[$PROGRAM@$(hostname -s)] ERROR [$$]" ${MAILTO}
65 # debug log, only output when DEBUG=1
67 if [ $DEBUG -eq 1 ]; then
72 # Timestamp. Used for dinstall stat graphs
75 echo "Archive maintenance timestamp $TS ($1): $(date +%H:%M:%S)"
83 # Setup the notice file to tell bad mirrors they used the wrong time
87 Packages are currently being installed and indices rebuilt.
88 Maintenance is automatic, starting at 01|07|13|19:52 UTC,
89 and ending about an hour later. This file is then removed.
91 You should not mirror the archive during this period.
95 # ushing merkels QA user, part one
97 log "Telling merkels QA user that we start dinstall"
98 ssh -2 -i ~dak/.ssh/push_merkel_qa -o BatchMode=yes -o SetupTimeOut=90 -o ConnectTimeout=90 qa@merkel.debian.org sleep 1
101 # Create the postgres dump files
102 function pgdump_pre() {
103 log "Creating pre-daily-cron-job backup of projectb database..."
104 pg_dump projectb > $base/backup/dump_$(date +%Y.%m.%d-%H:%M:%S)
107 function pgdump_post() {
108 log "Creating post-daily-cron-job backup of projectb database..."
110 POSTDUMP=$base/backup/dump_$(date +%Y.%m.%d-%H:%M:%S)
111 pg_dump projectb > $POSTDUMP
112 ln -sf $POSTDUMP current
115 # Updating various files
117 log "Updating Bugs docu, Mirror list and mailing-lists.txt"
119 $scriptsdir/update-bugdoctxt
120 $scriptsdir/update-mirrorlists
121 $scriptsdir/update-mailingliststxt
122 $scriptsdir/update-pseudopackages.sh
125 # Process (oldstable)-proposed-updates "NEW" queue
126 function punew_do() {
127 cd "${queuedir}/${1}"
129 dak process-new -a -C COMMENTS >> REPORT || true
133 log "Doing automated p-u-new processing"
137 log "Doing automated o-p-u-new processing"
141 # The first i18n one, syncing new descriptions
143 log "Synchronizing i18n package descriptions"
144 # First sync their newest data
145 cd ${scriptdir}/i18nsync
146 rsync -aq --delete --delete-after ddtp-sync:/does/not/matter . || true
148 # Now check if we still know about the packages for which they created the files
149 # is the timestamp signed by us?
150 if $(gpgv --keyring /srv/ftp.debian.org/s3kr1t/dot-gnupg/pubring.gpg timestamp.gpg timestamp); then
151 # now read it. As its signed by us we are sure the content is what we expect, no need
152 # to do more here. And we only test -d a directory on it anyway.
153 TSTAMP=$(cat timestamp)
154 # do we have the dir still?
155 if [ -d ${scriptdir}/i18n/${TSTAMP} ]; then
157 if ${scriptsdir}/ddtp-i18n-check.sh . ${scriptdir}/i18n/${TSTAMP}; then
158 # Yay, worked, lets copy around
159 for dir in squeeze sid; do
160 if [ -d dists/${dir}/ ]; then
161 cd dists/${dir}/main/i18n
162 rsync -aq --delete --delete-after . ${ftpdir}/dists/${dir}/main/i18n/.
164 cd ${scriptdir}/i18nsync
167 echo "ARRRR, bad guys, wrong files, ARRR"
168 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
171 echo "ARRRR, missing the timestamp ${TSTAMP} directory, not updating i18n, ARRR"
172 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
175 echo "ARRRRRRR, could not verify our timestamp signature, ARRR. Don't mess with our files, i18n guys, ARRRRR."
176 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
180 # Process the accepted queue
181 function accepted() {
182 log "Processing queue/accepted"
185 dak process-accepted -pa *.changes | tee REPORT | \
186 mail -s "Install for $(date +"%D - %R")" ftpmaster@ftp-master.debian.org
187 chgrp debadmin REPORT
192 log "Checking for cruft in overrides"
195 log "Fixing symlinks in $ftpdir"
196 symlinks -d -r $ftpdir
200 log "Generating suite file lists for apt-ftparchive"
201 dak make-suite-file-list
204 function fingerprints() {
205 log "Updating fingerprints"
206 dak import-keyring -L /srv/keyring.debian.org/keyrings/debian-keyring.gpg
209 function overrides() {
210 log "Writing overrides into text files"
215 rm -f override.sid.all3
216 for i in main contrib non-free main.debian-installer; do cat override.sid.$i >> override.sid.all3; done
220 log "Generating package / file mapping"
221 dak make-pkg-file-mapping | bzip2 -9 > $base/ftp/indices/package-file.map.bz2
224 function packages() {
225 log "Generating Packages and Sources files"
227 apt-ftparchive generate apt.conf
231 log "Generating pdiff files"
232 dak generate-index-diffs
236 log "Generating Release files"
237 dak generate-releases
241 log "Cleanup old packages/files"
247 # Needs to be rebuilt, as files have moved. Due to unaccepts, we need to
248 # update this before wanna-build is updated.
249 log "Regenerating wanna-build/buildd information"
250 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
251 symlinks -d /srv/incoming.debian.org/buildd > /dev/null
252 apt-ftparchive generate apt.conf.buildd
256 log "Running various scripts from $scriptsdir"
266 echo "Regenerating \"public\" mirror/ hardlink fun"
268 rsync -aH --link-dest ${ftpdir} --delete --delete-after --ignore-errors ${ftpdir}/. .
272 log "Trigger daily wanna-build run"
273 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
277 log "Expiring old database dumps..."
279 $scriptsdir/expire_dumps -d . -p -f "dump_*"
283 # Send a report on NEW/BYHAND packages
284 log "Nagging ftpteam about NEW/BYHAND packages"
285 dak queue-report | mail -e -s "NEW and BYHAND on $(date +%D)" ftpmaster@ftp-master.debian.org
286 # and one on crufty packages
287 log "Sending information about crufty packages"
288 dak cruft-report > $webdir/cruft-report-daily.txt
289 dak cruft-report -s experimental >> $webdir/cruft-report-daily.txt
290 cat $webdir/cruft-report-daily.txt | mail -e -s "Debian archive cruft report for $(date +%D)" ftpmaster@ftp-master.debian.org
294 log "Updating DM html page"
295 $scriptsdir/dm-monitor >$webdir/dm-uploaders.html
299 log "Categorizing uncategorized bugs filed against ftp.debian.org"
304 # Push katie@merkel so it syncs the projectb there. Returns immediately, the sync runs detached
305 log "Trigger merkels projectb sync"
306 ssh -2 -o BatchMode=yes -o SetupTimeOut=30 -o ConnectTimeout=30 -i ~/.ssh/push_merkel_projectb katie@merkel.debian.org sleep 1
309 function runparts() {
310 log "Using run-parts to run scripts in $base/scripts/distmnt"
311 run-parts --report $base/scripts/distmnt
315 log "Exporting package data foo for i18n project"
316 STAMP=$(date "+%Y%m%d%H%M")
317 mkdir -p ${scriptdir}/i18n/${STAMP}
318 cd ${scriptdir}/i18n/${STAMP}
319 dak control-suite -l stable > lenny
320 dak control-suite -l testing > squeeze
321 dak control-suite -l unstable > sid
322 echo "${STAMP}" > timestamp
323 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 6070D3A1 --detach-sign -o timestamp.gpg timestamp
327 ln -sfT ${scriptdir}/i18n/${STAMP} i18n
330 find ./i18n -mtime +2 -mindepth 1 -maxdepth 1 -not -name "${STAMP}" -type d -print0 | xargs --no-run-if-empty -0 rm -rf
334 log "Updating stats data"
336 $scriptsdir/update-ftpstats $base/log/* > $base/misc/ftpstats.data
337 R --slave --vanilla < $base/misc/ftpstats.R
340 function aptftpcleanup() {
341 log "Clean up apt-ftparchive's databases"
343 apt-ftparchive -q clean apt.conf
346 function compress() {
347 log "Compress old psql backups"
349 find -maxdepth 1 -mindepth 1 -type f -name 'dump_*' \! -name '*.bz2' \! -name '*.gz' -mtime +1 |
350 while read dumpname; do
351 echo "Compressing $dumpname"
352 bzip2 -9v "$dumpname"
356 function logstats() {
357 $masterdir/tools/logs.py "$LOGFILE"
360 ########################################################################
361 ########################################################################
363 # Function to save which stage we are in, so we can restart an interrupted
364 # dinstall. Or even run actions in parallel, if we dare to, by simply
365 # backgrounding the call to this function. But that should only really be
366 # done for things we dont care much about.
368 # This should be called with the first argument being an array, with the
370 # - FUNC - the function name to call
371 # - ARGS - Possible arguments to hand to the function. Can be the empty string
372 # - TS - The timestamp name. Can be the empty string
373 # - ERR - if this is the string false, then the call will be surrounded by
374 # set +e ... set -e calls, so errors in the function do not exit
375 # dinstall. Can be the empty string, meaning true.
377 # MAKE SURE TO KEEP THIS THE LAST FUNCTION, AFTER ALL THE VARIOUS ONES
378 # ADDED FOR DINSTALL FEATURES!
383 if [ -f "${stagedir}/${FUNC}" ]; then
384 stamptime=$(/usr/bin/stat -c %Z "${stagedir}/${FUNC}")
386 difference=$(( $unixtime - $stamptime ))
387 if [ ${difference} -ge 14400 ]; then
388 error "Did already run ${FUNC}, stagefile exists, but that was ${difference} seconds ago. Please check."
390 log "Did already run ${FUNC}, not calling again..."
395 debug "Now calling function ${FUNC}. Arguments: ${ARGS}. Timestamp: ${TS}"
397 # Make sure we are always at the same place. If a function wants to be elsewhere,
398 # it has to cd first!
401 if [ "${ERR}" = "false"]; then
406 # No matter what happened in the function, we make sure we have set -e default state back
409 # Make sure we are always at the same place.
412 touch "${stagedir}/${FUNC}"
414 if [ -n "${TIME}" ]; then
419 ########################################################################
422 LOGFILE="$logdir/dinstall.log"
424 exec > "$LOGFILE" 2>&1
426 # usually we are not using debug logs. Set to 1 if you want them.
432 # where do we want mails to go? For example log entries made with error()
433 if [ "x$(hostname -s)x" != "xriesx" ]; then
434 # Not our ftpmaster host
435 MAILTO=${MAILTO:-"root"}
438 MAILTO=${MAILTO:-"ftpmaster@debian.org"}
441 # How many logfiles to keep
442 LOGROTATE=${LOGROTATE:-400}
444 # Timestamps start at -1. so first gets 0
448 # Tell everyone we are doing some work
449 NOTICE="$ftpdir/Archive_Maintenance_In_Progress"
451 # lock cron.unchecked (it immediately exits when this exists)
452 LOCK_DAILY="$lockdir/daily.lock"
454 # Lock process-new and cron.unchecked from doing work
455 LOCK_ACCEPTED="$lockdir/unchecked.lock"
457 # This file is simply used to indicate to britney whether or not
458 # the Packages file updates completed sucessfully. It's not a lock
459 # from our point of view
460 LOCK_BRITNEY="$lockdir/britney.lock"
462 lockfile -l 3600 "${LOCK_DAILY}"
463 trap cleanup EXIT ERR TERM HUP INT QUIT
465 touch "${LOCK_BRITNEY}"
493 TIME="External Updates"
523 lockfile "$LOCK_ACCEPTED"
545 TIME="make-suite-file-list"
553 TIME="import-keyring"
569 TIME="pkg-file-mapping"
577 TIME="apt-ftparchive"
625 TIME="mirror hardlinks"
640 rm -f "${LOCK_DAILY}"
642 ts "locked part finished"
686 TIME="merkel projectb push"
692 ulimit -m 90000 -d 90000 -s 10000 -v 200000
722 TIME="apt-ftparchive cleanup"
736 log "Daily cron scripts successful, all done"
738 exec > /dev/null 2>&1
748 cat "$LOGFILE" | mail -s "Log for dinstall run of ${NOW}" cron@ftp-master.debian.org
750 # Now, at the very (successful) end of dinstall, make sure we remove
751 # our stage files, so the next dinstall run will do it all again.
752 rm -f "${stagedir}/*"