diff options
Diffstat (limited to 'infra/dgit-repos-policy-debian')
-rwxr-xr-x | infra/dgit-repos-policy-debian | 85 |
1 files changed, 44 insertions, 41 deletions
diff --git a/infra/dgit-repos-policy-debian b/infra/dgit-repos-policy-debian index fa1d17d..526db03 100755 --- a/infra/dgit-repos-policy-debian +++ b/infra/dgit-repos-policy-debian @@ -4,7 +4,9 @@ use strict; use POSIX; use JSON; -use File::Temp; +use File::Temp qw(tempfile); +use DBI; +use IPC::Open2; use Debian::Dgit qw(:DEFAULT :policyflags); use Debian::Dgit::Policy::Debian; @@ -114,18 +116,17 @@ sub good_suite_has_vsn_in_our_history () { } sub getpackage () { - die unless @ARGV > 1; + die unless @ARGV >= 1; $pkg = shift @ARGV; - die if $pkg =~ m#[^-+.0-9a-z]#; - die unless $pkg =~ m#^[^-]#; + die unless $pkg =~ m/^$package_re$/; $pkgdir = "$repos/$pkg"; - if (!stat $pkgdir) { - die "$pkgdir $!" unless $!==ENOENT; + if (!stat_exists $pkgdir) { $pkg_exists = 0; + } else { + $pkg_exists = 1; + $pkg_secret = !!(~(stat _)[2] & 05); } - $pkg_exists = 1; - $pkg_secret = !!(~(stat _)[2] & 05); } sub add_taint ($$) { @@ -144,7 +145,7 @@ sub add_taint ($$) { close $tf or die $!; $_ = <GCF>; - m/^(\w+) (\w+) (\d+)\n/ or die "$objline ?"; + m/^(\w+) (\w+) (\d+)\n/ or die "$_ ?"; my $gitobjid = $1; my $gitobjtype = $2; my $bytes = $3; @@ -193,9 +194,8 @@ sub action__check_package () { git_for_each_ref('refs/tags', sub { my ($objid,$objtype,$fullrefname,$tagname) = @_; - add_taint_by_tag($tagname,$refobjid); + add_taint_by_tag($tagname,$objid); }); - $?=0; $!=0; close TAGL or die "git for-each-ref $? $!"; return FRESHREPO; } @@ -238,7 +238,7 @@ sub action_push () { } sub action_push_confirm () { - my $initq = $dbh->prepare(<<END); + my $initq = $poldbh->prepare(<<END); SELECT taint_id, gitobjid FROM taints t WHERE (package = ? OR package = '') END @@ -248,24 +248,25 @@ END my $chkinput = tempfile(); while (my $taint = $initq->fetchrow_hashref()) { push @taintids, $taint->{taint_id}; - print $chkinput, $taint->{gitobjid}, "\n" or die $!; + print $chkinput $taint->{gitobjid}, "\n" or die $!; } flush $chkinput or die $!; seek $chkinput,0,0 or die $!; - my $checkpid = open2("<&$chkinput", \*CHKOUT, qw(git cat-file --batch)); - $checkpid or die $!; + my $checkpid = open CHKOUT, "-|" // die $!; + if (!$checkpid) { + open STDIN, "<&", $chkinput or die $!; + exec qw(git cat-file --batch) or die $!; + } my ($taintinfoq,$overridesanyq,$untaintq,$overridesq); my $overridesstmt = <<END; - SELECT deliberately FROM taintoverrides WHERE ( - my @overridesv = sort keys %deliberately; - $overridesstmt .= join <<END, (<<END x @overridesv); -END - OR + SELECT deliberately FROM taintoverrides WHERE ( 1 END - deliberately = ? + my @overridesv = sort keys %deliberately; + $overridesstmt .= join '', (<<END x @overridesv); + OR deliberately = ? END $overridesstmt .= <<END; ) AND taint_id = ? @@ -274,17 +275,21 @@ END my $mustreject=0; - while (<CHKOUT>) { - my $taintid = shift @taintids; - die unless defined $taintid; + while (my $taintid = shift @taintids) { + # git cat-file prints a spurious newline after it gets EOF + # This is not documented. I guess it might go away. So we + # just read what we expect and then let it get SIGPIPE. + $!=0; $_ = <CHKOUT>; + die "$? $!" unless defined $_; next if m/^\w+ missing$/; - die unless m/^(\w+) (\s+) (\d+)\s/; - my ($objid,$objtype,$nbytes) = @_; + die unless m/^(\w+) (\w+) (\d+)\s/; + my ($objid,$objtype,$nbytes) = ($1,$2,$3); - read CHKOUT, $_, $nbytes == $bytes or last; + my $drop; + (read CHKOUT, $drop, $nbytes) == $nbytes or die; - $taintinfoq ||= $dbh->prepare(<<END); + $taintinfoq ||= $poldbh->prepare(<<END); SELECT package, time, comment FROM taints WHERE taint_id = ? END $taintinfoq->execute($taintid); @@ -293,7 +298,7 @@ END die unless $ti; my $timeshow = defined $ti->{time} - ? " at time ".strftime("%Y-%m-%d %H:%M:%S Z", gmtime $ti->time) + ? " at time ".strftime("%Y-%m-%d %H:%M:%S Z", gmtime $ti->{time}) : ""; my $pkgshow = length $ti->{package} ? "package $ti->{package}" @@ -302,15 +307,15 @@ END $stderr .= <<END; History contains tainted $objtype $objid -Taint recorded$timeshow for $pkginfo +Taint recorded$timeshow for $pkgshow Reason: $ti->{comment} END - $overridesq ||= $dbh->prepare($overridesstmt); + $overridesq ||= $poldbh->prepare($overridesstmt); $overridesq->execute(@overridesv, $taintid); my ($ovwhy) = $overridesq->fetchrow_array(); if (!defined $ovwhy) { - $overridesanyq ||= $dbh->prepare(<<END); + $overridesanyq ||= $poldbh->prepare(<<END); SELECT 1 FROM taintoverrides WHERE taint_id = ? LIMIT 1 END $overridesanyq->execute($taintid); @@ -325,16 +330,13 @@ END $stderr .= <<END; Forcing due to --deliberately-$ovwhy END - $untaintq ||= $dbh->prepare(<<END); + $untaintq ||= $poldbh->prepare(<<END); DELETE FROM taints WHERE taint_id = ? END - $untaintq->execute($taint_id); + $untaintq->execute($taintid); } } - if (@taintids) { - $?=0; my $gotpid = waitpid $checkpid, WNOHANG; - die "@taintids $gotpid $? $!"; - } + close CHKOUT; if ($mustreject) { $stderr .= <<END; @@ -347,19 +349,20 @@ END return 0; } -$cmd =~ y/-/_/; -my $fn = ${*::}{"action__$cmd"}; +$action =~ y/-/_/; +my $fn = ${*::}{"action_$action"}; if (!$fn) { exit 0; } my $sleepy=0; +our $rcode = 127; for (;;) { poldb_setup(poldb_path($repos)); $stderr = ''; - my $rcode = $fn->(); + $rcode = $fn->(); die unless defined $rcode; eval { $poldbh->commit; }; |