(experimental code) push wild repos across a master slave connection

It creates the repo on the remote side (getting the creator name from
the gl-creator file and sending it across), as well as sending gl-perms
on subsequent connections.

This has only been minimally tested.  E.g., complex setups or asymmetric
configs on master and slave, etc. have NOT been tested.

This has also not been tested with redirected pushes.
This commit is contained in:
Sitaram Chamarty 2012-06-01 11:47:17 +05:30
parent 42e0bac48c
commit 78866f6f28
3 changed files with 48 additions and 4 deletions

View file

@ -38,8 +38,29 @@ Gitolite extends this simple notion in the following ways:
## caveats ## caveats
* Mirroring will never *create* a repo on a slave; it has to exist and be * Mirroring will never *create* a repo on a slave; it has to exist and be
prepared to receive updates from the master. (For example, [wild][] repos prepared to receive updates from the master.
must be created on the slave as well, otherwise they will not propagate).
However, there is limited support for auto-creating wild card repos and
sending 'perms' info across, with the following caveats at present:
* This has only been minimally tested. For example, complex setups or
asymmetric configs on master and slave, etc. have NOT been tested.
* This has also not been tested with redirected pushes. It may not
work.
* As with lots of extra features in gitolite, smart http support is not
on my radar. Don't ask.
* If you change permissions using the 'perms' command, they will only go
across on the next push. Or, if you know the name of the slave
server, you can run
ssh git@host mirror push slave-server-name repo-name
Please test it out and let me know if something surprising happens. Be
aware that I have been known to claim bugs are features if I don't have
time to fix them immediately :-)
* Mirroring is only for git repos. Ancillary files like gl-creator and * Mirroring is only for git repos. Ancillary files like gl-creator and
gl-perms in the repo directory are not mirrored; you must do that gl-perms in the repo directory are not mirrored; you must do that

View file

@ -45,6 +45,12 @@ if ( $cmd eq 'push' ) {
_chdir( $rc{GL_REPO_BASE} ); _chdir( $rc{GL_REPO_BASE} );
_chdir("$repo.git"); _chdir("$repo.git");
if (-f "gl-creator") {
# try to propagate the wild repo, including creator name and gl-perms
my $creator = `cat gl-creator`; chomp($creator);
trace(1, `cat gl-perms 2>/dev/null | ssh $host CREATOR=$creator perms -c \\'$repo\\'`);
}
my $errors = 0; my $errors = 0;
for (`git push --mirror $host:$repo 2>&1`) { for (`git push --mirror $host:$repo 2>&1`) {
print STDERR "$_" if -t STDERR or exists $ENV{GL_USER}; print STDERR "$_" if -t STDERR or exists $ENV{GL_USER};

View file

@ -10,11 +10,30 @@ use warnings;
my $git_commands = "git-upload-pack|git-receive-pack|git-upload-archive"; my $git_commands = "git-upload-pack|git-receive-pack|git-upload-archive";
my $hn = $rc{HOSTNAME}; my $hn = $rc{HOSTNAME};
my ( $mode, $master, %slaves, %trusted_slaves );
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
sub input { sub input {
return unless $ARGV[0] =~ /^server-(\S+)$/; return unless $ARGV[0] =~ /^server-(\S+)$/;
# custom peer-to-peer commands. At present the only one is 'perms -c',
# sent from a mirror command
if ($ENV{SSH_ORIGINAL_COMMAND} =~ /^CREATOR=(\S+) perms -c '(\S+)'$/) {
$ENV{GL_USER} = $1;
my $repo = $2;
details($repo);
_die "$hn: '$repo' is local" if $mode eq 'local';
_die "$hn: '$repo' is native" if $mode eq 'master';
# this expects valid perms content on STDIN
_system("gitolite perms -c $repo");
# we're done. Yes, really...
exit 0;
}
# note: we treat %rc as our own internal "poor man's %ENV" # note: we treat %rc as our own internal "poor man's %ENV"
$rc{FROM_SERVER} = $1; $rc{FROM_SERVER} = $1;
trace( 3, "from_server: $1" ); trace( 3, "from_server: $1" );
@ -33,8 +52,6 @@ sub input {
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
my ( $mode, $master, %slaves, %trusted_slaves );
sub pre_git { sub pre_git {
return unless $hn; return unless $hn;
# nothing, and I mean NOTHING, happens if HOSTNAME is not set # nothing, and I mean NOTHING, happens if HOSTNAME is not set