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 ########################################################################
31 # log something (basically echo it together with a timestamp)
33 # Set $PROGRAM to a string to have it added to the output.
35 if [ -z "${PROGRAM}" ]; then
36 echo "$(date +"%b %d %H:%M:%S") $(hostname -s) [$$] $@"
38 echo "$(date +"%b %d %H:%M:%S") $(hostname -s) ${PROGRAM}[$$]: $@"
42 # log the message using log() but then also send a mail
43 # to the address configured in MAILTO (if non-empty)
44 function log_error () {
46 if [ -z "${MAILTO}" ]; then
47 echo "$@" | mail -e -s "[$PROGRAM@$(hostname -s)] ERROR [$$]" ${MAILTO}
51 # debug log, only output when DEBUG=1
53 if [ $DEBUG -eq 1 ]; then
58 # Timestamp. Used for dinstall stat graphs
61 echo "Archive maintenance timestamp $TS ($1): $(date +%H:%M:%S)"
67 rm -f ${LOCK_ACCEPTED}
70 # Setup the notice file to tell bad mirrors they used the wrong time
74 Packages are currently being installed and indices rebuilt.
75 Maintenance is automatic, starting at 01|07|13|19:52 UTC,
76 and ending about an hour later. This file is then removed.
78 You should not mirror the archive during this period.
82 # pushing merkels QA user, part one
84 log "Telling merkels QA user that we start dinstall"
85 ssh -2 -i ~dak/.ssh/push_merkel_qa -o BatchMode=yes -o SetupTimeOut=90 -o ConnectTimeout=90 qa@merkel.debian.org sleep 1
88 # Create the postgres dump files
89 function pgdump_pre() {
90 log "Creating pre-daily-cron-job backup of projectb database..."
91 pg_dump projectb > $base/backup/dump_$(date +%Y.%m.%d-%H:%M:%S)
94 function pgdump_post() {
95 log "Creating post-daily-cron-job backup of projectb database..."
97 POSTDUMP=$base/backup/dump_$(date +%Y.%m.%d-%H:%M:%S)
98 pg_dump projectb > $POSTDUMP
99 ln -sf $POSTDUMP current
102 # Updating various files
104 log "Updating Bugs docu, Mirror list and mailing-lists.txt"
106 $scriptsdir/update-bugdoctxt
107 $scriptsdir/update-mirrorlists
108 $scriptsdir/update-mailingliststxt
109 $scriptsdir/update-pseudopackages.sh
112 # Process (oldstable)-proposed-updates "NEW" queue
113 function punew_do() {
114 cd "${queuedir}/${1}"
116 dak process-new -a -C COMMENTS >> REPORT || true
120 log "Doing automated p-u-new processing"
124 log "Doing automated o-p-u-new processing"
128 # The first i18n one, syncing new descriptions
130 log "Synchronizing i18n package descriptions"
131 # First sync their newest data
132 cd ${scriptdir}/i18nsync
133 rsync -aq --delete --delete-after ddtp-sync:/does/not/matter . || true
135 # Now check if we still know about the packages for which they created the files
136 # is the timestamp signed by us?
137 if $(gpgv --keyring /srv/ftp.debian.org/s3kr1t/dot-gnupg/pubring.gpg timestamp.gpg timestamp); then
138 # now read it. As its signed by us we are sure the content is what we expect, no need
139 # to do more here. And we only test -d a directory on it anyway.
140 TSTAMP=$(cat timestamp)
141 # do we have the dir still?
142 if [ -d ${scriptdir}/i18n/${TSTAMP} ]; then
144 if ${scriptsdir}/ddtp-i18n-check.sh . ${scriptdir}/i18n/${TSTAMP}; then
145 # Yay, worked, lets copy around
146 for dir in squeeze sid; do
147 if [ -d dists/${dir}/ ]; then
148 cd dists/${dir}/main/i18n
149 rsync -aq --delete --delete-after . ${ftpdir}/dists/${dir}/main/i18n/.
151 cd ${scriptdir}/i18nsync
154 echo "ARRRR, bad guys, wrong files, ARRR"
155 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
158 echo "ARRRR, missing the timestamp ${TSTAMP} directory, not updating i18n, ARRR"
159 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
162 echo "ARRRRRRR, could not verify our timestamp signature, ARRR. Don't mess with our files, i18n guys, ARRRRR."
163 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
167 # Process the accepted queue
168 function accepted() {
169 log "Processing queue/accepted"
172 dak process-accepted -pa -d /srv/ftp.debian.org/queue/accepted > REPORT
173 cat REPORT | mail -s "Install for $(date +"%D - %R")" ftpmaster@ftp-master.debian.org
174 chgrp debadmin REPORT
179 log "Checking for cruft in overrides"
182 log "Fixing symlinks in $ftpdir"
183 symlinks -d -r $ftpdir
187 log "Generating suite file lists for apt-ftparchive"
188 dak make-suite-file-list
191 function fingerprints() {
192 log "Updating fingerprints"
193 dak import-keyring -L /srv/keyring.debian.org/keyrings/debian-keyring.gpg
196 function overrides() {
197 log "Writing overrides into text files"
202 rm -f override.sid.all3
203 for i in main contrib non-free main.debian-installer; do cat override.sid.$i >> override.sid.all3; done
207 log "Generating package / file mapping"
208 dak make-pkg-file-mapping | bzip2 -9 > $base/ftp/indices/package-file.map.bz2
211 function packages() {
212 log "Generating Packages and Sources files"
214 apt-ftparchive generate apt.conf
218 log "Generating pdiff files"
219 dak generate-index-diffs
223 log "Generating Release files"
224 dak generate-releases
227 function dakcleanup() {
228 log "Cleanup old packages/files"
234 # Needs to be rebuilt, as files have moved. Due to unaccepts, we need to
235 # update this before wanna-build is updated.
236 log "Regenerating wanna-build/buildd information"
237 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
238 symlinks -d /srv/incoming.debian.org/buildd > /dev/null
239 apt-ftparchive generate apt.conf.buildd
243 log "Running various scripts from $scriptsdir"
253 echo "Regenerating \"public\" mirror/ hardlink fun"
255 rsync -aH --link-dest ${ftpdir} --delete --delete-after --ignore-errors ${ftpdir}/. .
259 log "Trigger daily wanna-build run"
260 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
264 log "Expiring old database dumps..."
266 $scriptsdir/expire_dumps -d . -p -f "dump_*"
270 # Send a report on NEW/BYHAND packages
271 log "Nagging ftpteam about NEW/BYHAND packages"
272 dak queue-report | mail -e -s "NEW and BYHAND on $(date +%D)" ftpmaster@ftp-master.debian.org
273 # and one on crufty packages
274 log "Sending information about crufty packages"
275 dak cruft-report > $webdir/cruft-report-daily.txt
276 dak cruft-report -s experimental >> $webdir/cruft-report-daily.txt
277 cat $webdir/cruft-report-daily.txt | mail -e -s "Debian archive cruft report for $(date +%D)" ftpmaster@ftp-master.debian.org
281 log "Updating DM html page"
282 $scriptsdir/dm-monitor >$webdir/dm-uploaders.html
286 log "Categorizing uncategorized bugs filed against ftp.debian.org"
291 # Push katie@merkel so it syncs the projectb there. Returns immediately, the sync runs detached
292 log "Trigger merkels projectb sync"
293 ssh -2 -o BatchMode=yes -o SetupTimeOut=30 -o ConnectTimeout=30 -i ~/.ssh/push_merkel_projectb katie@merkel.debian.org sleep 1
296 function runparts() {
297 log "Using run-parts to run scripts in $base/scripts/distmnt"
298 run-parts --report $base/scripts/distmnt
302 log "Exporting package data foo for i18n project"
303 STAMP=$(date "+%Y%m%d%H%M")
304 mkdir -p ${scriptdir}/i18n/${STAMP}
305 cd ${scriptdir}/i18n/${STAMP}
306 dak control-suite -l stable > lenny
307 dak control-suite -l testing > squeeze
308 dak control-suite -l unstable > sid
309 echo "${STAMP}" > timestamp
310 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
314 ln -sfT ${scriptdir}/i18n/${STAMP} i18n
317 find ./i18n -mtime +2 -mindepth 1 -maxdepth 1 -not -name "${STAMP}" -type d -print0 | xargs --no-run-if-empty -0 rm -rf
321 log "Updating stats data"
323 $scriptsdir/update-ftpstats $base/log/* > $base/misc/ftpstats.data
324 R --slave --vanilla < $base/misc/ftpstats.R
327 function aptftpcleanup() {
328 log "Clean up apt-ftparchive's databases"
330 apt-ftparchive -q clean apt.conf
333 function compress() {
334 log "Compress old psql backups"
336 find -maxdepth 1 -mindepth 1 -type f -name 'dump_*' \! -name '*.bz2' \! -name '*.gz' -mtime +1 |
337 while read dumpname; do
338 echo "Compressing $dumpname"
339 bzip2 -9v "$dumpname"
343 function logstats() {
344 $masterdir/tools/logs.py "$LOGFILE"
347 ########################################################################
348 ########################################################################
350 # Function to save which stage we are in, so we can restart an interrupted
351 # dinstall. Or even run actions in parallel, if we dare to, by simply
352 # backgrounding the call to this function. But that should only really be
353 # done for things we dont care much about.
355 # This should be called with the first argument being an array, with the
357 # - FUNC - the function name to call
358 # - ARGS - Possible arguments to hand to the function. Can be the empty string
359 # - TS - The timestamp name. Can be the empty string
360 # - ERR - if this is the string false, then the call will be surrounded by
361 # set +e ... set -e calls, so errors in the function do not exit
362 # dinstall. Can be the empty string, meaning true.
364 # MAKE SURE TO KEEP THIS THE LAST FUNCTION, AFTER ALL THE VARIOUS ONES
365 # ADDED FOR DINSTALL FEATURES!
370 if [ -f "${stagedir}/${FUNC}" ]; then
371 stamptime=$(/usr/bin/stat -c %Z "${stagedir}/${FUNC}")
373 difference=$(( $unixtime - $stamptime ))
374 if [ ${difference} -ge 14400 ]; then
375 log_error "Did already run ${FUNC}, stagefile exists, but that was ${difference} seconds ago. Please check."
377 log "Did already run ${FUNC}, not calling again..."
382 debug "Now calling function ${FUNC}. Arguments: ${ARGS}. Timestamp: ${TS}"
384 # Make sure we are always at the same place. If a function wants to be elsewhere,
385 # it has to cd first!
388 if [ "${ERR}" = "false" ]; then
393 # No matter what happened in the function, we make sure we have set -e default state back
396 # Make sure we are always at the same place.
399 touch "${stagedir}/${FUNC}"
401 if [ -n "${TIME}" ]; then
406 ########################################################################
409 LOGFILE="$logdir/dinstall.log"
411 exec >> "$LOGFILE" 2>&1
413 # usually we are not using debug logs. Set to 1 if you want them.
419 # where do we want mails to go? For example log entries made with error()
420 if [ "x$(hostname -s)x" != "xriesx" ]; then
421 # Not our ftpmaster host
422 MAILTO=${MAILTO:-"root"}
425 MAILTO=${MAILTO:-"ftpmaster@debian.org"}
428 # How many logfiles to keep
429 LOGROTATE=${LOGROTATE:-400}
431 # Timestamps start at -1. so first gets 0
435 # Tell everyone we are doing some work
436 NOTICE="$ftpdir/Archive_Maintenance_In_Progress"
438 # lock cron.unchecked (it immediately exits when this exists)
439 LOCK_DAILY="$lockdir/daily.lock"
441 # Lock process-new and cron.unchecked from doing work
442 LOCK_ACCEPTED="$lockdir/unchecked.lock"
444 # This file is simply used to indicate to britney whether or not
445 # the Packages file updates completed sucessfully. It's not a lock
446 # from our point of view
447 LOCK_BRITNEY="$lockdir/britney.lock"
449 lockfile -l 3600 "${LOCK_DAILY}"
450 trap cleanup EXIT ERR TERM HUP INT QUIT
452 touch "${LOCK_BRITNEY}"
480 TIME="External Updates"
510 lockfile "$LOCK_ACCEPTED"
528 rm -f "$LOCK_ACCEPTED"
532 TIME="make-suite-file-list"
540 TIME="import-keyring"
556 TIME="pkg-file-mapping"
564 TIME="apt-ftparchive"
612 TIME="mirror hardlinks"
627 rm -f "${LOCK_DAILY}"
629 ts "locked part finished"
673 TIME="merkel projectb push"
679 ulimit -m 90000 -d 90000 -s 10000 -v 200000
709 TIME="apt-ftparchive cleanup"
723 log "Daily cron scripts successful, all done"
725 exec > /dev/null 2>&1
735 cat "$LOGFILE" | mail -s "Log for dinstall run of ${NOW}" cron@ftp-master.debian.org
737 savelog -c ${LOGROTATE} -j "$LOGFILE"
739 # Now, at the very (successful) end of dinstall, make sure we remove
740 # our stage files, so the next dinstall run will do it all again.
741 rm -f "${stagedir}/*"