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"
170 rm -f "$accepted/REPORT"
171 dak process-accepted -pa -d "$accepted" > "$accepted/REPORT"
172 cat "$accepted/REPORT" | mail -s "Install for $(date +"%D - %R")" ftpmaster@ftp-master.debian.org
173 chgrp debadmin "$accepted/REPORT"
174 chmod 664 "$accepted/REPORT"
178 log "Checking for cruft in overrides"
181 log "Fixing symlinks in $ftpdir"
182 symlinks -d -r $ftpdir
186 log "Generating suite file lists for apt-ftparchive"
187 dak make-suite-file-list
190 function fingerprints() {
191 log "Updating fingerprints"
192 dak import-keyring -L /srv/keyring.debian.org/keyrings/debian-keyring.gpg
195 function overrides() {
196 log "Writing overrides into text files"
201 rm -f override.sid.all3
202 for i in main contrib non-free main.debian-installer; do cat override.sid.$i >> override.sid.all3; done
206 log "Generating package / file mapping"
207 dak make-pkg-file-mapping | bzip2 -9 > $base/ftp/indices/package-file.map.bz2
210 function packages() {
211 log "Generating Packages and Sources files"
213 apt-ftparchive generate apt.conf
217 log "Generating pdiff files"
218 dak generate-index-diffs
222 log "Generating Release files"
223 dak generate-releases
226 function dakcleanup() {
227 log "Cleanup old packages/files"
233 # Needs to be rebuilt, as files have moved. Due to unaccepts, we need to
234 # update this before wanna-build is updated.
235 log "Regenerating wanna-build/buildd information"
236 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
237 symlinks -d /srv/incoming.debian.org/buildd > /dev/null
238 apt-ftparchive generate apt.conf.buildd
242 log "Running various scripts from $scriptsdir"
252 echo "Regenerating \"public\" mirror/ hardlink fun"
254 rsync -aH --link-dest ${ftpdir} --delete --delete-after --ignore-errors ${ftpdir}/. .
258 log "Trigger daily wanna-build run"
259 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
263 log "Expiring old database dumps..."
265 $scriptsdir/expire_dumps -d . -p -f "dump_*"
269 # Send a report on NEW/BYHAND packages
270 log "Nagging ftpteam about NEW/BYHAND packages"
271 dak queue-report | mail -e -s "NEW and BYHAND on $(date +%D)" ftpmaster@ftp-master.debian.org
272 # and one on crufty packages
273 log "Sending information about crufty packages"
274 dak cruft-report > $webdir/cruft-report-daily.txt
275 dak cruft-report -s experimental >> $webdir/cruft-report-daily.txt
276 cat $webdir/cruft-report-daily.txt | mail -e -s "Debian archive cruft report for $(date +%D)" ftpmaster@ftp-master.debian.org
280 log "Updating DM html page"
281 $scriptsdir/dm-monitor >$webdir/dm-uploaders.html
285 log "Categorizing uncategorized bugs filed against ftp.debian.org"
290 # Push katie@merkel so it syncs the projectb there. Returns immediately, the sync runs detached
291 log "Trigger merkels projectb sync"
292 ssh -2 -o BatchMode=yes -o SetupTimeOut=30 -o ConnectTimeout=30 -i ~/.ssh/push_merkel_projectb katie@merkel.debian.org sleep 1
295 function runparts() {
296 log "Using run-parts to run scripts in $base/scripts/distmnt"
297 run-parts --report $base/scripts/distmnt
301 log "Exporting package data foo for i18n project"
302 STAMP=$(date "+%Y%m%d%H%M")
303 mkdir -p ${scriptdir}/i18n/${STAMP}
304 cd ${scriptdir}/i18n/${STAMP}
305 dak control-suite -l stable > lenny
306 dak control-suite -l testing > squeeze
307 dak control-suite -l unstable > sid
308 echo "${STAMP}" > timestamp
309 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
313 ln -sfT ${scriptdir}/i18n/${STAMP} i18n
316 find ./i18n -mindepth 1 -maxdepth 1 -mtime +2 -not -name "${STAMP}" -type d -print0 | xargs --no-run-if-empty -0 rm -rf
320 log "Updating stats data"
322 $scriptsdir/update-ftpstats $base/log/* > $base/misc/ftpstats.data
323 R --slave --vanilla < $base/misc/ftpstats.R
326 function aptftpcleanup() {
327 log "Clean up apt-ftparchive's databases"
329 apt-ftparchive -q clean apt.conf
332 function compress() {
333 log "Compress old psql backups"
335 find -maxdepth 1 -mindepth 1 -type f -name 'dump_*' \! -name '*.bz2' \! -name '*.gz' -mtime +1 |
336 while read dumpname; do
337 echo "Compressing $dumpname"
338 bzip2 -9v "$dumpname"
342 function logstats() {
343 $masterdir/tools/logs.py "$LOGFILE"
346 ########################################################################
347 ########################################################################
349 # Function to save which stage we are in, so we can restart an interrupted
350 # dinstall. Or even run actions in parallel, if we dare to, by simply
351 # backgrounding the call to this function. But that should only really be
352 # done for things we dont care much about.
354 # This should be called with the first argument being an array, with the
356 # - FUNC - the function name to call
357 # - ARGS - Possible arguments to hand to the function. Can be the empty string
358 # - TS - The timestamp name. Can be the empty string
359 # - ERR - if this is the string false, then the call will be surrounded by
360 # set +e ... set -e calls, so errors in the function do not exit
361 # dinstall. Can be the empty string, meaning true.
363 # MAKE SURE TO KEEP THIS THE LAST FUNCTION, AFTER ALL THE VARIOUS ONES
364 # ADDED FOR DINSTALL FEATURES!
369 if [ -f "${stagedir}/${FUNC}" ]; then
370 stamptime=$(/usr/bin/stat -c %Z "${stagedir}/${FUNC}")
372 difference=$(( $unixtime - $stamptime ))
373 if [ ${difference} -ge 14400 ]; then
374 log_error "Did already run ${FUNC}, stagefile exists, but that was ${difference} seconds ago. Please check."
376 log "Did already run ${FUNC}, not calling again..."
381 debug "Now calling function ${FUNC}. Arguments: ${ARGS}. Timestamp: ${TS}"
383 # Make sure we are always at the same place. If a function wants to be elsewhere,
384 # it has to cd first!
387 if [ -f "${LOCK_STOP}" ]; then
388 log "${LOCK_STOP} exists, exiting immediately"
392 if [ "${ERR}" = "false" ]; then
397 # No matter what happened in the function, we make sure we have set -e default state back
400 # Make sure we are always at the same place.
403 touch "${stagedir}/${FUNC}"
405 if [ -f "${LOCK_STOP}" ]; then
406 log "${LOCK_STOP} exists, exiting immediately"
410 if [ -n "${TIME}" ]; then
415 ########################################################################
418 LOGFILE="$logdir/dinstall.log"
420 exec >> "$LOGFILE" 2>&1
422 # usually we are not using debug logs. Set to 1 if you want them.
428 # where do we want mails to go? For example log entries made with error()
429 if [ "x$(hostname -s)x" != "xriesx" ]; then
430 # Not our ftpmaster host
431 MAILTO=${MAILTO:-"root"}
434 MAILTO=${MAILTO:-"ftpmaster@debian.org"}
437 # How many logfiles to keep
438 LOGROTATE=${LOGROTATE:-400}
440 # Timestamps start at -1. so first gets 0
444 # Tell everyone we are doing some work
445 NOTICE="$ftpdir/Archive_Maintenance_In_Progress"
447 # lock cron.unchecked (it immediately exits when this exists)
448 LOCK_DAILY="$lockdir/daily.lock"
450 # Lock process-new and cron.unchecked from doing work
451 LOCK_ACCEPTED="$lockdir/unchecked.lock"
453 # This file is simply used to indicate to britney whether or not
454 # the Packages file updates completed sucessfully. It's not a lock
455 # from our point of view
456 LOCK_BRITNEY="$lockdir/britney.lock"
458 # If this file exists we exit immediately after the currently running
460 LOCK_STOP="$lockdir/archive.stop"
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"
541 rm -f "$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
718 rm -f ${LOCK_BRITNEY}
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 savelog -c ${LOGROTATE} -j "$LOGFILE"
752 # Now, at the very (successful) end of dinstall, make sure we remove
753 # our stage files, so the next dinstall run will do it all again.
754 rm -f "${stagedir}/*"