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