git config settings in wild repos: part 1

- new GL_GITCONFIG_WILD to gate it
  - new sub to do all the hard work (refactored from a few lines in
    compile)
  - split the call from "compile" into two sets -- first for non-wild,
    then for wild

This ensures that after a "compile" (admin push) all git configs are
applied.

TODO: apply them when a new wild repo is created by a user, and then on
the "fork" (admin-defined command)
This commit is contained in:
Sitaram Chamarty 2010-06-25 23:36:15 +05:30
parent c944a8a3b9
commit d1d2c3e054
3 changed files with 69 additions and 9 deletions

View file

@ -145,6 +145,14 @@ $GL_GITCONFIG_KEYS = "";
# category:
# $GL_GITCONFIG_KEYS = "foo\\..*";
# --------------------------------------
# ALLOW GITCONFIG KEYS EVEN FOR WILD REPOS
#
# This is an efficiency issue more than a security issue, since this requires
# trawling through all of $REPO_BASE looking for stuff :)
# $GL_GITCONFIG_WILD = 0;
# --------------------------------------
# EXTERNAL COMMAND HELPER -- HTPASSWD

View file

@ -243,6 +243,50 @@ sub get_set_desc
}
}
# ----------------------------------------------------------------------------
# set/unset repo configs
# ----------------------------------------------------------------------------
sub setup_repo_configs
{
my ($repo_config_p, $repo, $wild) = @_;
wrap_chdir("$ENV{GL_REPO_BASE_ABS}/$repo.git");
# prep for wild and non-wild cases separately
my $repo_patt = ''; # actually "repo or repo_pattern"
if ($wild) {
chomp (my $creator = `cat gl-creater`);
# loop each key of %repo_config and make a copy
for my $key (keys %$repo_config_p) {
my $key2 = $key;
# subst $creator in the copy with the creator name
$key2 =~ s/\$creator/$creator/g;
# match the new key against $repo
if ($repo =~ /^$key2$/) {
# if it matches, proceed
$repo_patt = $key;
last;
}
}
print STDERR "$WARN repo $repo created by $creator is wild but doesn't match any patterns\n" unless $repo_patt;
} else {
$repo_patt ||= $repo; # just use the repo itself...
# XXX TODO there is a remote possibility of errors if you have a
# normal repo that fits a wild pattern; needs some digging into...
}
while ( my ($key, $value) = each(%{ $repo_config_p->{$repo_patt} }) ) {
if ($value) {
$value =~ s/^"(.*)"$/$1/;
system("git", "config", $key, $value);
} else {
system("git", "config", "--unset-all", $key);
}
}
}
# ----------------------------------------------------------------------------
# parse the compiled acl
# ----------------------------------------------------------------------------

View file

@ -52,7 +52,7 @@ $Data::Dumper::Sortkeys = 1;
open STDOUT, ">", "/dev/null" if (@ARGV and shift eq '-q');
# these are set by the "rc" file
our ($GL_ADMINDIR, $GL_CONF, $GL_KEYDIR, $GL_CONF_COMPILED, $REPO_BASE, $REPO_UMASK, $PROJECTS_LIST, $GIT_PATH, $GL_WILDREPOS, $GL_GITCONFIG_KEYS, $GL_PACKAGE_HOOKS, $GL_BIG_CONFIG, $GL_NO_DAEMON_NO_GITWEB, $GL_NO_CREATE_REPOS, $GL_NO_SETUP_AUTHKEYS);
our ($GL_ADMINDIR, $GL_CONF, $GL_KEYDIR, $GL_CONF_COMPILED, $REPO_BASE, $REPO_UMASK, $PROJECTS_LIST, $GIT_PATH, $GL_WILDREPOS, $GL_GITCONFIG_KEYS, $GL_GITCONFIG_WILD, $GL_PACKAGE_HOOKS, $GL_BIG_CONFIG, $GL_NO_DAEMON_NO_GITWEB, $GL_NO_CREATE_REPOS, $GL_NO_SETUP_AUTHKEYS);
# and these are set by gitolite.pm
our ($REPONAME_PATT, $REPOPATT_PATT, $USERNAME_PATT, $ABRT, $WARN);
@ -311,6 +311,7 @@ sub parse_conf_file
for my $repo (@repos) # each repo in the current stanza
{
$repo_config{$repo}{$key} = $value;
print STDERR "$WARN git config set for $repo but \$GL_GITCONFIG_WILD not set\n" unless $repo =~ $REPONAME_PATT or $GL_GITCONFIG_WILD;
}
}
# include
@ -382,6 +383,7 @@ my $compiled_fh = wrap_open( ">", "$GL_CONF_COMPILED.new" );
my $data_version = $current_data_version;
print $compiled_fh Data::Dumper->Dump([$data_version], [qw(*data_version)]);
my $dumped_data = Data::Dumper->Dump([\%repos], [qw(*repos)]);
$dumped_data .= Data::Dumper->Dump([\%repo_config], [qw(*repo_config)]) if %repo_config;
# the dump uses single quotes, but we convert any strings containing $creator,
# $readers, $writers, to double quoted strings. A wee bit sneaky, but not too
# much...
@ -476,14 +478,20 @@ unless ($GL_NO_CREATE_REPOS) {
# config hooks.emailprefix = "[foo]"
for my $repo (keys %repo_config) {
wrap_chdir("$repo_base_abs/$repo.git");
while ( my ($key, $value) = each(%{ $repo_config{$repo} }) ) {
if ($value) {
$value =~ s/^"(.*)"$/$1/;
system("git", "config", $key, $value);
} else {
system("git", "config", "--unset-all", $key);
}
&setup_repo_configs(\%repo_config, $repo) if $repo =~ $REPONAME_PATT;
}
# wild
if (%repo_config and $GL_WILDREPOS and $GL_GITCONFIG_WILD) {
wrap_chdir("$repo_base_abs");
for my $repo (`find . -type d -name "*.git"`) {
chomp ($repo);
next unless -f "$ENV{GL_REPO_BASE_ABS}/$repo/gl-creater"; # all/only wild repos have this file
# $repo will look like "./foo/bar.git", make it "foo/bar" before
# calling the repo config setup sub
$repo =~ s(\./(.*)\.git$)($1);
&setup_repo_configs(\%repo_config, $repo, 1);
}
}