From 78866f6f28ab05eb05d89b5a373f141a0cb7ec7a Mon Sep 17 00:00:00 2001 From: Sitaram Chamarty Date: Fri, 1 Jun 2012 11:47:17 +0530 Subject: [PATCH] (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. --- doc/mirroring.mkd | 25 +++++++++++++++++++++++-- src/commands/mirror | 6 ++++++ src/lib/Gitolite/Triggers/Mirroring.pm | 21 +++++++++++++++++++-- 3 files changed, 48 insertions(+), 4 deletions(-) diff --git a/doc/mirroring.mkd b/doc/mirroring.mkd index 387bbea..9f88f07 100644 --- a/doc/mirroring.mkd +++ b/doc/mirroring.mkd @@ -38,8 +38,29 @@ Gitolite extends this simple notion in the following ways: ## caveats * 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 - must be created on the slave as well, otherwise they will not propagate). + prepared to receive updates from the master. + + 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 gl-perms in the repo directory are not mirrored; you must do that diff --git a/src/commands/mirror b/src/commands/mirror index ec6f275..16c14dd 100755 --- a/src/commands/mirror +++ b/src/commands/mirror @@ -45,6 +45,12 @@ if ( $cmd eq 'push' ) { _chdir( $rc{GL_REPO_BASE} ); _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; for (`git push --mirror $host:$repo 2>&1`) { print STDERR "$_" if -t STDERR or exists $ENV{GL_USER}; diff --git a/src/lib/Gitolite/Triggers/Mirroring.pm b/src/lib/Gitolite/Triggers/Mirroring.pm index 435f8aa..bc38781 100644 --- a/src/lib/Gitolite/Triggers/Mirroring.pm +++ b/src/lib/Gitolite/Triggers/Mirroring.pm @@ -10,11 +10,30 @@ use warnings; my $git_commands = "git-upload-pack|git-receive-pack|git-upload-archive"; my $hn = $rc{HOSTNAME}; +my ( $mode, $master, %slaves, %trusted_slaves ); + # ---------------------------------------------------------------------- sub input { 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" $rc{FROM_SERVER} = $1; trace( 3, "from_server: $1" ); @@ -33,8 +52,6 @@ sub input { # ---------------------------------------------------------------------- -my ( $mode, $master, %slaves, %trusted_slaves ); - sub pre_git { return unless $hn; # nothing, and I mean NOTHING, happens if HOSTNAME is not set