X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=dgit.git;a=blobdiff_plain;f=infra%2Fdgit-repos-server;h=560f1ad3664f0d2134adc003b7a81f00b0a57096;hp=d3d711f178ab99fda55dbe849fd77114f98b6e01;hb=8c6209aa29c81ff6a02d9ab8de50b8392d0610b1;hpb=07bdd0fbd6a2cf1c0b175afe1e075bb566ed1f2c diff --git a/infra/dgit-repos-server b/infra/dgit-repos-server index d3d711f1..560f1ad3 100755 --- a/infra/dgit-repos-server +++ b/infra/dgit-repos-server @@ -2,10 +2,13 @@ # dgit-repos-server # # usages: -# .../dgit-repos-server DISTRO SUITES KEYRING-AUTH-SPEC \ -# DGIT-REPOS-DIR POLICY-HOOK-SCRIPT --ssh -# .../dgit-repos-server DISTRO SUITES KEYRING-AUTH-SPEC \ -# DGIT-REPOS-DIR POLICY-HOOK-SCRIPT --cron +# dgit-repos-server DISTRO DISTRO-DIR AUTH-SPEC [] --ssh +# dgit-repos-server DISTRO DISTRO-DIR AUTH-SPEC [] --cron +# settings +# --repos=GIT-REPOS-DIR default DISTRO-DIR/repos/ +# --suites=SUITES-FILE default DISTRO-DIR/suites +# --policy-hook=POLICY-HOOK default DISTRO-DIR/policy-hook +# (DISTRO-DIR is not used other than as default) # internal usage: # .../dgit-repos-server --pre-receive-hook PACKAGE # @@ -16,7 +19,7 @@ # SUITES is the name of a file which lists the permissible suites # one per line (#-comments and blank lines ignored) # -# KEYRING-AUTH-SPEC is a :-separated list of +# AUTH-SPEC is a :-separated list of # KEYRING.GPG,AUTH-SPEC # where AUTH-SPEC is one of # a @@ -158,7 +161,6 @@ our $package; our $distro; our $suitesfile; our $policyhook; -our $realdestrepo; our $destrepo; our $workrepo; our $keyrings; @@ -174,6 +176,8 @@ sub debug { print DEBUG "$debug @_\n"; } +sub realdestrepo () { "$dgitrepos/$package.git"; } + sub acquirelock ($$) { my ($lock, $must) = @_; my $fh; @@ -212,7 +216,7 @@ sub locksometree ($) { } sub lockrealtree () { - locksometree($realdestrepo); + locksometree(realdestrepo); } sub mkrepotmp () { @@ -284,7 +288,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 @@ -298,7 +302,7 @@ sub movetogarbage () { } rename "$garbagerepo", "$garbagerepo-old" or die "$garbagerepo $!"; } - rename $realdestrepo, $garbagerepo + rename realdestrepo, $garbagerepo or $! == ENOENT or die "$garbagerepo $!"; } @@ -344,7 +348,7 @@ sub dealwithfreshrepo () { } sub maybeinstallprospective () { - return if $destrepo eq $realdestrepo; + return if $destrepo eq realdestrepo; if (open REJ, "<", "$workrepo/drs-error") { local $/ = undef; @@ -388,8 +392,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 $!; } @@ -783,47 +787,19 @@ sub argval () { return $v; } -sub parseargsdispatch () { - die unless @ARGV; +our %indistrodir = ( + # keys are used for DGIT_DRS_XXX too + 'repos' => \$dgitrepos, + 'suites' => \$suitesfile, + 'policy-hook' => \$policyhook, + ); - delete $ENV{'GIT_DIR'}; # if not run via ssh, our parent git process - delete $ENV{'GIT_PREFIX'}; # sets these and they mess things up - - if ($ENV{'DGIT_DRS_DEBUG'}) { - $debug='='; - open DEBUG, ">&STDERR" or die $!; - } - - if ($ARGV[0] eq '--pre-receive-hook') { - if ($debug) { $debug.="="; } - shift @ARGV; - @ARGV == 1 or die; - $package = shift @ARGV; - defined($distro = $ENV{'DGIT_DRS_DISTRO'}) or die; - defined($dgitrepos = $ENV{'DGIT_DRS_REPOS'}) or die; - defined($suitesfile = $ENV{'DGIT_DRS_SUITES'}) or die; - 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(); - }; - if ($@) { - recorderror "$@" or die; - die $@; - } - exit 0; - } +our @hookenvs = qw(distro suitesfile policyhook keyrings dgitrepos); - $ENV{'DGIT_DRS_DISTRO'} = $distro = argval(); - $ENV{'DGIT_DRS_SUITES'} = $suitesfile = argval(); - $ENV{'DGIT_DRS_KEYRINGS'} = $keyrings = argval(); - $ENV{'DGIT_DRS_REPOS'} = $dgitrepos = argval(); - $ENV{'DGIT_DRS_POLICYHOOK'} = $policyhook = argval(); +# workrepo and destrepo handled ad-hoc - die unless @ARGV==1 && $ARGV[0] eq '--ssh'; +sub mode_ssh () { + die if @ARGV; my $cmd = $ENV{'SSH_ORIGINAL_COMMAND'}; $cmd =~ m{ @@ -838,7 +814,6 @@ sub parseargsdispatch () { or reject "command string not understood"; my $method = $1; $package = $2; - $realdestrepo = "$dgitrepos/$package.git"; my $funcn = $method; $funcn =~ y/-/_/; @@ -855,8 +830,8 @@ sub parseargsdispatch () { close $lfh; - if (stat_exists $realdestrepo) { - $destrepo = $realdestrepo; + if (stat_exists realdestrepo) { + $destrepo = realdestrepo; } else { debug " fixmissing $funcn"; my $fixfunc = $main::{"fixmissing__$funcn"}; @@ -867,6 +842,60 @@ sub parseargsdispatch () { &$mainfunc; } +sub parseargsdispatch () { + die unless @ARGV; + + delete $ENV{'GIT_DIR'}; # if not run via ssh, our parent git process + delete $ENV{'GIT_PREFIX'}; # sets these and they mess things up + + if ($ENV{'DGIT_DRS_DEBUG'}) { + $debug='='; + open DEBUG, ">&STDERR" or die $!; + } + + if ($ARGV[0] eq '--pre-receive-hook') { + if ($debug) { $debug.="="; } + shift @ARGV; + @ARGV == 1 or die; + $package = shift @ARGV; + ${ $main::{$_} } = $ENV{"DGIT_DRS_\U$_"} foreach @hookenvs; + defined($workrepo = $ENV{'DGIT_DRS_WORK'}) or die; + defined($destrepo = $ENV{'DGIT_DRS_DEST'}) or die; + open STDOUT, ">&STDERR" or die $!; + eval { + stunthook(); + }; + if ($@) { + recorderror "$@" or die; + die $@; + } + exit 0; + } + + $distro = $ENV{'DGIT_DRS_DISTRO'} = argval(); + my $distrodir = argval(); + $keyrings = $ENV{'DGIT_DRS_KEYRINGS'} = argval(); + + foreach my $dk (keys %indistrodir) { + ${ $indistrodir{$dk} } = "$distrodir/$dk"; + } + + while (@ARGV && $ARGV[0] =~ m/^--([-0-9a-z]+)=/ && $indistrodir{$1}) { + ${ $indistrodir{$1} } = $'; #'; + shift @ARGV; + } + + $ENV{"DGIT_DRS_\U$_"} = ${ $main::{$_} } foreach @hookenvs; + + die unless @ARGV==1; + + my $mode = shift @ARGV; + die unless $mode =~ m/^--(\w+)$/; + my $fn = ${*::}{"mode_$1"}; + die unless $fn; + $fn->(); +} + sub unlockall () { while (my $fh = pop @lockfhs) { close $fh; } }