]> git.decadent.org.uk Git - dak.git/blob - config/debian/dinstall.functions
acfbee4de6fb265029655274ce9923a60eb0d04d
[dak.git] / config / debian / dinstall.functions
1 # -*- mode:sh -*-
2
3 # Remove daily lock
4 # FIXME: Dead code when switched to cronscript
5 function remove_daily_lock() {
6     rm -f $LOCK_DAILY
7 }
8
9 # Remove changelog lock
10 function remove_changelog_lock() {
11     rm -f $LOCK_CHANGELOG
12 }
13
14 # Remove all locks
15 function remove_all_locks() {
16     rm -f $LOCK_DAILY $LOCK_ACCEPTED
17 }
18
19 function remove_locks {
20     remove_all_locks
21     trap - EXIT TERM HUP INT QUIT
22     ts "locked part finished"
23 }
24
25 function lockaccepted {
26     lockfile "$LOCK_ACCEPTED"
27     trap remove_all_locks EXIT TERM HUP INT QUIT
28 }
29
30 # If we error out this one is called, *FOLLOWED* by cleanup above
31 function onerror() {
32     ERRDATE=$(date "+%Y.%m.%d-%H:%M:%S")
33
34     subject="ATTENTION ATTENTION!"
35     if [ "${error}" = "false" ]; then
36         subject="${subject} (continued)"
37     else
38         subject="${subject} (interrupted)"
39     fi
40     subject="${subject} dinstall error at ${ERRDATE} in ${STAGEFILE} - (Be quiet, Brain, or I'll stab you with a Q-tip)"
41
42     if [ -r "${STAGEFILE}.log" ]; then
43         cat "${STAGEFILE}.log"
44     else
45         echo "file ${STAGEFILE}.log does not exist, sorry"
46     fi | mail -s "${subject}" -a "X-Debian: DAK" -a "From: Debian FTP Masters <ftpmaster@ftp-master.debian.org>" cron@ftp-master.debian.org
47 }
48
49 ########################################################################
50 # the actual functions follow                                          #
51 ########################################################################
52
53 # pushing merkels QA user, part one
54 function qa1() {
55     log "Telling QA user that we start dinstall"
56     ssh -n -2 -i ~dak/.ssh/push_merkel_qa  -o BatchMode=yes -o SetupTimeOut=90 -o ConnectTimeout=90 qa@qa.debian.org sleep 1
57 }
58
59 function mirrorlists() {
60     local mldir="${scriptdir}/mirrorlist"
61     local masterlist=${mldir}/Mirrors.masterlist
62
63     cd ${mldir}
64
65     [[ -f ${HOME}/.cvspass ]] || touch ${HOME}/.cvspass
66
67     grep -q "anonscm.debian.org:/cvs/webwml" ~/.cvspass || \
68         echo ":pserver:anonymous@anonscm.debian.org:/cvs/webwml A" >> ${HOME}/.cvspass
69
70     cvs update
71
72     if [[ ! -f ${ftpdir}/README.mirrors.html ]] || [[ ${masterlist} -nt ${ftpdir}/README.mirrors.html ]]; then
73         rm -f ${ftpdir}/README.mirrors.{html,txt}
74         ${mldir}/mirror_list.pl -m ${masterlist} -t html > ${ftpdir}/README.mirrors.html
75         ${mldir}/mirror_list.pl -m ${masterlist} -t text > ${ftpdir}/README.mirrors.txt
76         log Updated archive version of mirrors file
77     fi
78 }
79
80 function mailingliststxt() {
81     cd ${ftpdir}/doc
82
83     log "Updating archive version of mailing-lists.txt"
84     wget ${wgetopts} https://www.debian.org/misc/mailing-lists.txt
85 }
86
87 function pseudopackages() {
88     cd ${scriptdir}/masterfiles
89
90     log "Updating archive version of pseudo-packages"
91     for file in maintainers description; do
92         wget ${wgetopts} https://bugs.debian.org/pseudopackages/pseudo-packages.${file}
93     done
94 }
95
96 # Updating various files
97 function bugdoctxt() {
98     log "Updating Bugs docu"
99     cd $configdir
100     $scriptsdir/update-bugdoctxt
101 }
102
103 # The first i18n one, syncing new descriptions
104 function i18n1() {
105     log "Synchronizing i18n package descriptions"
106     # First sync their newest data
107     cd ${scriptdir}/i18nsync
108     rsync -aq --delete --delete-after ddtp-sync:/does/not/matter . || true
109
110     # Now check if we still know about the packages for which they created the files
111     # is the timestamp signed by us?
112     if $(gpgv --keyring /srv/ftp-master.debian.org/s3kr1t/dot-gnupg/pubring.gpg timestamp.gpg timestamp); then
113         # now read it. As its signed by us we are sure the content is what we expect, no need
114         # to do more here. And we only test -d a directory on it anyway.
115         TSTAMP=$(cat timestamp)
116         # do we have the dir still?
117         if [ -d ${scriptdir}/i18n/${TSTAMP} ]; then
118             # Lets check!
119             if ${scriptsdir}/ddtp-i18n-check.sh . ${scriptdir}/i18n/${TSTAMP}; then
120                 # Yay, worked, lets copy around
121                 for dir in ${extimportdists}; do
122                     if [ -d dists/${dir}/ ]; then
123                         cd dists/${dir}/main/i18n
124                         rsync -aq --delete --delete-after --exclude Translation-en.bz2 --exclude Translation-*.diff/ . ${ftpdir}/dists/${dir}/main/i18n/.
125                     fi
126                     cd ${scriptdir}/i18nsync
127                 done
128             else
129                 echo "ARRRR, bad guys, wrong files, ARRR"
130                 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." -a "From: Debian FTP Masters <ftpmaster@ftp-master.debian.org>" debian-l10n-devel@lists.alioth.debian.org
131             fi
132         else
133             echo "ARRRR, missing the timestamp ${TSTAMP} directory, not updating i18n, ARRR"
134             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." -a "From: Debian FTP Masters <ftpmaster@ftp-master.debian.org>" debian-l10n-devel@lists.alioth.debian.org
135         fi
136     else
137         echo "ARRRRRRR, could not verify our timestamp signature, ARRR. Don't mess with our files, i18n guys, ARRRRR."
138         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." -a "From: Debian FTP Masters <ftpmaster@ftp-master.debian.org>" debian-l10n-devel@lists.alioth.debian.org
139     fi
140 }
141
142 # Syncing AppStream/DEP-11 data
143 function dep11() {
144     log "Synchronizing AppStream metadata"
145     # First sync their newest data
146     local dep11dir="${scriptdir}/dep11"
147     mkdir -p ${dep11dir}
148     cd ${dep11dir}
149     rsync -aq --delete --delete-after dep11-sync:/does/not/matter . || true
150
151     # Lets check!
152     if ${scriptsdir}/dep11-basic-validate.py . ${dep11dir}/; then
153         # Yay, worked, lets copy around
154         for dir in ${extimportdists}; do
155             if [ -d ${dir}/ ]; then
156                 for comp in main contrib non-free; do
157                     mkdir -p ${ftpdir}/dists/${dir}/${comp}/dep11
158                     cd ${dir}/${comp}
159                     rsync -aq --delete --delete-after --exclude *.tmp . ${ftpdir}/dists/${dir}/${comp}/dep11/.
160                     cd ${dep11dir}
161                 done
162             fi
163         done
164     else
165         echo "ARRRR, bad guys, wrong files, ARRR"
166         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." -a "From: Debian FTP Masters <ftpmaster@ftp-master.debian.org>" mak@debian.org
167     fi
168 }
169
170 function cruft() {
171     log "Checking for cruft in overrides"
172     dak check-overrides
173 }
174
175 function dominate() {
176     log "Removing obsolete source and binary associations"
177     dak dominate
178     dak manage-debug-suites unstable-debug experimental-debug
179 }
180
181 function autocruft() {
182     log "Check for obsolete binary packages"
183     dak auto-decruft -s unstable
184     dak auto-decruft -s experimental --if-newer-version-in unstable --if-newer-version-in-rm-msg "NVIU"
185 }
186
187 function fingerprints() {
188     log "Updating fingerprints"
189     dak import-keyring -L /srv/keyring.debian.org/keyrings/debian-keyring.gpg
190
191     OUTFILE=$(mktemp)
192     dak import-keyring --generate-users "%s" /srv/keyring.debian.org/keyrings/debian-maintainers.gpg >"${OUTFILE}"
193
194     if [ -s "${OUTFILE}" ]; then
195         /usr/sbin/sendmail -odq -oi -t -f envelope@ftp-master.debian.org <<EOF
196 From: Debian FTP Masters <ftpmaster@ftp-master.debian.org>
197 To: <debian-project@lists.debian.org>
198 Subject: Debian Maintainers Keyring changes
199 Content-Type: text/plain; charset=utf-8
200 X-Debian: DAK
201 MIME-Version: 1.0
202
203 The following changes to the debian-maintainers keyring have just been activated:
204
205 $(cat $OUTFILE)
206
207 Debian distribution maintenance software,
208 on behalf of the Keyring maintainers
209
210 EOF
211     fi
212     rm -f "$OUTFILE"
213 }
214
215 function overrides() {
216     log "Writing overrides into text files"
217     cd $overridedir
218     dak make-overrides
219 }
220
221 function mpfm() {
222     local archiveroot
223
224     log "Generating package / file mapping"
225     for archive in "${public_archives[@]}"; do
226         log "  archive: ${archive}"
227         archiveroot="$(get_archiveroot "${archive}")"
228         dak make-pkg-file-mapping "${archive}" | bzip2 -9 > "${archiveroot}/indices/package-file.map.bz2"
229     done
230 }
231
232 function packages() {
233     for archive in "${public_archives[@]}"; do
234         log "  Generating Packages/Sources for ${archive}"
235         dak generate-packages-sources2 -a "${archive}"
236         log "  Generating Contents for ${archive}"
237         dak contents generate -a "${archive}"
238     done
239 }
240
241 function pdiff() {
242     log "Generating pdiff files"
243     dak generate-index-diffs
244 }
245
246 function release() {
247     log "Generating Release files"
248     for archive in "${public_archives[@]}"; do
249         log "  archive: ${archive}"
250         dak generate-releases -a "${archive}"
251     done
252 }
253
254 function dakcleanup() {
255     log "Cleanup old packages/files"
256     dak clean-suites -m 10000
257     dak clean-queues -i "$unchecked"
258 }
259
260 function mklslar() {
261     local archiveroot
262     local FILENAME=ls-lR
263
264     for archive in "${public_archives[@]}"; do
265         archiveroot="$(get_archiveroot "${archive}")"
266         cd "${archiveroot}"
267
268         log "Removing any core files ..."
269         find -type f -name core -print -delete
270
271         log "Checking symlinks ..."
272         symlinks -rd .
273
274         log "Creating recursive directory listing ... "
275         rm -f ${FILENAME}.gz
276         TZ=UTC ls -lR | gzip -9c --rsyncable > ${FILENAME}.gz
277     done
278 }
279
280 function mkmaintainers() {
281     local archiveroot
282     local indices
283
284     log 'Creating Maintainers index ... '
285
286     for archive in "${public_archives[@]}"; do
287         archiveroot="$(get_archiveroot "${archive}")"
288         indices="${archiveroot}/indices"
289         if ! [ -d "${indices}" ]; then
290             mkdir "${indices}"
291         fi
292         cd "${indices}"
293
294         dak make-maintainers -a "${archive}" ${scriptdir}/masterfiles/pseudo-packages.maintainers
295         gzip -9v --rsyncable <Maintainers >Maintainers.gz
296         gzip -9v --rsyncable <Uploaders >Uploaders.gz
297     done
298 }
299
300 function copyoverrides() {
301     log 'Copying override files into public view ...'
302
303     (
304         shopt -s nullglob
305         for ofile in ${overridedir}/override.{squeeze,wheezy,jessie,stretch,sid}.{,extra.}{main,contrib,non-free}*; do
306             bname=${ofile##*/}
307             gzip -9cv --rsyncable ${ofile} > ${indices}/${bname}.gz
308             chmod g+w ${indices}/${bname}.gz
309         done
310     )
311 }
312
313 function mkfilesindices() {
314     set +o pipefail
315     umask 002
316     cd $base/ftp/indices/files/components
317
318     ARCHLIST=$(tempfile)
319
320     log "Querying postgres"
321     local query="
322       SELECT './pool/' || c.name || '/' || f.filename AS path, a.arch_string AS arch_string
323       FROM files f
324       JOIN files_archive_map af ON f.id = af.file_id
325       JOIN component c ON af.component_id = c.id
326       JOIN archive ON af.archive_id = archive.id
327       LEFT OUTER JOIN
328         (binaries b
329          JOIN architecture a ON b.architecture = a.id)
330         ON f.id = b.file
331       WHERE archive.name = 'ftp-master'
332       ORDER BY path, arch_string
333     "
334     psql -At -c "$query" >$ARCHLIST
335
336     includedirs () {
337         perl -ne 'print; while (m,/[^/]+$,) { $_=$`; print $_ . "\n" unless $d{$_}++; }'
338     }
339     poolfirst () {
340         perl -e '@nonpool=(); while (<>) { if (m,^\./pool/,) { print; } else { push @nonpool, $_; } } print for (@nonpool);'
341     }
342
343     log "Generating sources list"
344     (
345         sed -n 's/|$//p' $ARCHLIST
346         cd $base/ftp
347         find ./dists -maxdepth 1 \! -type d
348         find ./dists \! -type d | grep "/source/"
349     ) | sort -u | gzip -9 > source.list.gz
350
351     log "Generating arch lists"
352
353     ARCHES=$( (<$ARCHLIST sed -n 's/^.*|//p'; echo amd64) | grep . | grep -v all | sort -u)
354     for a in $ARCHES; do
355         (sed -n "s/|$a$//p" $ARCHLIST
356          sed -n 's/|all$//p' $ARCHLIST
357
358          cd $base/ftp
359          find ./dists -maxdepth 1 \! -type d
360          find ./dists \! -type d | grep -E "(proposed-updates.*_$a.changes$|/main/disks-$a/|/main/installer-$a/|/Contents-$a|/binary-$a/)"
361         ) | sort -u | gzip -9 > arch-$a.list.gz
362     done
363
364     log "Generating suite lists"
365
366     suite_list () {
367         local suite_id="$(printf %d $1)"
368         local query
369         query="
370           SELECT DISTINCT './pool/' || c.name || '/' || f.filename
371           FROM
372             (SELECT sa.source AS source
373                FROM src_associations sa
374               WHERE sa.suite = $suite_id
375              UNION
376              SELECT esr.src_id
377                FROM extra_src_references esr
378                JOIN bin_associations ba ON esr.bin_id = ba.bin
379                WHERE ba.suite = $suite_id
380              UNION
381              SELECT b.source AS source
382                FROM bin_associations ba
383                JOIN binaries b ON ba.bin = b.id WHERE ba.suite = $suite_id) s
384             JOIN dsc_files df ON s.source = df.source
385             JOIN files f ON df.file = f.id
386             JOIN files_archive_map af ON f.id = af.file_id
387             JOIN component c ON af.component_id = c.id
388             JOIN archive ON af.archive_id = archive.id
389             WHERE archive.name = 'ftp-master'
390         "
391         psql -F' ' -A -t -c "$query"
392
393         query="
394           SELECT './pool/' || c.name || '/' || f.filename
395           FROM bin_associations ba
396           JOIN binaries b ON ba.bin = b.id
397           JOIN files f ON b.file = f.id
398           JOIN files_archive_map af ON f.id = af.file_id
399           JOIN component c ON af.component_id = c.id
400           JOIN archive ON af.archive_id = archive.id
401           WHERE ba.suite = $suite_id AND archive.name = 'ftp-master'
402         "
403         psql -F' ' -A -t -c "$query"
404     }
405
406     psql -F' ' -At -c "SELECT id, suite_name FROM suite" |
407         while read id suite; do
408             [ -e $base/ftp/dists/$suite ] || continue
409             (
410                 (cd $base/ftp
411                  distname=$(cd dists; readlink $suite || echo $suite)
412                  find ./dists/$distname \! -type d
413                  for distdir in ./dists/*; do
414                      [ "$(readlink $distdir)" != "$distname" ] || echo $distdir
415                  done
416                 )
417                 suite_list $id
418             ) | sort -u | gzip -9 > suite-${suite}.list.gz
419         done
420
421     log "Finding everything on the ftp site to generate sundries"
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     log "Generating files list"
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 jessie stretch; do
438          find ./dists/$dist/main/i18n/ \! -type d | sort -u | gzip -9 > $base/ftp/indices/files/components/translation-$dist.list.gz
439      done
440     )
441
442     (cat ../arch-i386.files ../arch-amd64.files; zcat suite-proposed-updates.list.gz ; zcat translation-sid.list.gz ; zcat translation-jessie.list.gz ; zcat translation-stretch.list.gz) |
443         sort -u | poolfirst > ../typical.files
444
445     rm -f $ARCHLIST
446     log "Done!"
447     set -o pipefail
448 }
449
450 function mkchecksums() {
451     local archiveroot dsynclist md5list
452
453     for archive in "${public_archives[@]}"; do
454         archiveroot="$(get_archiveroot "${archive}")"
455         dsynclist=$dbdir/dsync.${archive}.list
456         md5list=${archiveroot}/indices/md5sums
457
458         log -n "Creating md5 / dsync index file for ${archive}... "
459
460         cd "$archiveroot"
461         ${bindir}/dsync-flist -q generate $dsynclist --exclude $dsynclist --md5
462         ${bindir}/dsync-flist -q md5sums $dsynclist | gzip -9n > ${md5list}.gz
463         ${bindir}/dsync-flist -q link-dups $dsynclist || true
464     done
465 }
466
467 function mirror() {
468     local archiveroot targetpath TRACEFILE
469
470     for archive in "${public_archives[@]}"; do
471         archiveroot="$(get_archiveroot "${archive}")"
472         targetpath="${mirrordir}/${archive}"
473         TRACEFILE="${archiveroot}/project/trace/ftp-master.debian.org"
474         mkdir -p "${archiveroot}/project/trace/"
475
476         log "Regenerating \"public\" mirror/${archive} hardlink fun"
477         DATE_SERIAL=$(date +"%Y%m%d01")
478         FILESOAPLUS1=$(awk '/serial/ { print $3+1 }' ${TRACEFILE} || echo ${DATE_SERIAL} )
479         if [ "$DATE_SERIAL" -gt "$FILESOAPLUS1" ]; then
480             SERIAL="$DATE_SERIAL"
481         else
482             SERIAL="$FILESOAPLUS1"
483         fi
484         date -u > ${TRACEFILE}
485         echo "Using dak v1" >> ${TRACEFILE}
486         echo "Running on host: $(hostname -f)" >> ${TRACEFILE}
487         echo "Archive serial: ${SERIAL}" >> ${TRACEFILE}
488
489         mkdir -p ${targetpath}
490         cd ${targetpath}
491         rsync -aH --link-dest ${archiveroot} --delete --delete-after --delete-excluded --exclude Packages.*.new --exclude Sources.*.new  --ignore-errors ${archiveroot}/. .
492     done
493 }
494
495 function expire() {
496     log "Expiring old database dumps..."
497     cd $base/backup
498     $scriptsdir/expire_dumps -d . -p -f "dump_*"
499 }
500
501 function transitionsclean() {
502     log "Removing out of date transitions..."
503     cd $base
504     dak transitions -c -a
505 }
506
507 function dm() {
508     log "Updating DM permissions page"
509     dak acl export-per-source dm >$exportdir/dm.txt
510 }
511
512 function bts() {
513     log "Categorizing uncategorized bugs filed against ftp.debian.org"
514     sudo -u dak-unpriv dak bts-categorize
515 }
516
517 function mirrorpush() {
518     log "Checking the public archive copies..."
519
520     local archiveroot targetpath
521
522     for archive in "${public_archives[@]}"; do
523         log "... archive: ${archive}"
524         archiveroot="$(get_archiveroot "${archive}")"
525         targetpath="${mirrordir}/${archive}"
526         cd ${archiveroot}/dists
527
528         broken=0
529         for release in $(find . -name "InRelease"); do
530             echo "Processing: ${release}"
531             subdir=${release%/InRelease}
532             while read SHASUM SIZE NAME; do
533                 if ! [ -f "${subdir}/${NAME}" ]; then
534                     bname=$(basename ${NAME})
535                     if [[ "${bname}" =~ ^(Packages|Sources|Contents-[a-zA-Z0-9-]+|Translation-[a-zA-Z_]+|Components-(amd64|i386)\.yml|icons-(128x128|64x64)\.tar)$ ]]; then
536
537                         # We don't keep unpacked files, don't check for their existance.
538                         # We might want to go and check their unpacked shasum, but right now
539                         # I don't care. I believe it should be enough if all the packed shasums
540                         # match.
541                         continue
542                     fi
543                     broken=$(( broken + 1 ))
544                     echo "File ${subdir}/${NAME} is missing"
545                     continue
546                 fi
547
548                 # We do have symlinks in the tree (see the contents files currently).
549                 # So we use "readlink -f" to check the size of the target, as thats basically
550                 # what gen-releases does
551                 fsize=$(stat -c %s $(readlink -f "${subdir}/${NAME}"))
552                 if [ ${fsize} -ne ${SIZE} ]; then
553                     broken=$(( broken + 1 ))
554                     echo "File ${subdir}/${NAME} has size ${fsize}, expected is ${SIZE}"
555                     continue
556                 fi
557
558                 fshasum=$(sha1sum $(readlink -f "${subdir}/${NAME}"))
559                 fshasum=${fshasum%% *}
560                 if [ "${fshasum}" != "${SHASUM}" ]; then
561                     broken=$(( broken + 1 ))
562                     echo "File ${subdir}/${NAME} has checksum ${fshasum}, expected is ${SHASUM}"
563                     continue
564                 fi
565             done < <(sed '1,/SHA1:/d' "${release}" | sed '/SHA256:/,$d')
566         done
567
568         if [ $broken -gt 0 ]; then
569             log_error "Trouble with the public mirror for ${archive}, found ${broken} errors"
570             continue
571         else
572             log "Starting the mirrorpush for ${archive}"
573             case ${archive} in
574                 ftp-master)
575                     fname="mirrorstart"
576                     pusharg=""
577                     ;;
578                 debian-debug)
579                     pusharg="-a debug"
580                     ;;&
581                 backports)
582                     pusharg="-a backports"
583                     ;;&
584                 *)
585                     fname="mirrorstart.${archive}"
586                     ;;
587             esac
588             date -u > /srv/ftp.debian.org/web/${fname}
589             echo "Using dak v1" >> /srv/ftp.debian.org/web/${fname}
590             echo "Running on host $(hostname -f)" >> /srv/ftp.debian.org/web/${fname}
591             sudo -H -u archvsync /home/archvsync/runmirrors ${pusharg} > ~dak/runmirrors-${archive}.log 2>&1 &
592         fi
593     done
594 }
595
596 function mirrorpush-backports() {
597     log "Syncing backports mirror"
598     sudo -u backports /home/backports/bin/update-archive
599 }
600
601 function i18n2() {
602     log "Exporting package data foo for i18n project"
603     STAMP=$(date "+%Y%m%d%H%M")
604     mkdir -p ${scriptdir}/i18n/${STAMP}
605     cd ${scriptdir}/i18n/${STAMP}
606     for suite in stable testing unstable; do
607         codename=$(dak admin s show ${suite}|grep '^Codename')
608         codename=${codename##* }
609         echo "Codename is ${codename}"
610         dak control-suite -l ${suite} >${codename}
611     done
612     echo "${STAMP}" > timestamp
613     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 473041FA --detach-sign -o timestamp.gpg timestamp
614     rm -f md5sum
615     md5sum * > md5sum
616     cd ${webdir}/
617     ln -sfT ${scriptdir}/i18n/${STAMP} i18n
618
619     cd ${scriptdir}
620     find ./i18n -mindepth 1 -maxdepth 1 -mtime +2 -not -name "${STAMP}" -type d -print0 | xargs --no-run-if-empty -0 rm -rf
621 }
622
623 function stats() {
624     log "Updating stats data"
625     cd $configdir
626     $scriptsdir/update-ftpstats $base/log/* > $base/misc/ftpstats.data
627     R --slave --vanilla < $base/misc/ftpstats.R
628     dak stats arch-space > $webdir/arch-space
629     dak stats pkg-nums > $webdir/pkg-nums
630 }
631
632 function cleantransactions() {
633     log "Cleanup transaction ids older than 3 months"
634     cd $base/backup/
635     find -maxdepth 1 -mindepth 1 -type f -name 'txid_*' -mtime +90 -delete
636 }
637
638 function logstats() {
639     $masterdir/tools/logs.py "$1"
640 }
641
642 # save timestamp when we start
643 function savetimestamp() {
644     echo ${NOW} > "${dbdir}/dinstallstart"
645 }
646
647 function maillogfile() {
648     cat "$LOGFILE" | mail -a "X-Debian: DAK" -s "Log for dinstall run of ${NOW}" -a "From: Debian FTP Masters <ftpmaster@ftp-master.debian.org>" cron@ftp-master.debian.org
649 }
650
651 function testingsourcelist() {
652     dak ls -s testing -f heidi -r .| egrep 'source$' > ${webdir}/testing.list
653 }
654
655 # Function to update a "statefile" telling people what we are doing
656 # (more or less).
657 #
658 # This should be called with the argument(s)
659 #  - Status name we want to show.
660 #
661 function state() {
662     RIGHTNOW="$(date -u +"%a %b %d %T %Z %Y (%s)")"
663     cat >"${DINSTALLSTATE}" <<EOF
664 Dinstall start: ${DINSTALLBEGIN}
665 Current action: ${1}
666 Action start: ${RIGHTNOW}
667 EOF
668 }
669
670 # extract changelogs and stuff
671 function changelogs() {
672     if lockfile -r3 $LOCK_CHANGELOG; then
673         log "Extracting changelogs"
674         dak make-changelog -e -a ftp-master
675         [ -f ${exportdir}/changelogs/filelist.yaml ] && xz -f ${exportdir}/changelogs/filelist.yaml
676         mkdir -p ${exportpublic}/changelogs
677         cd ${exportpublic}/changelogs
678         rsync -aHW --delete --delete-after --ignore-errors ${exportdir}/changelogs/. .
679         sudo -H -u staticsync /usr/local/bin/static-update-component metadata.ftp-master.debian.org >/dev/null 2>&1 &
680
681         dak make-changelog -e -a backports
682         [ -f /srv/backports-master.debian.org/export/changelogs/filelist.yaml ] && xz -f /srv/backports-master.debian.org/export/changelogs/filelist.yaml
683         mkdir -p /srv/backports-master.debian.org/rsync/export/changelogs
684         cd /srv/backports-master.debian.org/rsync/export/changelogs
685         rsync -aHW --delete --delete-after --ignore-errors /srv/backports-master.debian.org/export/changelogs/. .
686         remove_changelog_lock
687         trap remove_changelog_lock EXIT TERM HUP INT QUIT
688     fi
689 }
690
691 # Generate a list of extra mirror files, sha256sum em and sign that
692 function signotherfiles() {
693     log "Signing extra mirror files"
694
695     local archiveroot
696
697     for archive in "${public_archives[@]}"; do
698         log "... archive: ${archive}"
699         archiveroot="$(get_archiveroot "${archive}")"
700         local TMPLO=$( mktemp -p ${TMPDIR} )
701         trap "rm -f ${TMPLO}" ERR EXIT TERM HUP INT QUIT
702
703         cd ${archiveroot}
704         rm -f extrafiles
705         sha256sum $(find * -type f | egrep -v '(pool|i18n|dep11|source)/|Contents-.*\.(gz|diff)|installer|binary-|(In)?Release(.gpg)?|\.changes' | sort) > ${TMPLO}
706         gpg --no-options --batch --no-tty --armour --personal-digest-preferences=SHA256 --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 473041FA --clearsign --output ${archiveroot}/extrafiles ${TMPLO}
707         rm -f ${TMPLO}
708     done
709 }
710
711 function startup() {
712     touch "${DINSTALLSTART}"
713     ts "startup"
714     lockfile -l 3600 "${LOCK_DAILY}"
715     trap onerror ERR
716     touch "${LOCK_BRITNEY}"
717     TMPFILES="${TMPFILES} ${LOCK_DAILY} ${LOCK_BRITNEY}"
718 }