2 # Timestamp. Used for dinstall stat graphs
4 echo "Archive maintenance timestamp ($1): $(date +%H:%M:%S)"
8 function remove_daily_lock() {
13 function remove_all_locks() {
14 rm -f $LOCK_DAILY $LOCK_ACCEPTED $LOCK_NEW
17 # If we error out this one is called, *FOLLOWED* by cleanup above
19 ERRDATE=$(date "+%Y.%m.%d-%H:%M:%S")
21 subject="ATTENTION ATTENTION!"
22 if [ "${error}" = "false" ]; then
23 subject="${subject} (continued)"
25 subject="${subject} (interrupted)"
27 subject="${subject} dinstall error at ${ERRDATE} in ${STAGEFILE} - (Be quiet, Brain, or I'll stab you with a Q-tip)"
29 if [ -r "${STAGEFILE}.log" ]; then
30 cat "${STAGEFILE}.log"
32 echo "file ${STAGEFILE}.log does not exist, sorry"
33 fi | mail -s "${subject}" -a "X-Debian: DAK" cron@ftp-master.debian.org -- -F "Debian FTP Masters" -f ftpmaster@ftp-master.debian.org
36 ########################################################################
37 # the actual dinstall functions follow #
38 ########################################################################
40 # pushing merkels QA user, part one
42 log "Telling merkels QA user that we start dinstall"
43 ssh -2 -i ~dak/.ssh/push_merkel_qa -o BatchMode=yes -o SetupTimeOut=90 -o ConnectTimeout=90 qa@qa.debian.org sleep 1
46 # Create the postgres dump files
47 function pgdump_pre() {
48 log "Creating pre-daily-cron-job backup of $PGDATABASE database..."
49 pg_dump > $base/backup/dump_pre_$(date +%Y.%m.%d-%H:%M:%S)
52 function pgdump_post() {
53 log "Creating post-daily-cron-job backup of $PGDATABASE database..."
55 POSTDUMP=$(date +%Y.%m.%d-%H:%M:%S)
56 pg_dump > $base/backup/dump_$POSTDUMP
57 #pg_dumpall --globals-only > $base/backup/dumpall_$POSTDUMP
58 ln -sf $base/backup/dump_$POSTDUMP current
59 #ln -sf $base/backup/dumpall_$POSTDUMP currentall
62 # Load the dak-dev projectb
64 # Make sure to unset any possible psql variables so we don't drop the wrong
65 # f****** database by accident
75 echo "drop database projectb" | psql -p 5434 template1
76 #cat currentall | psql -p 5433 template1
77 createdb -p 5434 -T template1 projectb
78 fgrep -v '\connect' current | psql -p 5434 projectb
81 # Updating various files
83 log "Updating Bugs docu, Mirror list and mailing-lists.txt"
85 $scriptsdir/update-bugdoctxt
86 $scriptsdir/update-mirrorlists
87 $scriptsdir/update-mailingliststxt
88 $scriptsdir/update-pseudopackages.sh
91 # Process (oldstable)-proposed-updates "NEW" queue
94 dak process-policy $1 | tee -a REPORT | mail -a "X-Debian: DAK" -e -s "NEW changes in $1" debian-release@lists.debian.org -- -F "Debian FTP Masters" -f ftpmaster@ftp-master.debian.org
98 log "Doing automated p-u-new processing"
99 cd "${queuedir}/p-u-new"
103 log "Doing automated o-p-u-new processing"
104 cd "${queuedir}/o-p-u-new"
108 # The first i18n one, syncing new descriptions
110 log "Synchronizing i18n package descriptions"
111 # First sync their newest data
112 cd ${scriptdir}/i18nsync
113 rsync -aq --delete --delete-after ddtp-sync:/does/not/matter . || true
115 # Now check if we still know about the packages for which they created the files
116 # is the timestamp signed by us?
117 if $(gpgv --keyring /srv/ftp-master.debian.org/s3kr1t/dot-gnupg/pubring.gpg timestamp.gpg timestamp); then
118 # now read it. As its signed by us we are sure the content is what we expect, no need
119 # to do more here. And we only test -d a directory on it anyway.
120 TSTAMP=$(cat timestamp)
121 # do we have the dir still?
122 if [ -d ${scriptdir}/i18n/${TSTAMP} ]; then
124 if ${scriptsdir}/ddtp-i18n-check.sh . ${scriptdir}/i18n/${TSTAMP}; then
125 # Yay, worked, lets copy around
126 for dir in wheezy sid; do
127 if [ -d dists/${dir}/ ]; then
128 cd dists/${dir}/main/i18n
129 rsync -aq --delete --delete-after . ${ftpdir}/dists/${dir}/main/i18n/.
131 cd ${scriptdir}/i18nsync
134 echo "ARRRR, bad guys, wrong files, ARRR"
135 echo "Arf, Arf, Arf, bad guys, wrong files, arf, arf, arf" | mail -a "X-Debian: DAK" -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 -- -F "Debian FTP Masters" -f ftpmaster@ftp-master.debian.org
138 echo "ARRRR, missing the timestamp ${TSTAMP} directory, not updating i18n, ARRR"
139 echo "Arf, Arf, Arf, missing the timestamp ${TSTAMP} directory, not updating i18n, arf, arf, arf" | mail -a "X-Debian: DAK" -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 -- -F "Debian FTP Masters" -f ftpmaster@ftp-master.debian.org
142 echo "ARRRRRRR, could not verify our timestamp signature, ARRR. Don't mess with our files, i18n guys, ARRRRR."
143 echo "Arf, Arf, Arf, could not verify our timestamp signature, arf. Don't mess with our files, i18n guys, arf, arf, arf" | mail -a "X-Debian: DAK" -s "You can't keep blaming yourself. Just blame yourself once, and move on." debian-l10n-devel@lists.alioth.debian.org -- -F "Debian FTP Masters" -f ftpmaster@ftp-master.debian.org
148 log "Checking for cruft in overrides"
152 function dominate() {
153 log "Removing obsolete source and binary associations"
157 function filelist() {
158 log "Generating file lists for apt-ftparchive"
159 dak generate-filelist
162 function fingerprints() {
163 log "Not updating fingerprints - scripts needs checking"
165 log "Updating fingerprints"
166 dak import-keyring -L /srv/keyring.debian.org/keyrings/debian-keyring.gpg
169 dak import-keyring --generate-users "%s" /srv/keyring.debian.org/keyrings/debian-maintainers.gpg >"${OUTFILE}"
171 if [ -s "${OUTFILE}" ]; then
172 /usr/sbin/sendmail -odq -oi -t -f envelope@ftp-master.debian.org <<EOF
173 From: Debian FTP Masters <ftpmaster@ftp-master.debian.org>
174 To: <debian-project@lists.debian.org>
175 Subject: Debian Maintainers Keyring changes
176 Content-Type: text/plain; charset=utf-8
180 The following changes to the debian-maintainers keyring have just been activated:
184 Debian distribution maintenance software,
185 on behalf of the Keyring maintainers
192 function overrides() {
193 log "Writing overrides into text files"
198 rm -f override.sid.all3
199 for i in main contrib non-free main.debian-installer; do cat override.sid.$i >> override.sid.all3; done
203 log "Generating package / file mapping"
204 dak make-pkg-file-mapping | bzip2 -9 > $base/ftp/indices/package-file.map.bz2
207 function packages() {
208 log "Generating Packages and Sources files"
210 #apt-ftparchive generate apt.conf
211 dak generate-packages-sources
215 log "Generating pdiff files"
216 dak generate-index-diffs
220 log "Generating Release files"
221 dak generate-releases
224 function dakcleanup() {
225 log "Cleanup old packages/files"
226 dak clean-suites -m 10000
230 function buildd_dir() {
231 # Rebuilt the buildd dir to avoid long times of 403
232 log "Regenerating the buildd incoming dir"
233 STAMP=$(date "+%Y%m%d%H%M")
242 log "Removing any core files ..."
243 find -type f -name core -print0 | xargs -0r rm -v
245 log "Checking permissions on files in the FTP tree ..."
246 find -type f \( \! -perm -444 -o -perm +002 \) -ls
247 find -type d \( \! -perm -555 -o -perm +002 \) -ls
249 log "Checking symlinks ..."
252 log "Creating recursive directory listing ... "
253 rm -f .${FILENAME}.new
254 TZ=UTC ls -lR > .${FILENAME}.new
256 if [ -r ${FILENAME}.gz ] ; then
257 mv -f ${FILENAME}.gz ${FILENAME}.old.gz
258 mv -f .${FILENAME}.new ${FILENAME}
259 rm -f ${FILENAME}.patch.gz
260 zcat ${FILENAME}.old.gz | diff -u - ${FILENAME} | gzip -9cfn - >${FILENAME}.patch.gz
261 rm -f ${FILENAME}.old.gz
263 mv -f .${FILENAME}.new ${FILENAME}
266 gzip -9cfN ${FILENAME} >${FILENAME}.gz
270 function mkmaintainers() {
271 log 'Creating Maintainers index ... '
274 dak make-maintainers ${scriptdir}/masterfiles/pseudo-packages.maintainers | \
275 sed -e "s/~[^ ]*\([ ]\)/\1/" | \
276 awk '{printf "%-20s ", $1; for (i=2; i<=NF; i++) printf "%s ", $i; printf "\n";}' > .new-maintainers
278 if ! cmp -s .new-maintainers Maintainers || [ ! -f Maintainers ]; then
279 log "installing Maintainers ... "
280 mv -f .new-maintainers Maintainers
281 gzip -9v <Maintainers >.new-maintainers.gz
282 mv -f .new-maintainers.gz Maintainers.gz
284 rm -f .new-maintainers
288 function mkuploaders() {
289 log 'Creating Uploaders index ... '
292 dak make-maintainers -u ${scriptdir}/masterfiles/pseudo-packages.maintainers | \
293 sed -e "s/~[^ ]*\([ ]\)/\1/" | \
294 awk '{printf "%-20s ", $1; for (i=2; i<=NF; i++) printf "%s ", $i; printf "\n";}' > .new-uploaders
296 if ! cmp -s .new-uploaders Uploaders || [ ! -f Uploaders ]; then
297 log "installing Uploaders ... "
298 mv -f .new-uploaders Uploaders
299 gzip -9v <Uploaders >.new-uploaders.gz
300 mv -f .new-uploaders.gz Uploaders.gz
306 function copyoverrides() {
307 log 'Copying override files into public view ...'
309 for ofile in $copyoverrides ; do
311 chmod g+w override.$ofile
315 newofile=override.$ofile.gz
316 rm -f .newover-$ofile.gz
317 pc="`gzip 2>&1 -9nv <$overridedir/override.$ofile >.newover-$ofile.gz`"
318 if ! cmp -s .newover-$ofile.gz $newofile || [ ! -f $newofile ]; then
319 log " installing new $newofile $pc"
320 mv -f .newover-$ofile.gz $newofile
323 rm -f .newover-$ofile.gz
328 function mkfilesindices() {
330 cd $base/ftp/indices/files/components
334 log "Querying $PGDATABASE..."
335 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 -At | sed 's/|//;s,^/srv/ftp-master.debian.org/ftp,.,' | sort >$ARCHLIST
338 perl -ne 'print; while (m,/[^/]+$,) { $_=$`; print $_ . "\n" unless $d{$_}++; }'
341 perl -e '@nonpool=(); while (<>) { if (m,^\./pool/,) { print; } else { push @nonpool, $_; } } print for (@nonpool);'
344 log "Generating sources list"
346 sed -n 's/|$//p' $ARCHLIST
348 find ./dists -maxdepth 1 \! -type d
349 find ./dists \! -type d | grep "/source/"
350 ) | sort -u | gzip -9 > source.list.gz
352 log "Generating arch lists"
354 ARCHES=$( (<$ARCHLIST sed -n 's/^.*|//p'; echo amd64) | grep . | grep -v all | sort -u)
356 (sed -n "s/|$a$//p" $ARCHLIST
357 sed -n 's/|all$//p' $ARCHLIST
360 find ./dists -maxdepth 1 \! -type d
361 find ./dists \! -type d | grep -E "(proposed-updates.*_$a.changes$|/main/disks-$a/|/main/installer-$a/|/Contents-$a|/binary-$a/)"
362 ) | sort -u | gzip -9 > arch-$a.list.gz
365 log "Generating suite lists"
368 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
370 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
373 printf 'SELECT id, suite_name FROM suite\n' | psql -F' ' -At |
374 while read id suite; do
375 [ -e $base/ftp/dists/$suite ] || continue
378 distname=$(cd dists; readlink $suite || echo $suite)
379 find ./dists/$distname \! -type d
380 for distdir in ./dists/*; do
381 [ "$(readlink $distdir)" != "$distname" ] || echo $distdir
384 suite_list $id | tr -d ' ' | sed 's,^/srv/ftp-master.debian.org/ftp,.,'
385 ) | sort -u | gzip -9 > suite-${suite}.list.gz
388 log "Finding everything on the ftp site to generate sundries"
389 (cd $base/ftp; find . \! -type d \! -name 'Archive_Maintenance_In_Progress' | sort) >$ARCHLIST
392 zcat *.list.gz | cat - *.list | sort -u |
393 diff - $ARCHLIST | sed -n 's/^> //p' > sundries.list
395 log "Generating files list"
398 (echo ./project/trace; zcat arch-$a.list.gz source.list.gz) |
399 cat - sundries.list dists.list project.list docs.list indices.list |
400 sort -u | poolfirst > ../arch-$a.files
404 for dist in sid wheezy; do
405 find ./dists/$dist/main/i18n/ \! -type d | sort -u | gzip -9 > $base/ftp/indices/files/components/translation-$dist.list.gz
409 (cat ../arch-i386.files ../arch-amd64.files; zcat suite-proposed-updates.list.gz ; zcat translation-sid.list.gz ; zcat translation-wheezy.list.gz) |
410 sort -u | poolfirst > ../typical.files
416 function mkchecksums() {
417 dsynclist=$dbdir/dsync.list
418 md5list=$indices/md5sums
420 log -n "Creating md5 / dsync index file ... "
423 ${bindir}/dsync-flist -q generate $dsynclist --exclude $dsynclist --md5
424 ${bindir}/dsync-flist -q md5sums $dsynclist | gzip -9n > ${md5list}.gz
425 ${bindir}/dsync-flist -q link-dups $dsynclist || true
429 log "Regenerating \"public\" mirror/ hardlink fun"
430 DATE_SERIAL=$(date +"%Y%m%d01")
431 FILESOAPLUS1=$(awk '/serial/ { print $3+1 }' ${TRACEFILE} )
432 if [ "$DATE_SERIAL" -gt "$FILESOAPLUS1" ]; then
433 SERIAL="$DATE_SERIAL"
435 SERIAL="$FILESOAPLUS1"
437 date -u > ${TRACEFILE}
438 echo "Using dak v1" >> ${TRACEFILE}
439 echo "Running on host: $(hostname -f)" >> ${TRACEFILE}
440 echo "Archive serial: ${SERIAL}" >> ${TRACEFILE}
442 rsync -aH --link-dest ${ftpdir} --delete --delete-after --ignore-errors ${ftpdir}/. .
446 log "Expiring old database dumps..."
448 $scriptsdir/expire_dumps -d . -p -f "dump_*"
451 function transitionsclean() {
452 log "Removing out of date transitions..."
454 dak transitions -c -a
458 log "Updating DM html page"
459 $scriptsdir/dm-monitor >$webdir/dm-uploaders.html
463 log "Categorizing uncategorized bugs filed against ftp.debian.org"
468 # Push dak@merkel so it syncs the projectb there. Returns immediately, the sync runs detached
469 log "Trigger merkel/flotows $PGDATABASE sync"
470 ssh -2 -o BatchMode=yes -o SetupTimeOut=30 -o ConnectTimeout=30 -i ~/.ssh/push_merkel_projectb dak@merkel.debian.org sleep 1
471 # Also trigger flotow, the ftpmaster test box
472 ssh -2 -o BatchMode=yes -o SetupTimeOut=30 -o ConnectTimeout=30 -i ~/.ssh/push_flotow_projectb dak@flotow.debconf.org sleep 1
476 # Push dak@merkel to tell it to sync the dd accessible parts. Returns immediately, the sync runs detached
477 log "Trigger merkels dd accessible parts sync"
478 ssh -2 -o BatchMode=yes -o SetupTimeOut=30 -o ConnectTimeout=30 -i ~/.ssh/push_merkel_ddaccess dak@merkel.debian.org sleep 1
481 function mirrorpush() {
482 log "Starting the mirrorpush"
483 date -u > /srv/ftp.debian.org/web/mirrorstart
484 echo "Using dak v1" >> /srv/ftp.debian.org/web/mirrorstart
485 echo "Running on host $(hostname -f)" >> /srv/ftp.debian.org/web/mirrorstart
486 sudo -H -u archvsync /home/archvsync/runmirrors > ~dak/runmirrors.log 2>&1 &
490 log "Exporting package data foo for i18n project"
491 STAMP=$(date "+%Y%m%d%H%M")
492 mkdir -p ${scriptdir}/i18n/${STAMP}
493 cd ${scriptdir}/i18n/${STAMP}
494 dak control-suite -l stable > squeeze
495 dak control-suite -l testing > wheezy
496 dak control-suite -l unstable > sid
497 echo "${STAMP}" > timestamp
498 gpg --secret-keyring /srv/ftp-master.debian.org/s3kr1t/dot-gnupg/secring.gpg --keyring /srv/ftp-master.debian.org/s3kr1t/dot-gnupg/pubring.gpg --no-options --batch --no-tty --armour --default-key 55BE302B --detach-sign -o timestamp.gpg timestamp
502 ln -sfT ${scriptdir}/i18n/${STAMP} i18n
505 find ./i18n -mindepth 1 -maxdepth 1 -mtime +2 -not -name "${STAMP}" -type d -print0 | xargs --no-run-if-empty -0 rm -rf
509 log "Updating stats data"
511 $scriptsdir/update-ftpstats $base/log/* > $base/misc/ftpstats.data
512 R --slave --vanilla < $base/misc/ftpstats.R
513 dak stats arch-space > $webdir/arch-space
514 dak stats pkg-nums > $webdir/pkg-nums
517 function aptftpcleanup() {
518 log "Clean up apt-ftparchive's databases"
520 apt-ftparchive -q clean apt.conf
523 function compress() {
524 log "Compress old psql backups"
526 find -maxdepth 1 -mindepth 1 -type f -name 'dump_pre_*' -mtime +2 -print0 | xargs -0 --no-run-if-empty rm
528 find -maxdepth 1 -mindepth 1 -type f -name 'dump_*' \! -name '*.bz2' \! -name '*.gz' -mmin +720 |
529 while read dumpname; do
530 echo "Compressing $dumpname"
531 bzip2 -9fv "$dumpname"
533 find -maxdepth 1 -mindepth 1 -type f -name "dumpall_*" \! -name '*.bz2' \! -name '*.gz' -mmin +720 |
534 while read dumpname; do
535 echo "Compressing $dumpname"
536 bzip2 -9fv "$dumpname"
538 finddup -l -d $base/backup
541 function logstats() {
542 $masterdir/tools/logs.py "$1"
545 # save timestamp when we start
546 function savetimestamp() {
547 NOW=`date "+%Y.%m.%d-%H:%M:%S"`
548 echo ${NOW} > "${dbdir}/dinstallstart"
551 function maillogfile() {
552 cat "$LOGFILE" | mail -a "X-Debian: DAK" -s "Log for dinstall run of ${NOW}" cron@ftp-master.debian.org -- -F "Debian FTP Masters" -f ftpmaster@ftp-master.debian.org
555 function renamelogfile() {
556 if [ -f "${dbdir}/dinstallstart" ]; then
557 NOW=$(cat "${dbdir}/dinstallstart")
559 mv "$LOGFILE" "$logdir/dinstall_${NOW}.log"
560 logstats "$logdir/dinstall_${NOW}.log"
561 bzip2 -9 "$logdir/dinstall_${NOW}.log"
563 error "Problem, I don't know when dinstall started, unable to do log statistics."
564 NOW=`date "+%Y.%m.%d-%H:%M:%S"`
566 mv "$LOGFILE" "$logdir/dinstall_${NOW}.log"
567 bzip2 -9 "$logdir/dinstall_${NOW}.log"
571 function testingsourcelist() {
572 dak ls -s testing -f heidi -r .| egrep 'source$' > ${webdir}/testing.list
575 # do a last run of process-unchecked before dinstall is on.
576 function process_unchecked() {
577 log "Processing the unchecked queue"
578 UNCHECKED_WITHOUT_LOCK="-p"
583 # do a run of newstage only before dinstall is on.
584 function newstage() {
585 log "Processing the newstage queue"
586 UNCHECKED_WITHOUT_LOCK="-p"
590 # Function to update a "statefile" telling people what we are doing
593 # This should be called with the argument(s)
594 # - Status name we want to show.
597 RIGHTNOW="$(date -u +"%a %b %d %T %Z %Y (%s)")"
598 cat >"${DINSTALLSTATE}" <<EOF
599 Dinstall start: ${DINSTALLBEGIN}
601 Action start: ${RIGHTNOW}
605 # extract changelogs and stuff
606 function changelogs() {
607 log "Extracting changelogs"
608 dak make-changelog -e
609 mkdir -p ${exportpublic}/changelogs
610 cd ${exportpublic}/changelogs
611 rsync -aHW --delete --delete-after --ignore-errors ${exportdir}/changelogs/. .
612 sudo -H -u archvsync /home/archvsync/runmirrors metaftpdo > ~dak/runmirrors-metadata.log 2>&1 &