X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=dgit.git;a=blobdiff_plain;f=infra%2Fdgit-repos-server;h=8162fa109cab65e8c66fe2afb8be89ee7b5d7c35;hp=56fc4fd0ef766bbfd617aac8dfc34148ccfd55c2;hb=444896a3a9780647f751966f2c0b26f39c5cd8d3;hpb=eab588a83905122af678182876c2f800e4b6fa77;ds=sidebyside diff --git a/infra/dgit-repos-server b/infra/dgit-repos-server index 56fc4fd0..8162fa10 100755 --- a/infra/dgit-repos-server +++ b/infra/dgit-repos-server @@ -2,7 +2,8 @@ # dgit-repos-server # # usages: -# .../dgit-repos-server DISTRO SUITES KEYRING-AUTH-SPEC DGIT-REPOS-DIR --ssh +# .../dgit-repos-server DISTRO SUITES KEYRING-AUTH-SPEC \ +# DGIT-REPOS-DIR POLICY-HOOK-SCRIPT --ssh # internal usage: # .../dgit-repos-server --pre-receive-hook PACKAGE # @@ -94,6 +95,7 @@ our $func; our $dgitrepos; our $package; our $suitesfile; +our $policyhook; our $realdestrepo; our $destrepo; our $workrepo; @@ -186,6 +188,18 @@ sub runcmd { die "@_ $? $!" if $r; } +sub policyhook { + my ($policyallowbits, @polargs) = @_; + # => ($exitstatuspolicybitmap, $policylockfh); + die if $policyallowbits & ~0x3e; + my @cmd = ($policyhook,$distro,$repos,@polargs); + debugcmd @_; + my $r = system @_; + die "system: $!" if $r < 0; + die "hook (@cmd) failed ($?)" if $r & ~($policyallowbits << 8); + return $r >> 8; +} + #----- git-receive-pack ----- sub fixmissing__git_receive_pack () { @@ -490,11 +504,15 @@ sub checks () { debug "translated version $v"; $tagname eq "debian/$v" or die; + my ($policy) = policyhook(2,'push',$package, + $version,$suite,$tagname, + join(",",@delberatelies)); + checksuite(); # check that our ref is being fast-forwarded debug "oldcommit $oldcommit"; - if ($oldcommit =~ m/[^0]/) { + if (!($policy & 2) && $oldcommit =~ m/[^0]/) { $?=0; $!=0; my $mb = `git merge-base $commit $oldcommit`; chomp $mb; $mb eq $oldcommit or reject "not fast forward on dgit branch"; @@ -572,6 +590,7 @@ sub parseargsdispatch () { defined($workrepo = $ENV{'DGIT_DRS_WORK'}) or die; defined($destrepo = $ENV{'DGIT_DRS_DEST'}) or die; defined($keyrings = $ENV{'DGIT_DRS_KEYRINGS'}) or die $!; + defined($policyhook = $ENV{'DGIT_DRS_POLICYHOOK'}) or die $!; open STDOUT, ">&STDERR" or die $!; eval { stunthook(); @@ -587,6 +606,7 @@ sub parseargsdispatch () { $ENV{'DGIT_DRS_SUITES'} = argval(); $ENV{'DGIT_DRS_KEYRINGS'} = argval(); $dgitrepos = argval(); + $ENV{'DGIT_DRS_POLICYHOOK'} = $policyhook = argval(); die unless @ARGV==1 && $ARGV[0] eq '--ssh'; @@ -611,6 +631,17 @@ sub parseargsdispatch () { reject "unknown method" unless $mainfunc; + my ($policy, $pollock) = policyhook(4, 'check-package',$package); + if ($policy & 4) { + my $garbagerepo = "$dgitrepos/_tmp/${package}_garbage"; + acquiretree($garbagerepo,1); + rmtree $garbagerepo; + rename $realdestrepo, $garbagerepo + or $! == ENOENT + or die "rename repo $destrepo to $garbagerepo: $!"; + } + close $pollock or die $!; + if (stat $realdestrepo) { $destrepo = $realdestrepo; } else {