# --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
#
# 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 [...]
#
# 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)
# 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);
our $suitesfile;
our $suitesformasterfile;
our $policyhook;
+our $mirrorhook;
our $dgitlive;
our $distrodir;
our $destrepo;
# => ($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"
$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;
runcmd qw(git receive-pack), $workrepo;
dealwithfreshrepo();
maybeinstallprospective();
+ mirrorhook('updated-hook', $package);
}
#----- stunt post-receive hook -----
'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