]> git.decadent.org.uk Git - dak.git/blob - config/debian/dinstall.functions
8e8735bf85ec42286b79cf5df51d71b56cee4310
[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     log "Generating package / file mapping"
150     dak make-pkg-file-mapping ftp-master | bzip2 -9 > $base/ftp/indices/package-file.map.bz2
151 }
152
153 function packages() {
154     log "Generating Packages and Sources files"
155     dak generate-packages-sources2 -a ftp-master
156     dak contents generate -a ftp-master
157 }
158
159 function pdiff() {
160     log "Generating pdiff files"
161     dak generate-index-diffs
162 }
163
164 function release() {
165     # XXX: disable once we can remove i18n/Index (#649314)
166     log "Generating i18n/Index"
167     (
168         cd "$ftpdir/dists";
169         for dist in testing unstable experimental proposed-updates testing-proposed-updates; do
170             $scriptsdir/generate-i18n-Index $dist;
171         done
172     )
173     log "Generating Release files"
174     dak generate-releases -a ftp-master
175 }
176
177 function dakcleanup() {
178     log "Cleanup old packages/files"
179     dak clean-suites -m 10000
180     dak clean-queues -i "$unchecked"
181 }
182
183 function buildd_dir() {
184     # Rebuilt the buildd dir to avoid long times of 403
185     log "Regenerating the buildd incoming dir"
186     STAMP=$(date "+%Y%m%d%H%M")
187     make_buildd_dir
188 }
189
190 function mklslar() {
191     cd $ftpdir
192
193     FILENAME=ls-lR
194
195     log "Removing any core files ..."
196     find -type f -name core -print -delete
197
198     log "Checking symlinks ..."
199     symlinks -rd .
200
201     log "Creating recursive directory listing ... "
202     rm -f ${FILENAME}.gz
203     TZ=UTC ls -lR | gzip -9c --rsyncable > ${FILENAME}.gz
204 }
205
206 function mkmaintainers() {
207     log 'Creating Maintainers index ... '
208
209     cd $indices
210     dak make-maintainers -a ftp-master ${scriptdir}/masterfiles/pseudo-packages.maintainers
211     gzip -9v --rsyncable <Maintainers >Maintainers.gz
212     gzip -9v --rsyncable <Uploaders >Uploaders.gz
213 }
214
215 function copyoverrides() {
216     log 'Copying override files into public view ...'
217
218     for ofile in ${overridedir}/override.{squeeze,wheezy,sid}.{,extra.}{main,contrib,non-free}*; do
219         bname=${ofile##*/}
220         gzip -9cv --rsyncable ${ofile} > ${indices}/${bname}.gz
221         chmod g+w ${indices}/${bname}.gz
222     done
223 }
224
225 function mkfilesindices() {
226     set +o pipefail
227     umask 002
228     cd $base/ftp/indices/files/components
229
230     ARCHLIST=$(tempfile)
231
232     log "Querying postgres"
233     local query="
234       SELECT './pool/' || c.name || '/' || f.filename AS path, a.arch_string AS arch_string
235       FROM files f
236       JOIN files_archive_map af ON f.id = af.file_id
237       JOIN component c ON af.component_id = c.id
238       JOIN archive ON af.archive_id = archive.id
239       LEFT OUTER JOIN
240         (binaries b
241          JOIN architecture a ON b.architecture = a.id)
242         ON f.id = b.file
243       WHERE archive.name = 'ftp-master'
244       ORDER BY path, arch_string
245     "
246     psql -At -c "$query" >$ARCHLIST
247
248     includedirs () {
249         perl -ne 'print; while (m,/[^/]+$,) { $_=$`; print $_ . "\n" unless $d{$_}++; }'
250     }
251     poolfirst () {
252         perl -e '@nonpool=(); while (<>) { if (m,^\./pool/,) { print; } else { push @nonpool, $_; } } print for (@nonpool);'
253     }
254
255     log "Generating sources list"
256     (
257         sed -n 's/|$//p' $ARCHLIST
258         cd $base/ftp
259         find ./dists -maxdepth 1 \! -type d
260         find ./dists \! -type d | grep "/source/"
261     ) | sort -u | gzip -9 > source.list.gz
262
263     log "Generating arch lists"
264
265     ARCHES=$( (<$ARCHLIST sed -n 's/^.*|//p'; echo amd64) | grep . | grep -v all | sort -u)
266     for a in $ARCHES; do
267         (sed -n "s/|$a$//p" $ARCHLIST
268             sed -n 's/|all$//p' $ARCHLIST
269
270             cd $base/ftp
271             find ./dists -maxdepth 1 \! -type d
272             find ./dists \! -type d | grep -E "(proposed-updates.*_$a.changes$|/main/disks-$a/|/main/installer-$a/|/Contents-$a|/binary-$a/)"
273         ) | sort -u | gzip -9 > arch-$a.list.gz
274     done
275
276     log "Generating suite lists"
277
278     suite_list () {
279         local suite_id="$(printf %d $1)"
280         local query
281         query="
282           SELECT DISTINCT './pool/' || c.name || '/' || f.filename
283           FROM
284             (SELECT sa.source AS source
285                FROM src_associations sa
286               WHERE sa.suite = $suite_id
287              UNION
288              SELECT esr.src_id
289                FROM extra_src_references esr
290                JOIN bin_associations ba ON esr.bin_id = ba.bin
291                WHERE ba.suite = $suite_id
292              UNION
293              SELECT b.source AS source
294                FROM bin_associations ba
295                JOIN binaries b ON ba.bin = b.id WHERE ba.suite = $suite_id) s
296             JOIN dsc_files df ON s.source = df.source
297             JOIN files f ON df.file = f.id
298             JOIN files_archive_map af ON f.id = af.file_id
299             JOIN component c ON af.component_id = c.id
300             JOIN archive ON af.archive_id = archive.id
301             WHERE archive.name = 'ftp-master'
302         "
303         psql -F' ' -A -t -c "$query"
304
305         query="
306           SELECT './pool/' || c.name || '/' || f.filename
307           FROM bin_associations ba
308           JOIN binaries b ON ba.bin = b.id
309           JOIN files f ON b.file = f.id
310           JOIN files_archive_map af ON f.id = af.file_id
311           JOIN component c ON af.component_id = c.id
312           JOIN archive ON af.archive_id = archive.id
313           WHERE ba.suite = $suite_id AND archive.name = 'ftp-master'
314         "
315         psql -F' ' -A -t -c "$query"
316     }
317
318     psql -F' ' -At -c "SELECT id, suite_name FROM suite" |
319     while read id suite; do
320         [ -e $base/ftp/dists/$suite ] || continue
321         (
322             (cd $base/ftp
323                 distname=$(cd dists; readlink $suite || echo $suite)
324                 find ./dists/$distname \! -type d
325                 for distdir in ./dists/*; do
326                     [ "$(readlink $distdir)" != "$distname" ] || echo $distdir
327                 done
328             )
329             suite_list $id
330         ) | sort -u | gzip -9 > suite-${suite}.list.gz
331     done
332
333     log "Finding everything on the ftp site to generate sundries"
334     (cd $base/ftp; find . \! -type d \! -name 'Archive_Maintenance_In_Progress' | sort) >$ARCHLIST
335
336     rm -f sundries.list
337     zcat *.list.gz | cat - *.list | sort -u |
338     diff - $ARCHLIST | sed -n 's/^> //p' > sundries.list
339
340     log "Generating files list"
341
342     for a in $ARCHES; do
343         (echo ./project/trace; zcat arch-$a.list.gz source.list.gz) |
344         cat - sundries.list dists.list project.list docs.list indices.list |
345         sort -u | poolfirst > ../arch-$a.files
346     done
347
348     (cd $base/ftp/
349             for dist in sid wheezy; do
350                     find ./dists/$dist/main/i18n/ \! -type d | sort -u | gzip -9 > $base/ftp/indices/files/components/translation-$dist.list.gz
351             done
352     )
353
354     (cat ../arch-i386.files ../arch-amd64.files; zcat suite-proposed-updates.list.gz ; zcat translation-sid.list.gz ; zcat translation-wheezy.list.gz) |
355     sort -u | poolfirst > ../typical.files
356
357     rm -f $ARCHLIST
358     log "Done!"
359     set -o pipefail
360 }
361
362 function mkchecksums() {
363     dsynclist=$dbdir/dsync.list
364     md5list=$indices/md5sums
365
366     log -n "Creating md5 / dsync index file ... "
367
368     cd "$ftpdir"
369     ${bindir}/dsync-flist -q generate $dsynclist --exclude $dsynclist --md5
370     ${bindir}/dsync-flist -q md5sums $dsynclist | gzip -9n > ${md5list}.gz
371     ${bindir}/dsync-flist -q link-dups $dsynclist || true
372 }
373
374 function mirror() {
375     log "Regenerating \"public\" mirror/ hardlink fun"
376     DATE_SERIAL=$(date +"%Y%m%d01")
377     FILESOAPLUS1=$(awk '/serial/ { print $3+1 }' ${TRACEFILE} )
378     if [ "$DATE_SERIAL" -gt "$FILESOAPLUS1" ]; then
379         SERIAL="$DATE_SERIAL"
380     else
381         SERIAL="$FILESOAPLUS1"
382     fi
383     date -u > ${TRACEFILE}
384     echo "Using dak v1" >> ${TRACEFILE}
385     echo "Running on host: $(hostname -f)" >> ${TRACEFILE}
386     echo "Archive serial: ${SERIAL}" >> ${TRACEFILE}
387     cd ${mirrordir}
388     rsync -aH --link-dest ${ftpdir} --delete --delete-after --delete-excluded --exclude Packages.*.new --exclude Sources.*.new  --ignore-errors ${ftpdir}/. .
389 }
390
391 function expire() {
392     log "Expiring old database dumps..."
393     cd $base/backup
394     $scriptsdir/expire_dumps -d . -p -f "dump_*"
395 }
396
397 function transitionsclean() {
398     log "Removing out of date transitions..."
399     cd $base
400     dak transitions -c -a
401 }
402
403 function dm() {
404     log "Updating DM html page"
405     $scriptsdir/dm-monitor >$webdir/dm-uploaders.html
406     dak acl export-per-source dm >$exportdir/dm.txt
407 }
408
409 function bts() {
410     log "Categorizing uncategorized bugs filed against ftp.debian.org"
411     dak bts-categorize
412 }
413
414 function ddaccess() {
415     # Tell our dd accessible mirror to sync itself up. Including ftp dir.
416     log "Trigger dd accessible parts sync including ftp dir"
417     ${scriptsdir}/sync-dd ries-sync ries-sync1 ries-sync2 pool
418 }
419
420 function mirrorpush() {
421     log "Checking the public archive copy"
422     cd ${mirrordir}/dists
423
424     broken=0
425     for release in $(find . -name "InRelease"); do
426         echo "Processing: ${release}"
427         subdir=${release%/InRelease}
428         while read SHASUM SIZE NAME; do
429             if ! [ -f "${subdir}/${NAME}" ]; then
430                bname=$(basename ${NAME})
431                 if [[ "${bname}" =~ ^(Packages|Sources|Translation-[a-zA-Z_]+)$ ]]; then
432                     # We don't keep unpacked files, don't check for their existance.
433                     # We might want to go and check their unpacked shasum, but right now
434                     # I don't care. I believe it should be enough if all the packed shasums
435                     # match.
436                     continue
437                 fi
438                 broken=$(( broken + 1 ))
439                 echo "File ${subdir}/${NAME} is missing"
440                 continue
441             fi
442
443            # We do have symlinks in the tree (see the contents files currently).
444            # So we use "readlink -f" to check the size of the target, as thats basically
445            # what gen-releases does
446             fsize=$(stat -c %s $(readlink -f "${subdir}/${NAME}"))
447             if [ ${fsize} -ne ${SIZE} ]; then
448                 broken=$(( broken + 1 ))
449                 echo "File ${subdir}/${NAME} has size ${fsize}, expected is ${SIZE}"
450                 continue
451             fi
452
453             fshasum=$(sha1sum $(readlink -f "${subdir}/${NAME}"))
454             fshasum=${fshasum%% *}
455             if [ "${fshasum}" != "${SHASUM}" ]; then
456                 broken=$(( broken + 1 ))
457                 echo "File ${subdir}/${NAME} has checksum ${fshasum}, expected is ${SHASUM}"
458                 continue
459             fi
460         done < <(sed '1,/SHA1:/d' "${release}" | sed '/SHA256:/,$d')
461     done
462
463     if [ $broken -gt 0 ]; then
464         log_error "Trouble with the public mirror, found ${broken} errors"
465         return 21
466     fi
467
468     log "Starting the mirrorpush"
469     date -u > /srv/ftp.debian.org/web/mirrorstart
470     echo "Using dak v1" >> /srv/ftp.debian.org/web/mirrorstart
471     echo "Running on host $(hostname -f)" >> /srv/ftp.debian.org/web/mirrorstart
472     sudo -H -u archvsync /home/archvsync/runmirrors > ~dak/runmirrors.log 2>&1 &
473 }
474
475 function i18n2() {
476     log "Exporting package data foo for i18n project"
477     STAMP=$(date "+%Y%m%d%H%M")
478     mkdir -p ${scriptdir}/i18n/${STAMP}
479     cd ${scriptdir}/i18n/${STAMP}
480     for suite in stable testing unstable; do
481         codename=$(dak admin s show ${suite}|grep '^Codename')
482         codename=${codename##* }
483         echo "Codename is ${codename}"
484         dak control-suite -l ${suite} >${codename}
485     done
486     echo "${STAMP}" > timestamp
487     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
488     rm -f md5sum
489     md5sum * > md5sum
490     cd ${webdir}/
491     ln -sfT ${scriptdir}/i18n/${STAMP} i18n
492
493     cd ${scriptdir}
494     find ./i18n -mindepth 1 -maxdepth 1 -mtime +2 -not -name "${STAMP}" -type d -print0 | xargs --no-run-if-empty -0 rm -rf
495 }
496
497 function stats() {
498     log "Updating stats data"
499     cd $configdir
500     $scriptsdir/update-ftpstats $base/log/* > $base/misc/ftpstats.data
501     R --slave --vanilla < $base/misc/ftpstats.R
502     dak stats arch-space > $webdir/arch-space
503     dak stats pkg-nums > $webdir/pkg-nums
504 }
505
506 function aptftpcleanup() {
507     log "Clean up apt-ftparchive's databases"
508     cd $configdir
509     apt-ftparchive -q clean apt.conf
510 }
511
512 function cleantransactions() {
513     log "Cleanup transaction ids older than 3 months"
514     cd $base/backup/
515     find -maxdepth 1 -mindepth 1 -type f -name 'txid_*' -mtime +90 -print0 | xargs -0 --no-run-if-empty rm
516 }
517
518 function logstats() {
519     $masterdir/tools/logs.py "$1"
520 }
521
522 # save timestamp when we start
523 function savetimestamp() {
524         NOW=`date "+%Y.%m.%d-%H:%M:%S"`
525         echo ${NOW} > "${dbdir}/dinstallstart"
526 }
527
528 function maillogfile() {
529     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
530 }
531
532 function renamelogfile() {
533     if [ -f "${dbdir}/dinstallstart" ]; then
534         NOW=$(cat "${dbdir}/dinstallstart")
535 #        maillogfile
536         mv "$LOGFILE" "$logdir/dinstall_${NOW}.log"
537         logstats "$logdir/dinstall_${NOW}.log"
538         bzip2 -9 "$logdir/dinstall_${NOW}.log"
539     else
540         error "Problem, I don't know when dinstall started, unable to do log statistics."
541         NOW=`date "+%Y.%m.%d-%H:%M:%S"`
542 #        maillogfile
543         mv "$LOGFILE" "$logdir/dinstall_${NOW}.log"
544         bzip2 -9 "$logdir/dinstall_${NOW}.log"
545     fi
546 }
547
548 function testingsourcelist() {
549     dak ls -s testing -f heidi -r .| egrep 'source$' > ${webdir}/testing.list
550 }
551
552 # do a last run of process-unchecked before dinstall is on.
553 function process_unchecked() {
554     log "Processing the unchecked queue"
555     UNCHECKED_WITHOUT_LOCK="-p"
556     do_unchecked
557     sync_debbugs
558 }
559
560 # Function to update a "statefile" telling people what we are doing
561 # (more or less).
562 #
563 # This should be called with the argument(s)
564 #  - Status name we want to show.
565 #
566 function state() {
567     RIGHTNOW="$(date -u +"%a %b %d %T %Z %Y (%s)")"
568     cat >"${DINSTALLSTATE}" <<EOF
569 Dinstall start: ${DINSTALLBEGIN}
570 Current action: ${1}
571 Action start: ${RIGHTNOW}
572 EOF
573 }
574
575 # extract changelogs and stuff
576 function changelogs() {
577     log "Extracting changelogs"
578     dak make-changelog -e -a ftp-master
579     mkdir -p ${exportpublic}/changelogs
580     cd ${exportpublic}/changelogs
581     rsync -aHW --delete --delete-after --ignore-errors ${exportdir}/changelogs/. .
582     sudo -H -u archvsync /home/archvsync/runmirrors metaftpdo > ~dak/runmirrors-metadata.log 2>&1 &
583 }
584
585 function gitpdiff() {
586     # Might be that we want to change this to have more than one git repository.
587     # Advantage of one is that we do not need much space in terms of storage in git itself,
588     # git gc is pretty good on our input.
589     # But it might be faster. Well, lets test.
590     log "Adjusting the git tree for pdiffs"
591     cd ${dbdir}/git/git/
592
593     # The regex needs the architectures seperated with \|
594     garchs=$(dak admin a list|sed -e ':q;N;s/\n/\\|/g;t q')
595
596     # First, get all the files we want to work on. ../dists/ is a symlink to the real dists/ we
597     # want to work with.
598     # Also, we only want contents, packages and sources.
599     for file in $(find ../dists/ -regex ".*/\(Contents-\($archs\)\|\(Packages\|Sources\)\).gz"); do
600         log "${file}"
601         basen=${file%%.gz};
602         basen=${basen##../};
603         dir=${basen%/*};
604         mkdir -p $dir;
605         zcat $file > $basen;
606     done
607
608     # Second, add all there is into git
609     cd dists
610     git add .
611     # Maybe we want to make this the same for tag and commit? But well, shouldn't matter
612     COMD=$(date  -Is)
613     TAGD=$(date +%Y-%m-%d-%H-%M)
614     git commit -m "Commit of ${COMD}"
615     git tag "${TAGD}"
616  }