]> git.decadent.org.uk Git - dak.git/blob - config/debian/dinstall.functions
ssh in a while loop really wants -n
[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 -n -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     done
569 }
570
571 function mirrorpush-backports() {
572     log "Syncing backports mirror"
573     sudo -u backports /home/backports/bin/update-archive
574 }
575
576 function i18n2() {
577     log "Exporting package data foo for i18n project"
578     STAMP=$(date "+%Y%m%d%H%M")
579     mkdir -p ${scriptdir}/i18n/${STAMP}
580     cd ${scriptdir}/i18n/${STAMP}
581     for suite in stable testing unstable; do
582         codename=$(dak admin s show ${suite}|grep '^Codename')
583         codename=${codename##* }
584         echo "Codename is ${codename}"
585         dak control-suite -l ${suite} >${codename}
586     done
587     echo "${STAMP}" > timestamp
588     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
589     rm -f md5sum
590     md5sum * > md5sum
591     cd ${webdir}/
592     ln -sfT ${scriptdir}/i18n/${STAMP} i18n
593
594     cd ${scriptdir}
595     find ./i18n -mindepth 1 -maxdepth 1 -mtime +2 -not -name "${STAMP}" -type d -print0 | xargs --no-run-if-empty -0 rm -rf
596 }
597
598 function stats() {
599     log "Updating stats data"
600     cd $configdir
601     $scriptsdir/update-ftpstats $base/log/* > $base/misc/ftpstats.data
602     R --slave --vanilla < $base/misc/ftpstats.R
603     dak stats arch-space > $webdir/arch-space
604     dak stats pkg-nums > $webdir/pkg-nums
605 }
606
607 function cleantransactions() {
608     log "Cleanup transaction ids older than 3 months"
609     cd $base/backup/
610     find -maxdepth 1 -mindepth 1 -type f -name 'txid_*' -mtime +90 -delete
611 }
612
613 function logstats() {
614     $masterdir/tools/logs.py "$1"
615 }
616
617 # save timestamp when we start
618 function savetimestamp() {
619         NOW=`date "+%Y.%m.%d-%H:%M:%S"`
620         echo ${NOW} > "${dbdir}/dinstallstart"
621 }
622
623 function maillogfile() {
624     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
625 }
626
627 function renamelogfile() {
628     if [ -f "${dbdir}/dinstallstart" ]; then
629         NOW=$(cat "${dbdir}/dinstallstart")
630 #        maillogfile
631         mv "$LOGFILE" "$logdir/dinstall_${NOW}.log"
632         logstats "$logdir/dinstall_${NOW}.log"
633         bzip2 -9 "$logdir/dinstall_${NOW}.log"
634     else
635         error "Problem, I don't know when dinstall started, unable to do log statistics."
636         NOW=`date "+%Y.%m.%d-%H:%M:%S"`
637 #        maillogfile
638         mv "$LOGFILE" "$logdir/dinstall_${NOW}.log"
639         bzip2 -9 "$logdir/dinstall_${NOW}.log"
640     fi
641 }
642
643 function testingsourcelist() {
644     dak ls -s testing -f heidi -r .| egrep 'source$' > ${webdir}/testing.list
645 }
646
647 # do a last run of process-unchecked before dinstall is on.
648 function process_unchecked() {
649     log "Processing the unchecked queue"
650     UNCHECKED_WITHOUT_LOCK="-p"
651     do_unchecked
652     sync_debbugs
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 function gitpdiff() {
692     # Might be that we want to change this to have more than one git repository.
693     # Advantage of one is that we do not need much space in terms of storage in git itself,
694     # git gc is pretty good on our input.
695     # But it might be faster. Well, lets test.
696     log "Adjusting the git tree for pdiffs"
697     cd ${dbdir}/git/git/
698
699     # The regex needs the architectures seperated with \|
700     garchs=$(dak admin a list|sed -e ':q;N;s/\n/\\|/g;t q')
701
702     # First, get all the files we want to work on. ../dists/ is a symlink to the real dists/ we
703     # want to work with.
704     # Also, we only want contents, packages and sources.
705     for file in $(find ../dists/ -regex ".*/\(Contents-\($archs\)\|\(Packages\|Sources\)\).gz"); do
706         log "${file}"
707         basen=${file%%.gz};
708         basen=${basen##../};
709         dir=${basen%/*};
710         mkdir -p $dir;
711         zcat $file > $basen;
712     done
713
714     # Second, add all there is into git
715     cd dists
716     git add .
717     # Maybe we want to make this the same for tag and commit? But well, shouldn't matter
718     COMD=$(date  -Is)
719     TAGD=$(date +%Y-%m-%d-%H-%M)
720     git commit -m "Commit of ${COMD}"
721     git tag "${TAGD}"
722  }