]> git.decadent.org.uk Git - dak.git/blob - config/debian/dinstall.functions
config/debian/dinstall.functions: create ${archiveroot}/indices
[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     dsynclist=$dbdir/dsync.list
389     md5list=$indices/md5sums
390
391     log -n "Creating md5 / dsync index file ... "
392
393     cd "$ftpdir"
394     ${bindir}/dsync-flist -q generate $dsynclist --exclude $dsynclist --md5
395     ${bindir}/dsync-flist -q md5sums $dsynclist | gzip -9n > ${md5list}.gz
396     ${bindir}/dsync-flist -q link-dups $dsynclist || true
397 }
398
399 function mirror() {
400     log "Regenerating \"public\" mirror/ hardlink fun"
401     DATE_SERIAL=$(date +"%Y%m%d01")
402     FILESOAPLUS1=$(awk '/serial/ { print $3+1 }' ${TRACEFILE} )
403     if [ "$DATE_SERIAL" -gt "$FILESOAPLUS1" ]; then
404         SERIAL="$DATE_SERIAL"
405     else
406         SERIAL="$FILESOAPLUS1"
407     fi
408     date -u > ${TRACEFILE}
409     echo "Using dak v1" >> ${TRACEFILE}
410     echo "Running on host: $(hostname -f)" >> ${TRACEFILE}
411     echo "Archive serial: ${SERIAL}" >> ${TRACEFILE}
412     cd ${mirrordir}
413     rsync -aH --link-dest ${ftpdir} --delete --delete-after --delete-excluded --exclude Packages.*.new --exclude Sources.*.new  --ignore-errors ${ftpdir}/. .
414 }
415
416 function expire() {
417     log "Expiring old database dumps..."
418     cd $base/backup
419     $scriptsdir/expire_dumps -d . -p -f "dump_*"
420 }
421
422 function transitionsclean() {
423     log "Removing out of date transitions..."
424     cd $base
425     dak transitions -c -a
426 }
427
428 function dm() {
429     log "Updating DM permissions page"
430     dak acl export-per-source dm >$exportdir/dm.txt
431 }
432
433 function bts() {
434     log "Categorizing uncategorized bugs filed against ftp.debian.org"
435     dak bts-categorize
436 }
437
438 function ddaccess() {
439     # Tell our dd accessible mirror to sync itself up. Including ftp dir.
440     log "Trigger dd accessible parts sync including ftp dir"
441     ${scriptsdir}/sync-dd ries-sync ries-sync1 ries-sync2 pool
442 }
443
444 function mirrorpush() {
445     log "Checking the public archive copy"
446     cd ${mirrordir}/dists
447
448     broken=0
449     for release in $(find . -name "InRelease"); do
450         echo "Processing: ${release}"
451         subdir=${release%/InRelease}
452         while read SHASUM SIZE NAME; do
453             if ! [ -f "${subdir}/${NAME}" ]; then
454                bname=$(basename ${NAME})
455                 if [[ "${bname}" =~ ^(Packages|Sources|Translation-[a-zA-Z_]+)$ ]]; then
456                     # We don't keep unpacked files, don't check for their existance.
457                     # We might want to go and check their unpacked shasum, but right now
458                     # I don't care. I believe it should be enough if all the packed shasums
459                     # match.
460                     continue
461                 fi
462                 broken=$(( broken + 1 ))
463                 echo "File ${subdir}/${NAME} is missing"
464                 continue
465             fi
466
467            # We do have symlinks in the tree (see the contents files currently).
468            # So we use "readlink -f" to check the size of the target, as thats basically
469            # what gen-releases does
470             fsize=$(stat -c %s $(readlink -f "${subdir}/${NAME}"))
471             if [ ${fsize} -ne ${SIZE} ]; then
472                 broken=$(( broken + 1 ))
473                 echo "File ${subdir}/${NAME} has size ${fsize}, expected is ${SIZE}"
474                 continue
475             fi
476
477             fshasum=$(sha1sum $(readlink -f "${subdir}/${NAME}"))
478             fshasum=${fshasum%% *}
479             if [ "${fshasum}" != "${SHASUM}" ]; then
480                 broken=$(( broken + 1 ))
481                 echo "File ${subdir}/${NAME} has checksum ${fshasum}, expected is ${SHASUM}"
482                 continue
483             fi
484         done < <(sed '1,/SHA1:/d' "${release}" | sed '/SHA256:/,$d')
485     done
486
487     if [ $broken -gt 0 ]; then
488         log_error "Trouble with the public mirror, found ${broken} errors"
489         return 21
490     fi
491
492     log "Starting the mirrorpush"
493     date -u > /srv/ftp.debian.org/web/mirrorstart
494     echo "Using dak v1" >> /srv/ftp.debian.org/web/mirrorstart
495     echo "Running on host $(hostname -f)" >> /srv/ftp.debian.org/web/mirrorstart
496     sudo -H -u archvsync /home/archvsync/runmirrors > ~dak/runmirrors.log 2>&1 &
497 }
498
499 function i18n2() {
500     log "Exporting package data foo for i18n project"
501     STAMP=$(date "+%Y%m%d%H%M")
502     mkdir -p ${scriptdir}/i18n/${STAMP}
503     cd ${scriptdir}/i18n/${STAMP}
504     for suite in stable testing unstable; do
505         codename=$(dak admin s show ${suite}|grep '^Codename')
506         codename=${codename##* }
507         echo "Codename is ${codename}"
508         dak control-suite -l ${suite} >${codename}
509     done
510     echo "${STAMP}" > timestamp
511     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
512     rm -f md5sum
513     md5sum * > md5sum
514     cd ${webdir}/
515     ln -sfT ${scriptdir}/i18n/${STAMP} i18n
516
517     cd ${scriptdir}
518     find ./i18n -mindepth 1 -maxdepth 1 -mtime +2 -not -name "${STAMP}" -type d -print0 | xargs --no-run-if-empty -0 rm -rf
519 }
520
521 function stats() {
522     log "Updating stats data"
523     cd $configdir
524     $scriptsdir/update-ftpstats $base/log/* > $base/misc/ftpstats.data
525     R --slave --vanilla < $base/misc/ftpstats.R
526     dak stats arch-space > $webdir/arch-space
527     dak stats pkg-nums > $webdir/pkg-nums
528 }
529
530 function aptftpcleanup() {
531     log "Clean up apt-ftparchive's databases"
532     cd $configdir
533     apt-ftparchive -q clean apt.conf
534 }
535
536 function cleantransactions() {
537     log "Cleanup transaction ids older than 3 months"
538     cd $base/backup/
539     find -maxdepth 1 -mindepth 1 -type f -name 'txid_*' -mtime +90 -print0 | xargs -0 --no-run-if-empty rm
540 }
541
542 function logstats() {
543     $masterdir/tools/logs.py "$1"
544 }
545
546 # save timestamp when we start
547 function savetimestamp() {
548         NOW=`date "+%Y.%m.%d-%H:%M:%S"`
549         echo ${NOW} > "${dbdir}/dinstallstart"
550 }
551
552 function maillogfile() {
553     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
554 }
555
556 function renamelogfile() {
557     if [ -f "${dbdir}/dinstallstart" ]; then
558         NOW=$(cat "${dbdir}/dinstallstart")
559 #        maillogfile
560         mv "$LOGFILE" "$logdir/dinstall_${NOW}.log"
561         logstats "$logdir/dinstall_${NOW}.log"
562         bzip2 -9 "$logdir/dinstall_${NOW}.log"
563     else
564         error "Problem, I don't know when dinstall started, unable to do log statistics."
565         NOW=`date "+%Y.%m.%d-%H:%M:%S"`
566 #        maillogfile
567         mv "$LOGFILE" "$logdir/dinstall_${NOW}.log"
568         bzip2 -9 "$logdir/dinstall_${NOW}.log"
569     fi
570 }
571
572 function testingsourcelist() {
573     dak ls -s testing -f heidi -r .| egrep 'source$' > ${webdir}/testing.list
574 }
575
576 # do a last run of process-unchecked before dinstall is on.
577 function process_unchecked() {
578     log "Processing the unchecked queue"
579     UNCHECKED_WITHOUT_LOCK="-p"
580     do_unchecked
581     sync_debbugs
582 }
583
584 # Function to update a "statefile" telling people what we are doing
585 # (more or less).
586 #
587 # This should be called with the argument(s)
588 #  - Status name we want to show.
589 #
590 function state() {
591     RIGHTNOW="$(date -u +"%a %b %d %T %Z %Y (%s)")"
592     cat >"${DINSTALLSTATE}" <<EOF
593 Dinstall start: ${DINSTALLBEGIN}
594 Current action: ${1}
595 Action start: ${RIGHTNOW}
596 EOF
597 }
598
599 # extract changelogs and stuff
600 function changelogs() {
601     log "Extracting changelogs"
602     dak make-changelog -e -a ftp-master
603     mkdir -p ${exportpublic}/changelogs
604     cd ${exportpublic}/changelogs
605     rsync -aHW --delete --delete-after --ignore-errors ${exportdir}/changelogs/. .
606     sudo -H -u archvsync /home/archvsync/runmirrors metaftpdo > ~dak/runmirrors-metadata.log 2>&1 &
607 }
608
609 function gitpdiff() {
610     # Might be that we want to change this to have more than one git repository.
611     # Advantage of one is that we do not need much space in terms of storage in git itself,
612     # git gc is pretty good on our input.
613     # But it might be faster. Well, lets test.
614     log "Adjusting the git tree for pdiffs"
615     cd ${dbdir}/git/git/
616
617     # The regex needs the architectures seperated with \|
618     garchs=$(dak admin a list|sed -e ':q;N;s/\n/\\|/g;t q')
619
620     # First, get all the files we want to work on. ../dists/ is a symlink to the real dists/ we
621     # want to work with.
622     # Also, we only want contents, packages and sources.
623     for file in $(find ../dists/ -regex ".*/\(Contents-\($archs\)\|\(Packages\|Sources\)\).gz"); do
624         log "${file}"
625         basen=${file%%.gz};
626         basen=${basen##../};
627         dir=${basen%/*};
628         mkdir -p $dir;
629         zcat $file > $basen;
630     done
631
632     # Second, add all there is into git
633     cd dists
634     git add .
635     # Maybe we want to make this the same for tag and commit? But well, shouldn't matter
636     COMD=$(date  -Is)
637     TAGD=$(date +%Y-%m-%d-%H-%M)
638     git commit -m "Commit of ${COMD}"
639     git tag "${TAGD}"
640  }