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