fix up gitweb, daemon, for wild + big-config
Implementation notes: - %repo_config is now "our", not "my" - collect_repo_patts now uses repo_rights to get the name of the wild card repo (if any) that pertains to the physical $repo, instead of all that new code (duh!) - new "can_read(repo, user)" sub (to help daemon and gitweb use) - the "convenience copy on steroids" thing now copies %repo_config also, not just %repos. This makes setup_repo_configs simpler - $creator gets substituted into %groups also; we need that now that we (%repos and %groups) are working closer together :)
This commit is contained in:
parent
8deee9b6bd
commit
f21e7780a1
|
@ -40,6 +40,7 @@ our $REPOPATT_PATT=qr(^\@?[0-9a-zA-Z[][\\^.$|()[\]*+?{}0-9a-zA-Z._\@/-]*$);
|
||||||
our ($REPO_UMASK, $GL_WILDREPOS, $GL_PACKAGE_CONF, $GL_PACKAGE_HOOKS, $REPO_BASE, $GL_CONF_COMPILED, $GL_BIG_CONFIG);
|
our ($REPO_UMASK, $GL_WILDREPOS, $GL_PACKAGE_CONF, $GL_PACKAGE_HOOKS, $REPO_BASE, $GL_CONF_COMPILED, $GL_BIG_CONFIG);
|
||||||
our %repos;
|
our %repos;
|
||||||
our %groups;
|
our %groups;
|
||||||
|
our %repo_config;
|
||||||
our $data_version;
|
our $data_version;
|
||||||
our $current_data_version = '1.5';
|
our $current_data_version = '1.5';
|
||||||
|
|
||||||
|
@ -129,24 +130,9 @@ sub collect_repo_patts
|
||||||
for my $repo (`find . -type d -name "*.git"`) {
|
for my $repo (`find . -type d -name "*.git"`) {
|
||||||
chomp ($repo);
|
chomp ($repo);
|
||||||
$repo =~ s(\./(.*)\.git$)($1);
|
$repo =~ s(\./(.*)\.git$)($1);
|
||||||
# if its non-wild that's all you need
|
# the key has to be in the list, since the repo physically exists
|
||||||
if ($repos_p->{$repo}) {
|
my($perm, $creator, $wild) = &repo_rights($repo);
|
||||||
$repo_patts{$repo} = $repo;
|
$repo_patts{$repo} = $wild || $repo;
|
||||||
} else {
|
|
||||||
# otherwise it gets a wee bit complicated ;-)
|
|
||||||
chomp (my $creator = `cat $repo.git/gl-creater`);
|
|
||||||
for my $key (keys %$repos_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$/) {
|
|
||||||
# and if it matched you're done for this $repo
|
|
||||||
$repo_patts{$repo} = $key;
|
|
||||||
last;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return %repo_patts;
|
return %repo_patts;
|
||||||
|
@ -290,9 +276,9 @@ sub get_set_desc
|
||||||
|
|
||||||
sub setup_repo_configs
|
sub setup_repo_configs
|
||||||
{
|
{
|
||||||
my ($repo, $repo_patt, $repo_config_p) = @_;
|
my ($repo, $repo_config_p) = @_;
|
||||||
|
|
||||||
while ( my ($key, $value) = each(%{ $repo_config_p->{$repo_patt} }) ) {
|
while ( my ($key, $value) = each(%{ $repo_config_p->{$repo} }) ) {
|
||||||
if ($value) {
|
if ($value) {
|
||||||
$value =~ s/^"(.*)"$/$1/;
|
$value =~ s/^"(.*)"$/$1/;
|
||||||
system("git", "config", $key, $value);
|
system("git", "config", $key, $value);
|
||||||
|
@ -306,12 +292,13 @@ sub setup_repo_configs
|
||||||
# set/unset daemon access
|
# set/unset daemon access
|
||||||
# ----------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# does not return anything; just touch/unlink the appropriate file
|
||||||
my $export_ok = "git-daemon-export-ok";
|
my $export_ok = "git-daemon-export-ok";
|
||||||
sub setup_daemon_access
|
sub setup_daemon_access
|
||||||
{
|
{
|
||||||
my ($repo, $allowed) = @_;
|
my $repo = shift;
|
||||||
|
|
||||||
if ($allowed) {
|
if (&can_read($repo, 'daemon')) {
|
||||||
system("touch $export_ok");
|
system("touch $export_ok");
|
||||||
} else {
|
} else {
|
||||||
unlink($export_ok);
|
unlink($export_ok);
|
||||||
|
@ -322,13 +309,18 @@ sub setup_daemon_access
|
||||||
# set/unset gitweb access
|
# set/unset gitweb access
|
||||||
# ----------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# returns 1 if gitweb access has happened; this is to allow the caller to add
|
||||||
|
# an entry to the projects.list file
|
||||||
my $desc_file = "description";
|
my $desc_file = "description";
|
||||||
sub setup_gitweb_access
|
sub setup_gitweb_access
|
||||||
# this also sets "owner" for gitweb, by the way
|
# this also sets "owner" for gitweb, by the way
|
||||||
{
|
{
|
||||||
my ($repo, $allowed, $desc, $owner) = @_;
|
my ($repo, $desc, $owner) = @_;
|
||||||
|
my $ret = 0;
|
||||||
|
|
||||||
if ($allowed) {
|
# passing in a descr implies 'R = gitweb'
|
||||||
|
if ($desc or &can_read($repo, 'gitweb')) {
|
||||||
|
$ret = 1;
|
||||||
if ($desc) {
|
if ($desc) {
|
||||||
open(DESC, ">", $desc_file);
|
open(DESC, ">", $desc_file);
|
||||||
print DESC $desc . "\n";
|
print DESC $desc . "\n";
|
||||||
|
@ -351,6 +343,8 @@ sub setup_gitweb_access
|
||||||
if (length($keys) == 0) {
|
if (length($keys) == 0) {
|
||||||
system("git config --remove-section gitweb 2>/dev/null");
|
system("git config --remove-section gitweb 2>/dev/null");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return $ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
# ----------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------
|
||||||
|
@ -409,6 +403,7 @@ sub parse_acl
|
||||||
$repos{$dr}{DELETE_IS_D} = 1 if $repos{$r}{DELETE_IS_D};
|
$repos{$dr}{DELETE_IS_D} = 1 if $repos{$r}{DELETE_IS_D};
|
||||||
$repos{$dr}{CREATE_IS_C} = 1 if $repos{$r}{CREATE_IS_C};
|
$repos{$dr}{CREATE_IS_C} = 1 if $repos{$r}{CREATE_IS_C};
|
||||||
$repos{$dr}{NAME_LIMITS} = 1 if $repos{$r}{NAME_LIMITS};
|
$repos{$dr}{NAME_LIMITS} = 1 if $repos{$r}{NAME_LIMITS};
|
||||||
|
$repo_config{$dr} = $repo_config{$r} if $repo_config{$r};
|
||||||
|
|
||||||
for my $u ('@all', "$gl_user - wild", @user_plus) {
|
for my $u ('@all', "$gl_user - wild", @user_plus) {
|
||||||
my $du = $gl_user; $du = '@all' if $u eq '@all';
|
my $du = $gl_user; $du = '@all' if $u eq '@all';
|
||||||
|
@ -522,8 +517,6 @@ sub expand_wild
|
||||||
$repo =~ s/^\.\///;
|
$repo =~ s/^\.\///;
|
||||||
$repo =~ s/\.git$//;
|
$repo =~ s/\.git$//;
|
||||||
|
|
||||||
return if $last_repo eq $repo; # a wee bit o' caching, though not yet needed
|
|
||||||
|
|
||||||
# we get passed an actual repo name. It may be a normal
|
# we get passed an actual repo name. It may be a normal
|
||||||
# (non-wildcard) repo, in which case it is assumed to exist. If it's
|
# (non-wildcard) repo, in which case it is assumed to exist. If it's
|
||||||
# a wildrepo, it may or may not exist. If it doesn't exist, the "C"
|
# a wildrepo, it may or may not exist. If it doesn't exist, the "C"
|
||||||
|
@ -582,6 +575,14 @@ sub cli_repo_rights {
|
||||||
print "$perm $creator\n";
|
print "$perm $creator\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub can_read {
|
||||||
|
my $repo = shift;
|
||||||
|
my $user = shift || $ENV{GL_USER};
|
||||||
|
local $ENV{GL_USER} = $user;
|
||||||
|
my ($perm, $creator, $wild) = &repo_rights($repo);
|
||||||
|
return $perm =~ /R/;
|
||||||
|
}
|
||||||
|
|
||||||
# ----------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------
|
||||||
# setup the ~/.ssh/authorized_keys file
|
# setup the ~/.ssh/authorized_keys file
|
||||||
# ----------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------
|
||||||
|
|
|
@ -207,10 +207,9 @@ if ($perm =~ /C/) {
|
||||||
# it was missing, and you have create perms
|
# it was missing, and you have create perms
|
||||||
wrap_chdir("$ENV{GL_REPO_BASE_ABS}");
|
wrap_chdir("$ENV{GL_REPO_BASE_ABS}");
|
||||||
new_repo($repo, "$GL_ADMINDIR/hooks/common", $user);
|
new_repo($repo, "$GL_ADMINDIR/hooks/common", $user);
|
||||||
&setup_repo_configs($repo, $ENV{GL_REPOPATT}, \%repo_config);
|
&setup_repo_configs($repo, \%repo_config);
|
||||||
&setup_daemon_access($repo, $repos{$ENV{GL_REPOPATT}}{'R'}{'daemon'} || '');
|
&setup_daemon_access($repo);
|
||||||
&setup_gitweb_access($repo, $repos{$ENV{GL_REPOPATT}}{'R'}{'gitweb'} || '', '', '');
|
system("echo $repo.git >> $PROJECTS_LIST") if &setup_gitweb_access($repo, '', '');
|
||||||
system("echo $repo.git >> $PROJECTS_LIST");
|
|
||||||
wrap_chdir($ENV{HOME});
|
wrap_chdir($ENV{HOME});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -105,7 +105,7 @@ our $current_data_version; # this comes from gitolite.pm
|
||||||
my %user_list = ();
|
my %user_list = ();
|
||||||
|
|
||||||
# repo configurations
|
# repo configurations
|
||||||
my %repo_config = ();
|
our %repo_config = ();
|
||||||
|
|
||||||
# gitweb descriptions and owners; plain text, keyed by "$repo.git"
|
# gitweb descriptions and owners; plain text, keyed by "$repo.git"
|
||||||
my %desc = ();
|
my %desc = ();
|
||||||
|
@ -311,7 +311,15 @@ sub parse_conf_file
|
||||||
for my $repo (@repos) # each repo in the current stanza
|
for my $repo (@repos) # each repo in the current stanza
|
||||||
{
|
{
|
||||||
$repo_config{$repo}{$key} = $value;
|
$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;
|
# no problem if it's a plain repo (non-pattern, non-groupname)
|
||||||
|
# OR wild configs are allowed
|
||||||
|
unless ( ($repo =~ $REPONAME_PATT and $repo !~ /^@/) or $GL_GITCONFIG_WILD) {
|
||||||
|
my @r = ($repo); # single wildpatt
|
||||||
|
@r = sort keys %{ $groups{$repo} } if $groups{$repo}; # or a group; get its members
|
||||||
|
do {
|
||||||
|
print STDERR "$WARN git config set for $_ but \$GL_GITCONFIG_WILD not set\n" unless $_ =~ $REPONAME_PATT
|
||||||
|
} for @r;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
# include
|
# include
|
||||||
|
@ -389,7 +397,12 @@ $dumped_data .= Data::Dumper->Dump([\%repo_config], [qw(*repo_config)]) if %repo
|
||||||
# much...
|
# much...
|
||||||
$dumped_data =~ s/'(?=[^']*\$(?:creator|readers|writers|gl_user))~?(.*?)'/"$1"/g;
|
$dumped_data =~ s/'(?=[^']*\$(?:creator|readers|writers|gl_user))~?(.*?)'/"$1"/g;
|
||||||
print $compiled_fh $dumped_data;
|
print $compiled_fh $dumped_data;
|
||||||
print $compiled_fh Data::Dumper->Dump([\%groups], [qw(*groups)]) if $GL_BIG_CONFIG and %groups;
|
if ($GL_BIG_CONFIG and %groups) {
|
||||||
|
$dumped_data = Data::Dumper->Dump([\%groups], [qw(*groups)]);
|
||||||
|
$dumped_data =~ s/\bCREAT[EO]R\b/\$creator/g;
|
||||||
|
$dumped_data =~ s/'(?=[^']*\$(?:creator|readers|writers|gl_user))~?(.*?)'/"$1"/g;
|
||||||
|
print $compiled_fh $dumped_data;
|
||||||
|
}
|
||||||
close $compiled_fh or die "$ABRT close compiled-conf failed: $!\n";
|
close $compiled_fh or die "$ABRT close compiled-conf failed: $!\n";
|
||||||
rename "$GL_CONF_COMPILED.new", "$GL_CONF_COMPILED";
|
rename "$GL_CONF_COMPILED.new", "$GL_CONF_COMPILED";
|
||||||
|
|
||||||
|
@ -504,23 +517,12 @@ my %projlist = ();
|
||||||
# for each real repo (and remember this will be empty, thus skipping all this,
|
# for each real repo (and remember this will be empty, thus skipping all this,
|
||||||
# if $GL_NO_DAEMON_NO_GITWEB is on!)
|
# if $GL_NO_DAEMON_NO_GITWEB is on!)
|
||||||
for my $repo (keys %repo_patts) {
|
for my $repo (keys %repo_patts) {
|
||||||
my $repo_patt = $repo_patts{$repo}; # if non-wild, $repo_patt will be eq $repo anyway
|
my $repo_patt = $repo_patts{$repo};
|
||||||
|
|
||||||
wrap_chdir("$ENV{GL_REPO_BASE_ABS}/$repo.git");
|
wrap_chdir("$ENV{GL_REPO_BASE_ABS}/$repo.git");
|
||||||
|
|
||||||
# git config
|
|
||||||
if ($repo_patt eq $repo or $GL_GITCONFIG_WILD) {
|
|
||||||
# erm, what that means is that it's either a non-wild repo being
|
|
||||||
# config'd or a wild one but gitconfig is allowed on wilds.
|
|
||||||
# XXX do we really need GL_GITCONFIG_WILD now? It was meant to be
|
|
||||||
# only an efficiency thing, but that was before this whole revamp;
|
|
||||||
# we already trawl through $REPO_BASE exactly once now anyway!
|
|
||||||
# ...need to think about this
|
|
||||||
&setup_repo_configs($repo, $repo_patt, \%repo_config) if $repo_config{$repo_patt};
|
|
||||||
}
|
|
||||||
|
|
||||||
# daemon is easy
|
# daemon is easy
|
||||||
&setup_daemon_access($repo, $repos{$repo_patt}{'R'}{'daemon'} || '');
|
&setup_daemon_access($repo);
|
||||||
|
|
||||||
# gitweb is a little more complicated. Here're some notes:
|
# gitweb is a little more complicated. Here're some notes:
|
||||||
# - "setup_gitweb_access" also sets "owner", despite the name
|
# - "setup_gitweb_access" also sets "owner", despite the name
|
||||||
|
@ -532,12 +534,16 @@ for my $repo (keys %repo_patts) {
|
||||||
# into the "repo foo" section; they're essentialy independent.
|
# into the "repo foo" section; they're essentialy independent.
|
||||||
# Anyway, I believe it doesn't make sense to have all wild repos
|
# Anyway, I believe it doesn't make sense to have all wild repos
|
||||||
# (for some pattern) to have the same description and owner.
|
# (for some pattern) to have the same description and owner.
|
||||||
if ($repos{$repo_patt}{'R'}{'gitweb'} or $desc{"$repo.git"}) {
|
$projlist{"$repo.git"} = 1 if &setup_gitweb_access($repo, $desc{"$repo.git"} || '', $owner{"$repo.git"} || '');
|
||||||
$projlist{"$repo.git"} = 1;
|
|
||||||
&setup_gitweb_access($repo, 1, $desc{"$repo.git"} || '', $owner{"$repo.git"} || '');
|
# git config
|
||||||
} else {
|
# implementation note: this must happen *after* one of the previous 2
|
||||||
&setup_gitweb_access($repo, 0, '', '');
|
# calls (setup daemon or gitweb). The reason is that they call
|
||||||
}
|
# "can_read", which eventually calls parse_acl with the right "creator"
|
||||||
|
# set for the *current* repo, which in turn stores translated values fr
|
||||||
|
# $creator in the repo_config hash, which, (phew!) is needed for a match
|
||||||
|
# that eventually gets you a valid $repo_config{} below
|
||||||
|
&setup_repo_configs($repo, \%repo_config) if $repo_config{$repo};
|
||||||
}
|
}
|
||||||
|
|
||||||
# write out the project list
|
# write out the project list
|
||||||
|
|
Loading…
Reference in a new issue