X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=dgit.git;a=blobdiff_plain;f=infra%2Fdgit-repos-server;h=3f9298f2aa3bc61f645235e72c28e813b9b97fcf;hp=98ec16d9b4e382540ffd6ec59a07f307be5d5446;hb=2965f30cca23b1cb7c1cf1d764b4f6b571f0a78e;hpb=8a2c3aa997480f715f703b01be7568038eb82fd8 diff --git a/infra/dgit-repos-server b/infra/dgit-repos-server index 98ec16d9..3f9298f2 100755 --- a/infra/dgit-repos-server +++ b/infra/dgit-repos-server @@ -8,6 +8,7 @@ # --repos=GIT-REPOS-DIR default DISTRO-DIR/repos/ # --suites=SUITES-FILE default DISTRO-DIR/suites # --policy-hook=POLICY-HOOK default DISTRO-DIR/policy-hook +# --dgit-live=DGIT-LIVE-DIR default DISTRO-DIR/dgit-live # (DISTRO-DIR is not used other than as default) # internal usage: # .../dgit-repos-server --pre-receive-hook PACKAGE @@ -26,6 +27,7 @@ # mDM.TXT use strict; +$SIG{__WARN__} = sub { die $_[0]; }; # DGIT-REPOS-DIR contains: # git tree (or other object) lock (in acquisition order, outer first) @@ -114,12 +116,14 @@ use strict; # cleanup to do # # Policy hook script is invoked like this: -# POLICY-HOOK-SCRIPT DISTRO DGIT-REPOS-DIR ACTION... +# POLICY-HOOK-SCRIPT DISTRO DGIT-REPOS-DIR DGIT-LIVE-DIR ACTION... # ie. # POLICY-HOOK-SCRIPT ... check-list [...] # POLICY-HOOK-SCRIPT ... check-package PACKAGE [...] -# POLICY-HOOK-SCRIPT ... push|push-confirm PACKAGE \ +# POLICY-HOOK-SCRIPT ... push PACKAGE \ # VERSION SUITE TAGNAME DELIBERATELIES [...] +# POLICY-HOOK-SCRIPT ... push-confirm PACKAGE \ +# VERSION SUITE TAGNAME DELIBERATELIES FRESH-REPO|'' [...] # # Exit status is a bitmask. Bit weight constants are defined in Dgit.pm. # NOFFCHECK (2) @@ -136,7 +140,14 @@ use strict; # to-be-pushed objects have been received; TAGNAME is the # version-based tag # +# FRESH-REPO is '' iff the repo for this package already existed, or +# the pathname of the newly-created repo which will be renamed into +# place if everything goes well. (NB that this is generally not the +# same repo as the cwd, because the objects are first received into a +# temporary repo so they can be examined.) +# # if push requested FRESHREPO, push-confirm happens in said fresh repo +# and FRESH-REPO is guaranteed not to be ''. # # policy hook for a particular package will be invoked only once at # a time - (see comments about DGIT-REPOS-DIR, above) @@ -145,6 +156,9 @@ use strict; # First, without any locking, check-list is called. It should produce # a list of package names. Then check-package will be invoked for # each named package, in each case after taking an appropriate lock. +# +# If policy hook wants to run dgit (or something else in the dgit +# package), it should use DGIT-LIVE-DIR/dgit (etc.) use POSIX; @@ -161,7 +175,7 @@ our $package; our $distro; our $suitesfile; our $policyhook; -our $realdestrepo; +our $dgitlive; our $destrepo; our $workrepo; our $keyrings; @@ -177,6 +191,8 @@ sub debug { print DEBUG "$debug @_\n"; } +sub realdestrepo () { "$dgitrepos/$package.git"; } + sub acquirelock ($$) { my ($lock, $must) = @_; my $fh; @@ -215,7 +231,7 @@ sub locksometree ($) { } sub lockrealtree () { - locksometree($realdestrepo); + locksometree(realdestrepo); } sub mkrepotmp () { @@ -264,11 +280,12 @@ sub policyhook { my ($policyallowbits, @polargs) = @_; # => ($exitstatuspolicybitmap); die if $policyallowbits & ~0x3e; - my @cmd = ($policyhook,$distro,$dgitrepos,@polargs); + my @cmd = ($policyhook,$distro,$dgitrepos,$dgitlive,@polargs); debugcmd @cmd; my $r = system @cmd; die "system: $!" if $r < 0; die "hook (@cmd) failed ($?)" if $r & ~($policyallowbits << 8); + debug sprintf "hook (%s) => %#x", "@polargs", $r; return $r >> 8; } @@ -287,7 +304,7 @@ sub mkrepo_fromtemplate ($) { } sub movetogarbage () { - # $realdestrepo must have been locked + # realdestrepo must have been locked my $garbagerepo = "$dgitrepos/${package}_garbage"; # We arrange to always keep at least one old tree, for anti-rewind # purposes (and, I guess, recovery from mistakes). This is either @@ -301,7 +318,7 @@ sub movetogarbage () { } rename "$garbagerepo", "$garbagerepo-old" or die "$garbagerepo $!"; } - rename $realdestrepo, $garbagerepo + rename realdestrepo, $garbagerepo or $! == ENOENT or die "$garbagerepo $!"; } @@ -347,7 +364,7 @@ sub dealwithfreshrepo () { } sub maybeinstallprospective () { - return if $destrepo eq $realdestrepo; + return if $destrepo eq realdestrepo; if (open REJ, "<", "$workrepo/drs-error") { local $/ = undef; @@ -391,8 +408,8 @@ sub maybeinstallprospective () { movetogarbage; } - debug "install $destrepo => $realdestrepo"; - rename $destrepo, $realdestrepo or die $!; + debug "install $destrepo => ".realdestrepo; + rename $destrepo, realdestrepo or die $!; remove "$destrepo.lock" or die $!; } @@ -731,7 +748,8 @@ sub checks () { mkrepo_fromtemplate $destrepo; } - policyhook(0, 'push-confirm', @policy_args); + my $willinstall = ($destrepo eq realdestrepo ? '' : $destrepo); + policyhook(0, 'push-confirm', @policy_args, $willinstall); } sub onwardpush () { @@ -791,9 +809,10 @@ our %indistrodir = ( 'repos' => \$dgitrepos, 'suites' => \$suitesfile, 'policy-hook' => \$policyhook, + 'dgit-live' => \$dgitlive, ); -our @hookenvs = qw(distro suitesfile policyhook keyrings dgitrepos); +our @hookenvs = qw(distro suitesfile policyhook dgitlive keyrings dgitrepos); # workrepo and destrepo handled ad-hoc @@ -813,7 +832,6 @@ sub mode_ssh () { or reject "command string not understood"; my $method = $1; $package = $2; - $realdestrepo = "$dgitrepos/$package.git"; my $funcn = $method; $funcn =~ y/-/_/; @@ -830,8 +848,8 @@ sub mode_ssh () { close $lfh; - if (stat_exists $realdestrepo) { - $destrepo = $realdestrepo; + if (stat_exists realdestrepo) { + $destrepo = realdestrepo; } else { debug " fixmissing $funcn"; my $fixfunc = $main::{"fixmissing__$funcn"};