#!/bin/bash set -e salt='' tmp=tmp var=var rsync=rsync disable=true interactive=true target=source suppressrepeatedemails=false arch=`dpkg --print-architecture` logheadmaxbytes=32768 logtailmaxbytes=32768 upload_src=false for config in "$@"; do case "$config" in *=*) eval "$config" ;; *) . "$config" ;; esac done if $disable; then echo >&2 'disabled because config inadequate (no disable=false)' exit 1 fi : ${destdirtail:=$distro-$target} : ${destdirfin:="$destdircommon$destdirtail"} case $target in source) sources=Sources descx='' ;; binary-*) sources=Packages descx="${target#binary-}" ;; *) echo >&2 'target must be source or binary-*' exit 1 esac exec 3>&1 printf >&3 "starting " rm -rf "$tmp" mkdir "$tmp" >"$tmp"/_log_raw if $interactive; then echo '(log diverted to stdout)' >>"$tmp"/_log_raw else exec >>"$tmp"/_log_raw fi exec 4>&1 progress () { echo "++++++ $1 ++++++" } gurl () { progress "fetching $1" curl -fsS "$1" >"$2" } gurl "$mirror/dists/$distro/$suite/$target/$sources.gz" "$tmp"/_$sources.gz zcat "$tmp"/_$sources.gz >"$tmp"/_$sources-in lastinfo="$var"/lastinfo-$target : "${scorelog:="$var"/scores-$target}" now=`date +%s` >>"$lastinfo" progress selecting if test $target = source; then blacklist="$blacklistsourcepackages" else blacklist="$blacklistbinarypackages" fi if [ "x$pkg" = x ]; then pkg="`perl -e ' use IO::Handle; $pre= "[-+.0-9a-z]+"; $vre= "[-+.0-9a-zA-Z:~]+"; sub f1() { $fn=shift @ARGV; open F, $fn or die "$fn $!"; } sub f2() { F->error and die "$fn $!"; close F or die "$fn $!"; } $scorelog= "'"$scorelog"'"; if (length $scorelog) { open SCORE, "> $scorelog.new" or die $!; } sub pscore ($;$) { return unless length $scorelog; printf SCORE "%$_[1]s", $_[0] or die $!; } sub readpkglist ($$) { my ($arrayref, $filename) = @_; return unless length $filename; unshift @ARGV, $filename; f1(); while () { next if m/^\#/ or !m/\S/; die unless m/^($pre)(?:\S.*)?\s*$/; $arrayref->{$1}= 1; } f2(); } readpkglist(\%suppress, "'"$suppresspackages"'"); readpkglist(\%blacklist, "'"$blacklist"'"); f1(); while () { die unless m/^($pre) ($vre) (\d+)( .*)?$/; $lastver{$1}= $2; $lasttime{$1}= $3; $extras{$1}= $4." "; } f2(); f1(); $best_score= -2e9; sub scorepackage () { return if length $skip; return if $blacklist{$package}; return if $score < $best_score or ($score==$best_score and \ $package gt $best_package); #printf STDERR " <----- best score=%s best_score=%s\n", $score, $best_score; pscore(" (best)"); $best_score= $score; $best_package= $package; } sub endpackage () { return unless (defined $package or defined $version or defined $skip or defined $source); die unless defined $package; die unless defined $version; $source= $package if !defined $source; $score= '$now' - $lasttime{$package}; pscore("$package ",-30); pscore("$source ",-25); pscore("$score",10); if ($score>1e7) { $score= 1e7; $scorechars.='c'; } pscore(" $lastver{$package}",-25); pscore(" $version ",-25); $scorechars= ""; if ($lastver{$package} ne $version) { $score *= 5; $scorechars.="U"; } if ($extras{$package} =~ m/ nt /) { $scorechars.="n"; } else { $score *= 10; } if ($suppress{$source}) { $score -= 2e7; $scorechars.="s"; } $scorechars.="[$skip]" if length $skip; pscore("-$scorechars",-7); pscore("$score",10); #print STDERR "SCORE package=$package score $score source=$source\n"; scorepackage(); pscore("\n"); undef $package; undef $version; undef $skip; undef $source; } while () { if (m/^Package: ($pre)$/) { die if defined $package; $package= $1; } elsif (m/^Version: ($vre)$/) { die if defined $version; $version= $1; } elsif (m/^Source: ($pre)$/) { die if defined $source; $source= $1; } elsif (m/^Architecture:.*/ && !m/\s(?:'$arch'|all|any)\s/) { #printf STDERR " <----- skip %s %s\n", $&, "'$arch'"; $skip .= 'a'; } elsif (m/^$/) { endpackage(); } } f2(); endpackage(); if (length $scorelog) { close SCORE or die $!; rename "$scorelog.new","$scorelog" or die $!; } die unless length $best_package; open L, ">&4" or die $!; printf L "selected %s (age %s, score %d)\n", $best_package, exists($lastime{$best_package}) ? '$now' - $lasttime{$best_package} : "", $best_score; print "$best_package\n" or die $!; ' "$lastinfo" "$tmp"/_$sources-in`" else printf >&4 "package forced: %s\n" "$pkg" fi sed -n "/^Package: $pkg\$/,/^\$/p" \ <"$tmp"/_$sources-in >"$tmp"/_this-stanza echo cat "$tmp"/_this-stanza getfield () { eval 'p'$1'="` sed -n '\''s/^'$1': //p'\'' \ <"$tmp"/_this-stanza `"' } printf >&3 "selected \"%s\" " $pkg tp="$tmp/$pkg" mkdir "$tp" "$tp/src" "$tp/tmp" "$tp/out" getfield Version getfield Source if [ "x$pSource" != x ]; then src="$pSource" else src="$pkg" fi if test $target = source; then getfield Directory leafnames="` sed -n '/^Files:/,/^([^ ].*)?$/{ /^ /{ s/^ [0-9a-z][0-9a-z]* *[0-9][0-9]* //; p }}' \ <"$tmp"/_this-stanza `" for leafname in $leafnames; do df="$tp/src/$leafname" case "$leafname" in */*|.*) echo >&2 "bad leafname: $leafname"; exit 1;; *.dsc) fot="$df";; esac gurl "$mirror/$pDirectory/$leafname" "$df" done testmode=--source testmode2='' desc="$pkg" : ${upload_if_ok:=true} email_package_header="$email_sourcepackage_header" else getfield Filename fot="$tp/src/$pkg.deb" gurl "$mirror/$pFilename" "$fot" testmode='--binaries=install --binary' testmode2=--instantiate desc="$pkg $descx" : ${upload_if_ok:=false} email_package_header="$email_binarypackage_header" fi if [ "x$maintainer_email_override" = x ]; then getfield Maintainer maintainer_email=pMaintainer else maintainer_email=maintainer_email_override fi printf >&3 "adt-run " progress "starting test" xrc () { printf "+ %s\n" "$*" set +e "$@" rc=$? set -e } echo 'fatal: adt-run did not start properly' >"$tmp"/_summary xrc adt-run --tmp-dir "$tp"/tmp \ --output-dir "$tp"/out \ --log-file "$tp"/log \ --summary "$tmp"/_summary \ $adtrun_extra_opts \ $testmode "$fot" $testmode2 \ --- \ adt-virt-xenlvm \ $adtvirt_extra_opts \ --distro="$distro" \ -- \ 2>&1 3>&- 4>&- printf >&3 "%s " $rc ourx=0 upload=true : ${upload_if_notests:=false} extras='' case "$rc" in 0) summary='all OK'; email='' upload=$upload_if_ok ;; 2) summary='OK (some skipped)'; email='' upload=$upload_if_ok ;; 8) summary='package declares no tests'; email='' upload=$upload_if_notests; extras='nt' ;; 4|6) summary='test(s) failed!'; email="$maintainer_email" ;; 12) summary='erroneous package!'; email="$maintainer_email" ;; 16) summary='testbed failed!'; email="administrator_email" ;; *) summary='unexpected failure!'; email="administrator_email"; ourx=20;; esac progress "RESULTS $summary" if [ "x$suppresspackages" != x ] \ && grep -x "$src" "$suppresspackages" >/dev/null; then printf >&3 "email-suppressed " email='' fi if $upload; then progress "bundling" printf "\n%s\n" "$summary" >>"$tmp"/_summary edest=${email%_email} esummary="$var"/emailed/last-$pkg,$edest if [ "x$edest" = x ]; then printf >&3 "email-none " rm -f "$var"/emailed/last-$pkg,* esummary='' elif $suppressrepeatedemails \ && [ -f "$esummary" ] \ && diff -u "$esummary" "$tmp"/_summary >"$var"/emailed/diff-$pkg; then printf >&3 "email-same $email " email='' esummary='' else cp "$tmp"/_summary "$esummary".new fi ln -f "$tmp"/_summary "$tp"/summary for odir in tmp out; do if test -d "$tp"/$odir; then GZIP=-2 tar -f "$tp"/$odir.tar.gz -C "$tp" -zc $odir rm -r "$tp"/$odir fi done if ! $upload_src; then rm -r "$tp"/src fi progress "uploading" printf >&3 "uploading" $rsync -rltH --safe-links --delete "$tp" "$destrsynchead/$destdirfin/" printf >&3 " " fi if [ "x$email" != x ]; then progress "contacting $email" eval "email_addr=\$$email" printf >&3 "email \"%s\" " "$email_addr" cat >"$tmp"/_email_header <"$tmp"/_email "%s" "$email_package_header" cat >>"$tmp"/_email <>"$tmp"/_email cat >>"$tmp"/_email <>"$tmp"/_email <>"$tmp"/_email <>"$tmp"/_email <&2 "huh email $email is what why?" exit 1 ;; esac cat >>"$tmp/_email" <>"$var"/log "%s=%s rc=%s emailed='%s'\n" \ "$target" "$pkg" $rc "$email_addr" if [ "x$ourx" = x0 ]; then sed -e "/^$pkg /d" <"$lastinfo" >"$lastinfo".new printf "%s %s %s %s\n" "$pkg" "$pVersion" "$now" "$extras" \ >>"$lastinfo".new mv "$lastinfo".new "$lastinfo" progress "tested." else progress "fault ($ourx)." fi perl <"$tmp"/_log_raw >"$tmp"/_log -ne ' s/[^\012\040-\133\135-\176]/ $& eq "\t" ? "\\t" : $& eq "\r" ? "\\r" : $& eq "\b" ? "\\b" : $& eq "\\" ? "\\\\" : sprintf "\\x%02x", ord $& /ge; if (!$middle) { $headlen += length; $middle=1 if $headlen > '"$logheadmaxbytes"'; } if (!$middle) { print or die $!; } else { $taillen += length; push @tail, $_; while ($taillen > '"$logtailmaxbytes"') { $taillen -= length shift @tail; $some_dropped= 1; } } END { print "...\n" or die $! if $some_dropped; print @tail or die $!; } ' if [ "x$email" = x ]; then if $interactive; then cat "$tmp"/_log >&2 fi else cat >>"$tmp"/_email 2>&1 "$tmp"/_log ||: if [ "x$email_signing_key" != x ]; then printf >&3 "signing " echo >>"$tmp/_email" gpg -u"$email_signing_key" --clearsign \ <"$tmp/_email" >"$tmp/_email.asc" mv -f "$tmp/_email.asc" "$tmp/_email" fi cat "$tmp/_email_header" "$tmp/_email" >"$tmp/_email.new" mv -f "$tmp/_email.new" "$tmp/_email" if $interactive; then cat "$tmp"/_email >&2 else sendmail -odi -oem -t -oi <"$tmp"/_email if [ "x$esummary" != x ]; then printf >&3 "email-recorded " mv "$esummary".new "esummary" fi fi fi printf >&3 "done %s.\n" $ourx exit $ourx