diff options
-rwxr-xr-x | install | 13 | ||||
-rwxr-xr-x | src/VREF/MAX_NEWBIN_SIZE | 2 | ||||
-rwxr-xr-x | src/commands/config | 19 | ||||
-rw-r--r-- | src/lib/Gitolite/Common.pm | 2 | ||||
-rw-r--r-- | src/lib/Gitolite/Conf/Load.pm | 9 | ||||
-rw-r--r-- | src/lib/Gitolite/Triggers/RepoUmask.pm | 4 | ||||
-rwxr-xr-x | src/triggers/repo-specific-hooks | 18 | ||||
-rw-r--r-- | t/README | 108 | ||||
-rwxr-xr-x | t/fedora-root-smart-http-test-setup | 95 | ||||
-rwxr-xr-x | t/git-config.t | 1 | ||||
-rwxr-xr-x | t/manjaro-root-smart-http-test-setup | 114 | ||||
-rwxr-xr-x | t/smart-http | 2 |
12 files changed, 366 insertions, 21 deletions
@@ -7,6 +7,7 @@ use warnings; use Getopt::Long; use FindBin; +use Config; # meant to be run from the root of the gitolite tree, one level above 'src' BEGIN { $ENV{GL_BINDIR} = $FindBin::RealBin . "/src"; } @@ -34,6 +35,12 @@ Usage (from gitolite clone directory): Please provide a full path, not a relative path. + <perl-executable> ./install -to <dir> + to copy the entire 'src' directory to <dir>, but will replace + all of the shebangs with the path to <perl-executable>. This + is a way to force gitolite to use some perl that is not + installed at /usr/bin/perl. + Simplest use, if $HOME/bin exists and is in $PATH, is: git clone https://github.com/sitaramc/gitolite @@ -76,6 +83,12 @@ if ($to) { _mkdir($to); system("cp -RpP * $to"); _print( "$to/VERSION", $version ); + + # Replace shebangs if necessary. + my $thisperl = $Config{perlpath}; + if ($thisperl ne '/usr/bin/perl') { + system("cd $to; grep -r -l /usr/bin/perl | xargs perl -pi -e 's(^#!/usr/bin/perl)(#!$thisperl)'"); + } } elsif ($ln) { ln_sf( $ENV{GL_BINDIR}, "gitolite", $ln ); _print( "VERSION", $version ); diff --git a/src/VREF/MAX_NEWBIN_SIZE b/src/VREF/MAX_NEWBIN_SIZE index 84a9efa..99d51d3 100755 --- a/src/VREF/MAX_NEWBIN_SIZE +++ b/src/VREF/MAX_NEWBIN_SIZE @@ -21,6 +21,8 @@ die "not meant to be run manually" unless $ARGV[7]; my ( $newsha, $oldtree, $newtree, $refex, $max ) = @ARGV[ 2, 3, 4, 6, 7 ]; +exit 0 if $newsha eq '0000000000000000000000000000000000000000'; + # / (.*) +\| Bin 0 -> (\d+) bytes/ chomp( my $author_email = `git log --format=%ae -1 $newsha` ); diff --git a/src/commands/config b/src/commands/config index 7851c11..214158b 100755 --- a/src/commands/config +++ b/src/commands/config @@ -63,8 +63,8 @@ usage() if not @ARGV or $ARGV[0] eq '-h'; my $repo = shift; -my ($op, $key, $val) = @ARGV; -usage() unless $op and exists $nargs{$op} and @ARGV == $nargs{$op}; +my $op = shift; +usage() unless $op and exists $nargs{$op}; # ---------------------------------------------------------------------- # authorisation checks @@ -81,15 +81,30 @@ die "sorry, you are not authorised\n" unless # key validity checks unless ($op eq '--list') { + my $key = shift; + + my $val = ''; + $val = join(" ", @ARGV) if @ARGV; + # values with spaces embedded get flattened by sshd when it passes + # SSH_ORIGINAL_COMMAND to gitolite. In this specific instance, we will + # pretend we know what the user meant, and join up the last 1+ args into + # one space-separated arg. + my $user_configs = option( $repo, 'user-configs' ); # this is a space separated list of allowed config keys my @validkeys = split( ' ', ( $user_configs || '' ) ); my @matched = grep { $key =~ /^$_$/i } @validkeys; _die "config '$key' not allowed\n" if ( @matched < 1 ); + + @ARGV = ($key); + push @ARGV, $val if $val; } # ---------------------------------------------------------------------- # go! +unshift @ARGV, $op; +usage() unless @ARGV == $nargs{$op}; + _chdir("$rc{GL_REPO_BASE}/$repo.git"); _system( "git", "config", @ARGV ); diff --git a/src/lib/Gitolite/Common.pm b/src/lib/Gitolite/Common.pm index af9c875..b06f967 100644 --- a/src/lib/Gitolite/Common.pm +++ b/src/lib/Gitolite/Common.pm @@ -361,7 +361,7 @@ sub ssh_fingerprint_file { my $in = shift; -f $in or die "file not found: $in\n"; my $fh; - open( $fh, "ssh-keygen -l -f $in |" ) or die "could not fork: $!\n"; + open( $fh, "ssh-keygen -l -f $in 2>&1 |" ) or die "could not fork: $!\n"; my $output = <$fh>; chomp $output; # dbg("fp = $fp"); diff --git a/src/lib/Gitolite/Conf/Load.pm b/src/lib/Gitolite/Conf/Load.pm index 8abd386..57d1396 100644 --- a/src/lib/Gitolite/Conf/Load.pm +++ b/src/lib/Gitolite/Conf/Load.pm @@ -436,9 +436,12 @@ sub memberships { push @ret, @{ $groups{$base} } if exists $groups{$base}; push @ret, @{ $groups{$base2} } if $base2 and exists $groups{$base2}; - for my $i ( keys %{ $patterns{groups} } ) { - if ( $base =~ /^$i$/ or $base2 and ( $base2 =~ /^$i$/ ) ) { - push @ret, @{ $groups{$i} }; + if ($type eq 'repo') { + # regexes can only be used for repos, not for users + for my $i ( keys %{ $patterns{groups} } ) { + if ( $base =~ /^$i$/ or $base2 and ( $base2 =~ /^$i$/ ) ) { + push @ret, @{ $groups{$i} }; + } } } diff --git a/src/lib/Gitolite/Triggers/RepoUmask.pm b/src/lib/Gitolite/Triggers/RepoUmask.pm index 109cb31..276cd01 100644 --- a/src/lib/Gitolite/Triggers/RepoUmask.pm +++ b/src/lib/Gitolite/Triggers/RepoUmask.pm @@ -23,6 +23,10 @@ use warnings; option umask = 0027 + * Anytime you add or change the value, if there are existing repos that + would be affected, you will need to do a manual "chmod" adjustment, + because umask only affects newly created files. + =cut # sadly option/config values are not available at pre_create time for normal diff --git a/src/triggers/repo-specific-hooks b/src/triggers/repo-specific-hooks index 7c16f2f..4044cc9 100755 --- a/src/triggers/repo-specific-hooks +++ b/src/triggers/repo-specific-hooks @@ -42,19 +42,17 @@ while (<>) { my @codes = split /\s+/, $codes; - # check for disallowed hook types only if @codes is non-empty - if (@codes) { - # this is a special case - if ( $repo eq 'gitolite-admin' and $hook eq 'post-update' ) { - _warn "repo-specific-hooks: ignoring attempts to set post-update hook for the admin repo"; - next; - } - - unless ( $hook =~ /^(pre-receive|post-receive|post-update|pre-auto-gc)$/ ) { + # bail on disallowed hook types (but warn only if @codes is non-empty) + if ( $repo eq 'gitolite-admin' and $hook eq 'post-update' ) { + _warn "repo-specific-hooks: ignoring attempts to set post-update hook for the admin repo" if @codes; + next; + } + unless ( $hook =~ /^(pre-receive|post-receive|post-update|pre-auto-gc)$/ ) { + if (@codes) { _warn "repo-specific-hooks: '$hook' is not allowed, ignoring"; _warn " (only pre-receive, post-receive, post-update, and pre-auto-gc are allowed)"; - next; } + next; } push @{ $repo_hooks{$repo}{$hook} }, @codes; @@ -1,7 +1,26 @@ +# instructions for running the tests -============================================ -WARNING: THE TEST SUITE DELETES STUFF FIRST! -============================================ +# Pre-requisites + +Install the following packages: + +* Manjaro (and probably Arch): + + pacman -S perl-json perl-json-xs apache + +* Fedora (and probably CentOS): + + dnf install -y perl-Test-Harness perl-JSON perl-JSON-XS httpd httpd-tools + +* others: + + (TBD) + +# RUNNING THE MAIN TEST SUITE + + ====================================== + WARNING: THE TEST SUITE DELETES STUFF! + ====================================== Please run the tests ONLY on a userid where it's ok to LOSE DATA. @@ -12,3 +31,86 @@ On such a userid, clone gitolite then run this command in the clone: http://gitolite.com/gitolite/testing.html has more details. Alternatively, http://gitolite.com/gitolite/req.html#trying will help you try out gitolite if you want to play with gitolite safely. + +# RUNNING THE HTTP AND MIRROR TESTS + + ====================================== + WARNING: THE TEST SUITE DELETES STUFF! + ====================================== + +The http and mirror tests require a lot more preparation, including commands +and/or scripts to be run as root, so they're not invoked when you simply run +"prove" as above. + +## Manjaro + +1. Create 3 users: sam, frodo, and gollum (`useradd -m`). + +2. Assuming you're running the tests using a local user called `g3`, run + `visudo` and add the following line: + + g3 ALL = (sam,frodo,gollum) NOPASSWD: ALL + + Test this by running this command from within `g3` and making sure you get + the correct results: + + sudo -u sam -i pwd + # should print /home/sam + # similarly make sure frodo and gollum also give correct results + + The mirror test will not run if this does not work. That does not mean + *mirroring* will not work; only the test suite depends on this feature. + +3. Manjaro does not, by default, add $HOME/bin to $PATH, so you will need the + following on at least sam, frodo, and gollum: + + # copy-paste this into a root terminal + for u in frodo sam gollum; do + grep '$HOME/bin' /home/$u/.bash_profile || echo 'export PATH="$HOME/bin:$PATH"' >> /home/$u/.bash_profile + done + + Again, test this by running: + + sudo -u sam -i echo '$PATH' + + and making sure the output starts with `/home/sam/bin:` (and similarly for + frodo and gollum). + +4. Take a look inside `t/manjaro-root-smart-http-test-setup` to make sure + everything looks sane (because you have to run it as root!!), then run it + as root. + +5. Now you are ready to run the last two tests: + + GITOLITE_TEST=y prove t/smart-http + GITOLITE_TEST=y prove t/mirror-test + +## Fedora + +1. Create 3 users: sam, frodo, and gollum (`useradd`). + +2. Assuming you're running the tests using a local user called `g3`, run + `visudo` and add the following line: + + g3 ALL = (sam,frodo,gollum) NOPASSWD: ALL + + Test this by running this command from within `g3` and making sure you get + the correct results: + + sudo -u sam -i pwd + # should print /home/sam + # similarly make sure frodo and gollum also give correct results + + The mirror test will not run if this does not work. That does not mean + *mirroring* will not work; only the test suite depends on this feature. + +3. Take a look inside `t/fedora-root-smart-http-test-setup` to make sure + everything looks sane (because you have to run it as root!!), then run it + as root. + +4. Now you are ready to run the last two tests: + + prove t/smart-http + prove t/mirror-test + +vim: ft=markdown diff --git a/t/fedora-root-smart-http-test-setup b/t/fedora-root-smart-http-test-setup new file mode 100755 index 0000000..869d13d --- /dev/null +++ b/t/fedora-root-smart-http-test-setup @@ -0,0 +1,95 @@ +#!/bin/bash + +# gitolite http mode TESTING setup for Fedora +# - Probably works for CentOS also; if someone tests it let me know +# - Use the comments to create a version for your distro if needed + +# CAUTION: This script needs to be run as root, so you best eyeball it at +# least once to make sure you know what changes it is making. + +# WARNING: clobbers /usr/share/httpd/gitolite-home, and also creates 7 http +# users with trivial passwords FOR TESTING. + +# HOWEVER: if you remove some of that, especially the part that creates test +# users, this *should* work as a quick "setup gitolite http mode" script. + +# CAUTION: This script assumes the httpd.conf file is pretty much the default +# "as shipped" version. If you fiddled with it, this script *may* break. +# It's on you to determine if that is the case and manually simulate the +# actions of this script. It's not that hard, and anyway it's just once (for +# a given server) so it's not too bad. + +# ---------------------------------------------------------------------- + +cd ~apache +# should be /usr/share/httpd; you may want to check just to be safe +export GITOLITE_HTTP_HOME=$PWD/gitolite-home + +[[ -d gitolite-home ]] && { + [[ $GITOLITE_TEST != y ]] && { + echo "If you're OK with clobbering $GITOLITE_HTTP_HOME, please rerun with +environment variable GITOLITE_TEST set to 'y'." + exit 1; + } +} + +rm -rf gitolite-home +mkdir gitolite-home + +# setup apache conf for gitolite +cd /etc/httpd/conf.d +[[ -f gitolite.conf ]] || { + cat > gitolite.conf <<-EOF + SetEnv GIT_PROJECT_ROOT $GITOLITE_HTTP_HOME/repositories + ScriptAlias /git/ $GITOLITE_HTTP_HOME/gitolite-source/src/gitolite-shell/ + ScriptAlias /gitmob/ $GITOLITE_HTTP_HOME/gitolite-source/src/gitolite-shell/ + SetEnv GITOLITE_HTTP_HOME $GITOLITE_HTTP_HOME + SetEnv GIT_HTTP_EXPORT_ALL + + <Location /git> + AuthType Basic + AuthName "Private Git Access" + Require valid-user + AuthUserFile $GITOLITE_HTTP_HOME/gitolite-http-authuserfile + </Location> + EOF +} + +# get the gitolite sources +cd $GITOLITE_HTTP_HOME + +if [[ -d /tmp/gitolite.git ]]; then + git clone /tmp/gitolite.git gitolite-source + # I do this because I have to test stuff *before* it gets to github, so I + # can't simply clone what's on github. Instead, I use a local + # world-readable bare repo cloned from my dev environment. +else + git clone 'https://github.com/sitaramc/gitolite' gitolite-source +fi + +# make the bin directory, and add it to PATH +cd gitolite-source +mkdir $GITOLITE_HTTP_HOME/bin +./install -ln $GITOLITE_HTTP_HOME/bin +export PATH=$PATH:$GITOLITE_HTTP_HOME/bin + +# come back to base, then run setup. Notice that you have to point HOME to +# the right place, even if it is just for this command +cd $GITOLITE_HTTP_HOME +HOME=$GITOLITE_HTTP_HOME gitolite setup -a admin + +# insert some essential lines at the beginning of the rc file +echo '$ENV{PATH} .= ":$ENV{GITOLITE_HTTP_HOME}/bin";' > 1 +echo >> 1 +cat .gitolite.rc >> 1 +\mv 1 .gitolite.rc + +# create users "admin" and "u1" thru "u6" for testing +htpasswd -bc $GITOLITE_HTTP_HOME/gitolite-http-authuserfile admin admin +seq 6 | xargs -I % htpasswd -b $GITOLITE_HTTP_HOME/gitolite-http-authuserfile u% u% + +# fix up ownership +chown -R apache:apache $GITOLITE_HTTP_HOME + +# restart httpd to make it pick up all the new stuff +systemctl restart httpd diff --git a/t/git-config.t b/t/git-config.t index 86a3a7b..fb5097e 100755 --- a/t/git-config.t +++ b/t/git-config.t @@ -137,7 +137,6 @@ try " $t = join("\n", sort (lines())); cmp $t, 'bar.git/config: bare = true -bar.git/config:[foo] foo.git/config: bar = f1 foo.git/config: bare = true foo.git/config:[foo] diff --git a/t/manjaro-root-smart-http-test-setup b/t/manjaro-root-smart-http-test-setup new file mode 100755 index 0000000..f254b55 --- /dev/null +++ b/t/manjaro-root-smart-http-test-setup @@ -0,0 +1,114 @@ +#!/bin/bash + +# gitolite http mode TESTING setup for Manjaro +# - Probably works for Arch also; if someone tests it let me know +# - Use the comments to create a version for your distro if needed + +# CAUTION: This script needs to be run as root, so you best eyeball it at +# least once to make sure you know what changes it is making. + +# WARNING: clobbers /srv/http/gitolite-home, and also creates 7 http +# users with trivial passwords FOR TESTING. + +# HOWEVER: if you remove some of that, especially the part that creates test +# users, this *should* work as a quick "setup gitolite http mode" script. + +# CAUTION: This script assumes the httpd.conf file is pretty much the default +# "as shipped" version. If you fiddled with it, this script *may* break. +# It's on you to determine if that is the case and manually simulate the +# actions of this script. It's not that hard, and anyway it's just once (for +# a given server) so it's not too bad. + +# ---------------------------------------------------------------------- +# BEGIN APACHE CONF CHANGES + +# Unlike Fedora, Manjaro's default httpd.conf does not contain a wildcard +# include for stuff in conf.d; they're all explicitly included, so we need to +# include gitolite.conf. +cd /etc/httpd/conf +grep ^Include.*gitolite.conf httpd.conf || + printf "\n%s\n%s\n" '# gitolite http mode' 'Include conf/extra/gitolite.conf' >> httpd.conf + +# Again, unlike Fedora, Manjaro's default conf does not come with cgi enabled. +# In fact, the directive is both commented out *and* inside an "IF" block for +# some other module. Since I don't plan to be an expert on apache, I will +# punt by including the required LoadModule line before the first LoadModule +# line that is not in an "if" block (i.e., not indented). +grep '^LoadModule cgi_module modules/mod_cgi.so' httpd.conf || + perl -i -pE 'say "LoadModule cgi_module modules/mod_cgi.so" if /^LoadModule/ and not $flag++' httpd.conf + +# END APACHE CONF CHANGES +# ---------------------------------------------------------------------- + +cd ~http +# should be /srv/http; you may want to check just to be safe +export GITOLITE_HTTP_HOME=$PWD/gitolite-home + +[[ -d gitolite-home ]] && { + [[ $GITOLITE_TEST != y ]] && { + echo "If you're OK with clobbering $GITOLITE_HTTP_HOME, please rerun with +environment variable GITOLITE_TEST set to 'y'." + exit 1; + } +} + +rm -rf gitolite-home +mkdir gitolite-home + +# setup apache conf for gitolite +cd /etc/httpd/conf/extra +[[ -f gitolite.conf ]] || { + cat > gitolite.conf <<-EOF + SetEnv GIT_PROJECT_ROOT $GITOLITE_HTTP_HOME/repositories + ScriptAlias /git/ $GITOLITE_HTTP_HOME/gitolite-source/src/gitolite-shell/ + ScriptAlias /gitmob/ $GITOLITE_HTTP_HOME/gitolite-source/src/gitolite-shell/ + SetEnv GITOLITE_HTTP_HOME $GITOLITE_HTTP_HOME + SetEnv GIT_HTTP_EXPORT_ALL + + <Location /git> + AuthType Basic + AuthName "Private Git Access" + Require valid-user + AuthUserFile $GITOLITE_HTTP_HOME/gitolite-http-authuserfile + </Location> + EOF +} + +# get the gitolite sources +cd $GITOLITE_HTTP_HOME + +if [[ -d /tmp/gitolite.git ]]; then + git clone /tmp/gitolite.git gitolite-source + # I do this because I have to test stuff *before* it gets to github, so I + # can't simply clone what's on github. Instead, I use a local + # world-readable bare repo cloned from my dev environment. +else + git clone 'https://github.com/sitaramc/gitolite' gitolite-source +fi + +# make the bin directory, and add it to PATH +cd gitolite-source +mkdir $GITOLITE_HTTP_HOME/bin +./install -ln $GITOLITE_HTTP_HOME/bin +export PATH=$PATH:$GITOLITE_HTTP_HOME/bin + +# come back to base, then run setup. Notice that you have to point HOME to +# the right place, even if it is just for this command +cd $GITOLITE_HTTP_HOME +HOME=$GITOLITE_HTTP_HOME gitolite setup -a admin + +# insert some essential lines at the beginning of the rc file +echo '$ENV{PATH} .= ":$ENV{GITOLITE_HTTP_HOME}/bin";' > 1 +echo >> 1 +cat .gitolite.rc >> 1 +\mv 1 .gitolite.rc + +# create users "admin" and "u1" thru "u6" for testing +htpasswd -bc $GITOLITE_HTTP_HOME/gitolite-http-authuserfile admin admin +seq 6 | xargs -I % htpasswd -b $GITOLITE_HTTP_HOME/gitolite-http-authuserfile u% u% + +# fix up ownership +chown -R http:http $GITOLITE_HTTP_HOME + +# restart httpd to make it pick up all the new stuff +systemctl restart httpd diff --git a/t/smart-http b/t/smart-http index 9ae6d5b..3ac910b 100755 --- a/t/smart-http +++ b/t/smart-http @@ -62,7 +62,7 @@ tsh " /1 file.*changed/ git push ok - /Initialized.*usr.share.httpd.gitolite-home.repositories.t2.git/ + /Initialized.*gitolite-home.repositories.t2.git/ /To http:..localhost.git.gitolite-admin.git/ /master -. master/ ## various ls-remotes |