summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Jackson <ijackson@chiark.greenend.org.uk>2015-07-08 18:21:38 +0100
committerIan Jackson <ijackson@chiark.greenend.org.uk>2015-07-11 14:23:15 +0100
commit7c3fe2d148ebb06f84cf1ec6ecbe5d441c91427e (patch)
tree483d78a7cdc8b9cc48098641e1cbb70dc5da460a
parent8cba3f92026d48c5792f64ed996f9aab942cc9e6 (diff)
Mirroring: Run mirror hook script, if one is provided
-rwxr-xr-xinfra/dgit-repos-server46
1 files changed, 40 insertions, 6 deletions
diff --git a/infra/dgit-repos-server b/infra/dgit-repos-server
index 1be6e78..92f197b 100755
--- a/infra/dgit-repos-server
+++ b/infra/dgit-repos-server
@@ -9,8 +9,10 @@
# --suites=SUITES-FILE default DISTRO-DIR/suites
# --suites-master=SUITES-FILE default DISTRO-DIR/suites-master
# --policy-hook=POLICY-HOOK default DISTRO-DIR/policy-hook
+# --mirror-hook=MIRROR-HOOK default DISTRO-DIR/mirror-hook
# --dgit-live=DGIT-LIVE-DIR default DISTRO-DIR/dgit-live
-# (DISTRO-DIR is not used other than as default and to pass to policy hook)
+# (DISTRO-DIR is not used other than as default and to pass to policy
+# and mirror hooks)
# internal usage:
# .../dgit-repos-server --pre-receive-hook PACKAGE
#
@@ -119,7 +121,7 @@ $SIG{__WARN__} = sub { die $_[0]; };
# a stampfile whose presence indicates that there may be
# cleanup to do
#
-# Policy hook script is invoked like this:
+# Policy hook scripts are invoked like this:
# POLICY-HOOK-SCRIPT DISTRO DGIT-REPOS-DIR DGIT-LIVE-DIR DISTRO-DIR ACTION...
# ie.
# POLICY-HOOK-SCRIPT ... check-list [...]
@@ -131,7 +133,8 @@ $SIG{__WARN__} = sub { die $_[0]; };
#
# DELIBERATELIES is like this: --deliberately-foo,--deliberately-bar,...
#
-# Exit status is a bitmask. Bit weight constants are defined in Dgit.pm.
+# Exit status of policy hook is a bitmask.
+# Bit weight constants are defined in Dgit.pm.
# NOFFCHECK (2)
# suppress dgit-repos-server's fast-forward check ("push" only)
# FRESHREPO (4)
@@ -168,7 +171,18 @@ $SIG{__WARN__} = sub { die $_[0]; };
# If policy hook wants to run dgit (or something else in the dgit
# package), it should use DGIT-LIVE-DIR/dgit (etc.), or if that is
# ENOENT, use the installed version.
-
+#
+# Mirror hook scripts are invoked like this:
+# MIRROR-HOOK-SCRIPT DISTRO-DIR ACTION...
+# and currently there is only one action invoked by dgit-repos-server:
+# MIRROR-HOOK-SCRIPT DISTRO-DIR updated-hook PACKAGE [...]
+#
+# Exit status of the mirror hook is advisory only. The mirror hook
+# runs too late to do anything useful about a problem, so the only
+# effect of a mirror hook exiting nonzero is a warning message to
+# stderr (which the pushing user should end up seeing).
+#
+# If the mirror hook does not exist, it is silently skipped.
use POSIX;
use Fcntl qw(:flock);
@@ -186,6 +200,7 @@ our $distro;
our $suitesfile;
our $suitesformasterfile;
our $policyhook;
+our $mirrorhook;
our $dgitlive;
our $distrodir;
our $destrepo;
@@ -278,7 +293,7 @@ sub policyhook {
# => ($exitstatuspolicybitmap);
die if $policyallowbits & ~0x3e;
my @cmd = ($policyhook,$distro,$dgitrepos,$dgitlive,$distrodir,@polargs);
- debugcmd '+',@cmd;
+ debugcmd '+M',@cmd;
my $r = system @cmd;
die "system: $!" if $r < 0;
die "dgit-repos-server: policy hook failed (or rejected) ($?)\n"
@@ -390,6 +405,23 @@ sub dealwithfreshrepo () {
$destrepo = $freshrepo;
}
+sub mirrorhook {
+ my @cmd = ($mirrorhook,$distrodir,@_);
+ debugcmd '+',@cmd;
+ return unless stat_exists $mirrorhook;
+ my $r = system @cmd;
+ if ($r) {
+ printf STDERR <<END,
+dgit-repos-server: warning: mirror hook failed: %s
+dgit-repos-server: push complete but may not fully visible.
+END
+ ($r < 0 ? "exec: $!" :
+ $r == (124 << 8) ? "exited status 124 (timeout?)" :
+ !($r & ~0xff00) ? "exited ".($? >> 8) :
+ "wait status $?");
+ }
+}
+
sub maybeinstallprospective () {
return if $destrepo eq realdestrepo;
@@ -447,6 +479,7 @@ sub main__git_receive_pack () {
runcmd qw(git receive-pack), $workrepo;
dealwithfreshrepo();
maybeinstallprospective();
+ mirrorhook('updated-hook', $package);
}
#----- stunt post-receive hook -----
@@ -928,11 +961,12 @@ our %indistrodir = (
'suites' => \$suitesfile,
'suites-master' => \$suitesformasterfile,
'policy-hook' => \$policyhook,
+ 'mirror-hook' => \$mirrorhook,
'dgit-live' => \$dgitlive,
);
our @hookenvs = qw(distro suitesfile suitesformasterfile policyhook
- dgitlive keyrings dgitrepos distrodir);
+ mirrorhook dgitlive keyrings dgitrepos distrodir);
# workrepo and destrepo handled ad-hoc