]> git.decadent.org.uk Git - dak.git/blob - config/debian/dinstall.functions
761c7249e745f565bab0180351dd8f5e7b75d2dd
[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         RFC822DATE=$(LC_ALL=POSIX LANG=POSIX date -u -R)
481         date -u > ${TRACEFILE}
482         {
483             echo "Using dak v1"
484             echo "Running on host: $(hostname -f)"
485             echo "Archive serial: ${SERIAL}"
486             echo "Date: ${RFC822DATE}"
487         } >> ${TRACEFILE}
488         # Now make it accessible via one name, no matter on which host we run
489         cd ${archiveroot}/project/trace/
490         ln -sf ftp-master.debian.org master
491
492         mkdir -p ${targetpath}
493         cd ${targetpath}
494         rsync -aH --link-dest ${archiveroot} --delete --delete-after --delete-excluded --exclude Packages.*.new --exclude Sources.*.new  --ignore-errors ${archiveroot}/. .
495     done
496 }
497
498 function expire() {
499     log "Expiring old database dumps..."
500     cd ${base}/backup
501     ${scriptsdir}/expire_dumps -d . -p -f "dump_*"
502 }
503
504 function transitionsclean() {
505     log "Removing out of date transitions..."
506     cd ${base}
507     dak transitions -c -a
508 }
509
510 function dm() {
511     log "Updating DM permissions page"
512     dak acl export-per-source dm >${exportdir}/dm.txt
513 }
514
515 function bts() {
516     log "Categorizing uncategorized bugs filed against ftp.debian.org"
517     sudo -u dak-unpriv dak bts-categorize
518 }
519
520 function mirrorpush() {
521     log "Checking the public archive copies..."
522
523     local archiveroot targetpath
524
525     for archive in "${public_archives[@]}"; do
526         log "... archive: ${archive}"
527         archiveroot="$(get_archiveroot "${archive}")"
528         targetpath="${mirrordir}/${archive}"
529         cd ${archiveroot}/dists
530
531         broken=0
532         for release in $(find . -name "InRelease"); do
533             echo "Processing: ${release}"
534             subdir=${release%/InRelease}
535             while read SHASUM SIZE NAME; do
536                 if ! [[ -f ${subdir}/${NAME} ]]; then
537                     bname=$(basename ${NAME})
538                     if [[ "${bname}" =~ ^(Packages|Sources|Contents-[a-zA-Z0-9-]+|Translation-[a-zA-Z_]+|Components-[a-zA-Z0-9-]\.yml|icons-(128x128|64x64)\.tar)$ ]]; then
539
540                         # We don't keep unpacked files, don't check for their existance.
541                         # We might want to go and check their unpacked shasum, but right now
542                         # I don't care. I believe it should be enough if all the packed shasums
543                         # match.
544                         continue
545                     fi
546                     broken=$(( broken + 1 ))
547                     echo "File ${subdir}/${NAME} is missing"
548                     continue
549                 fi
550
551                 # We do have symlinks in the tree (see the contents files currently).
552                 # So we use "readlink -f" to check the size of the target, as thats basically
553                 # what gen-releases does
554                 fsize=$(stat -c %s $(readlink -f "${subdir}/${NAME}"))
555                 if [[ ${fsize} -ne ${SIZE} ]]; then
556                     broken=$(( broken + 1 ))
557                     echo "File ${subdir}/${NAME} has size ${fsize}, expected is ${SIZE}"
558                     continue
559                 fi
560
561                 fshasum=$(sha1sum $(readlink -f "${subdir}/${NAME}"))
562                 fshasum=${fshasum%% *}
563                 if [[ ${fshasum} != ${SHASUM} ]]; then
564                     broken=$(( broken + 1 ))
565                     echo "File ${subdir}/${NAME} has checksum ${fshasum}, expected is ${SHASUM}"
566                     continue
567                 fi
568             done < <(sed '1,/SHA1:/d' "${release}" | sed '/SHA256:/,$d')
569         done
570
571         if [[ $broken -gt 0 ]]; then
572             log_error "Trouble with the public mirror for ${archive}, found ${broken} errors"
573             continue
574         else
575             log "Starting the mirrorpush for ${archive}"
576             case ${archive} in
577                 ftp-master)
578                     fname="mirrorstart"
579                     pusharg=""
580                     pname="debian"
581                     ;;
582                 debian-debug)
583                     pusharg="-a debug"
584                     ;;&
585                 backports)
586                     pusharg="-a backports"
587                     ;;&
588                 *)
589                     fname="mirrorstart.${archive}"
590                     pname=${archive}
591                     ;;
592             esac
593             mkdir -p ${webdir}/${pname}/project/trace/
594             ln -sf ${mirrordir}/${archive}/project/trace/master ${webdir}/${pname}/project/trace/master
595
596             date -u > ${webdir}/${fname}
597             echo "Using dak v1" >> ${webdir}/${fname}
598             echo "Running on host $(hostname -f)" >> ${webdir}/${fname}
599             sudo -H -u archvsync /home/archvsync/runmirrors ${pusharg} > ~dak/runmirrors-${archive}.log 2>&1 &
600         fi
601     done
602 }
603
604 function mirrorpush-backports() {
605     log "Syncing backports mirror"
606     sudo -u backports /home/backports/bin/update-archive
607 }
608
609 function i18n2() {
610     log "Exporting package data foo for i18n project"
611     STAMP=$(date "+%Y%m%d%H%M")
612     mkdir -p ${scriptdir}/i18n/${STAMP}
613     cd ${scriptdir}/i18n/${STAMP}
614     for suite in stable testing unstable; do
615         codename=$(dak admin s show ${suite}|grep '^Codename')
616         codename=${codename##* }
617         echo "Codename is ${codename}"
618         dak control-suite -l ${suite} >${codename}
619     done
620     echo "${STAMP}" > timestamp
621     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
622     rm -f md5sum
623     md5sum * > md5sum
624     cd ${webdir}/
625     ln -sfT ${scriptdir}/i18n/${STAMP} i18n
626
627     cd ${scriptdir}
628     find ./i18n -mindepth 1 -maxdepth 1 -mtime +2 -not -name "${STAMP}" -type d -print0 | xargs --no-run-if-empty -0 rm -rf
629 }
630
631 function stats() {
632     log "Updating stats data"
633     cd ${configdir}
634     ${scriptsdir}/update-ftpstats ${base}/log/* > ${base}/misc/ftpstats.data
635     R --slave --vanilla < ${base}/misc/ftpstats.R
636     dak stats arch-space > ${webdir}/arch-space
637     dak stats pkg-nums > ${webdir}/pkg-nums
638 }
639
640 function cleantransactions() {
641     log "Cleanup transaction ids older than 3 months"
642     cd ${base}/backup/
643     find -maxdepth 1 -mindepth 1 -type f -name 'txid_*' -mtime +90 -delete
644 }
645
646 function logstats() {
647     ${masterdir}/tools/logs.py "$1"
648 }
649
650 # save timestamp when we start
651 function savetimestamp() {
652     echo ${NOW} > "${dbdir}/dinstallstart"
653 }
654
655 function maillogfile() {
656     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 < "${LOGFILE}"
657 }
658
659 function testingsourcelist() {
660     dak ls -s testing -f heidi -r .| egrep 'source$' > ${webdir}/testing.list
661 }
662
663 # Function to update a "statefile" telling people what we are doing
664 # (more or less).
665 #
666 # This should be called with the argument(s)
667 #  - Status name we want to show.
668 #
669 function state() {
670     RIGHTNOW="$(date -u +"%a %b %d %T %Z %Y (%s)")"
671     cat >"${DINSTALLSTATE}" <<EOF
672 Dinstall start: ${DINSTALLBEGIN}
673 Current action: ${1}
674 Action start: ${RIGHTNOW}
675 EOF
676 }
677
678 # extract changelogs and stuff
679 function changelogs() {
680     if lockfile -r3 ${LOCK_CHANGELOG}; then
681         trap remove_changelog_lock EXIT TERM HUP INT QUIT
682         log "Extracting changelogs"
683         dak make-changelog -e -a ftp-master
684         [[ -f ${exportdir}/changelogs/filelist.yaml ]] && xz -f ${exportdir}/changelogs/filelist.yaml
685         mkdir -p ${exportpublic}/changelogs
686         cd ${exportpublic}/changelogs
687         rsync -aHW --delete --delete-after --ignore-errors ${exportdir}/changelogs/. .
688         sudo -H -u staticsync /usr/local/bin/static-update-component metadata.ftp-master.debian.org >/dev/null 2>&1 &
689
690         dak make-changelog -e -a backports
691         [[ -f /srv/backports-master.debian.org/export/changelogs/filelist.yaml  ]] && xz -f /srv/backports-master.debian.org/export/changelogs/filelist.yaml
692         mkdir -p /srv/backports-master.debian.org/rsync/export/changelogs
693         cd /srv/backports-master.debian.org/rsync/export/changelogs
694         rsync -aHW --delete --delete-after --ignore-errors /srv/backports-master.debian.org/export/changelogs/. .
695         remove_changelog_lock
696     fi
697 }
698
699 # Generate a list of extra mirror files, sha256sum em and sign that
700 function signotherfiles() {
701     log "Signing extra mirror files"
702
703     local archiveroot
704
705     for archive in "${public_archives[@]}"; do
706         log "... archive: ${archive}"
707         archiveroot="$(get_archiveroot "${archive}")"
708         local TMPLO=$( gettempfile )
709
710         cd ${archiveroot}
711         rm -f extrafiles
712         sha256sum $(find * -type f | egrep -v '(pool|i18n|dep11|source)/|Contents-.*\.(gz|diff)|installer|binary-|(In)?Release(.gpg)?|\.changes' | sort) > ${TMPLO}
713         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}
714         rm -f ${TMPLO}
715     done
716 }
717
718 function startup() {
719     touch "${DINSTALLSTART}"
720     ts "startup"
721     lockfile -l 3600 "${LOCK_DAILY}"
722     trap onerror ERR
723     touch "${LOCK_BRITNEY}"
724     TMPFILES="${TMPFILES} ${LOCK_DAILY} ${LOCK_BRITNEY}"
725 }
726
727 function postcronscript() {
728     logstats ${LOGFILE}
729     state "all done"
730     touch "${DINSTALLEND}"
731 }