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