2009-08-25 05:14:46 +02:00
|
|
|
#!/usr/bin/perl
|
2009-08-23 07:35:14 +02:00
|
|
|
|
|
|
|
use strict;
|
2009-08-25 05:14:46 +02:00
|
|
|
use warnings;
|
2009-08-23 10:16:45 +02:00
|
|
|
use Data::Dumper;
|
2009-09-18 14:30:14 +02:00
|
|
|
$Data::Dumper::Indent = 1;
|
2009-11-23 13:34:18 +01:00
|
|
|
$Data::Dumper::Sortkeys = 1;
|
2009-08-23 07:35:14 +02:00
|
|
|
|
2009-08-23 11:25:50 +02:00
|
|
|
# ----------------------------------------------------------------------------
|
2011-01-15 16:39:56 +01:00
|
|
|
# find the rc file, then pull the libraries
|
2009-08-23 11:25:50 +02:00
|
|
|
# ----------------------------------------------------------------------------
|
|
|
|
|
2011-01-15 16:39:56 +01:00
|
|
|
BEGIN {
|
|
|
|
die "ENV GL_RC not set\n" unless $ENV{GL_RC};
|
|
|
|
die "ENV GL_BINDIR not set\n" unless $ENV{GL_BINDIR};
|
|
|
|
}
|
2009-09-15 17:32:23 +02:00
|
|
|
|
2011-01-15 16:39:56 +01:00
|
|
|
use lib $ENV{GL_BINDIR};
|
|
|
|
use gitolite_rc;
|
|
|
|
use gitolite qw(:DEFAULT %repos %groups %git_configs %split_conf);
|
2009-10-25 03:59:52 +01:00
|
|
|
|
2011-01-15 16:39:56 +01:00
|
|
|
# === add-auth-keys ===
|
2009-08-23 11:25:50 +02:00
|
|
|
|
2011-01-15 16:39:56 +01:00
|
|
|
# setup quiet mode if asked; please do not use this when running manually
|
|
|
|
open STDOUT, ">", "/dev/null" if (@ARGV and shift eq '-q');
|
2009-10-13 06:32:45 +02:00
|
|
|
|
2009-08-23 11:25:50 +02:00
|
|
|
# ----------------------------------------------------------------------------
|
|
|
|
# definitions specific to this program
|
|
|
|
# ----------------------------------------------------------------------------
|
2009-08-23 07:35:14 +02:00
|
|
|
|
2009-10-05 16:51:33 +02:00
|
|
|
# groups can now represent user groups or repo groups.
|
|
|
|
|
|
|
|
# $groups{group}{member} = "master" (or name of fragment file in which the
|
|
|
|
# group is defined).
|
2011-01-15 16:39:56 +01:00
|
|
|
# our %groups = (); # moved to gitolite.pm now
|
2009-10-05 16:51:33 +02:00
|
|
|
|
|
|
|
# %repos has two functions.
|
|
|
|
|
|
|
|
# $repos{repo}{R|W}{user} = 1 if user has R (or W) permissions for at least
|
2009-12-05 14:08:46 +01:00
|
|
|
# one branch in repo. This is used by the "level 1 check" (see faq). There's
|
|
|
|
# also the new "C" (create a repo) permission now
|
2009-10-05 16:51:33 +02:00
|
|
|
|
|
|
|
# $repos{repo}{user} is a list of {ref, perms} pairs. This is used by the
|
|
|
|
# level 2 check. In order to allow "exclude" rules, the order of rules now
|
|
|
|
# matters, so what used to be entirely "hash of hash of hash" now has a list
|
|
|
|
# in between :)
|
2011-01-15 16:39:56 +01:00
|
|
|
# copy above desc to lite.pm -- my %repos = ();
|
2009-10-05 16:51:33 +02:00
|
|
|
|
2011-01-15 16:39:56 +01:00
|
|
|
# names of repos whose ACLs don't make it into the main compiled config file
|
|
|
|
# copy above desc to lite.pm -- my %split_conf = ();
|
2011-01-01 10:44:54 +01:00
|
|
|
|
2011-08-17 16:16:07 +02:00
|
|
|
# rule and config sequence numbers
|
(big one!) rule sequencing changes!
There were 2 problems with rule sequencing.
Eli had a use case where everyone is equal, but some are more equal than
the others ;-) He wanted a way to say "everyone can create repos under
their own names, but only some people should be able to rewind their
branches".
Something like this would be ideal (follow the rules in sequence for
u1/u2/u3/u4, and you will see that the "deny" rule kicks in to prevent
u1/u2 from being able to rewind, although they can certainly delete
their branches):
@private-owners = u1 u2
@experienced-private-owners = u3 u4
repo CREATOR/.*
C = @private-owners @experienced-private-owners
RWD = CREATOR
RW = WRITERS
R = READERS
- = @private-owners
RW+D = CREATOR
In normal gitolite this doesn't work because the CREATOR rules (which
get translated to "u1" at runtime) end up over-writing the "deny" rule
when u1 or u2 are the creators. This over-writing happens directly at
the "do compiled.pm" step.
With big-config, this does not happen (because @private-owners does not
get expanded to u1 and u2), but the problem remains: the order of
picking up elements of repo_plus and user_plus is such that, again, the
RW+D wins (it appears before the "-" rule).
We fix all that by
- making CREATOR complete to more than just the creator's name (for
"u1", it now becomes "u1 - wild", which is actually illegal to use
for real so there's no possibility of a name clash!)
- maintaining a rule sequence number that is used to sort the rules
eventually applied (this also resulted in the refex+perm hash
becoming a list)
2010-05-18 11:27:14 +02:00
|
|
|
my $rule_seq = 0;
|
2011-08-17 16:16:07 +02:00
|
|
|
my $config_seq = 0;
|
(big one!) rule sequencing changes!
There were 2 problems with rule sequencing.
Eli had a use case where everyone is equal, but some are more equal than
the others ;-) He wanted a way to say "everyone can create repos under
their own names, but only some people should be able to rewind their
branches".
Something like this would be ideal (follow the rules in sequence for
u1/u2/u3/u4, and you will see that the "deny" rule kicks in to prevent
u1/u2 from being able to rewind, although they can certainly delete
their branches):
@private-owners = u1 u2
@experienced-private-owners = u3 u4
repo CREATOR/.*
C = @private-owners @experienced-private-owners
RWD = CREATOR
RW = WRITERS
R = READERS
- = @private-owners
RW+D = CREATOR
In normal gitolite this doesn't work because the CREATOR rules (which
get translated to "u1" at runtime) end up over-writing the "deny" rule
when u1 or u2 are the creators. This over-writing happens directly at
the "do compiled.pm" step.
With big-config, this does not happen (because @private-owners does not
get expanded to u1 and u2), but the problem remains: the order of
picking up elements of repo_plus and user_plus is such that, again, the
RW+D wins (it appears before the "-" rule).
We fix all that by
- making CREATOR complete to more than just the creator's name (for
"u1", it now becomes "u1 - wild", which is actually illegal to use
for real so there's no possibility of a name clash!)
- maintaining a rule sequence number that is used to sort the rules
eventually applied (this also resulted in the refex+perm hash
becoming a list)
2010-05-18 11:27:14 +02:00
|
|
|
|
2009-10-05 16:51:33 +02:00
|
|
|
# <sigh>... having been forced to use a list as described above, we lose some
|
|
|
|
# efficiency due to the possibility of the same {ref, perms} pair showing up
|
|
|
|
# multiple times for the same repo+user. So...
|
|
|
|
my %rurp_seen = ();
|
|
|
|
|
|
|
|
# catch usernames<->pubkeys mismatches; search for "lint" below
|
|
|
|
my %user_list = ();
|
2009-08-23 10:16:45 +02:00
|
|
|
|
2011-01-01 07:02:58 +01:00
|
|
|
# repo specific 'git config' stuff
|
2011-01-15 16:39:56 +01:00
|
|
|
# our %git_configs = (); # moved to gitolite.pm now
|
2009-12-07 21:20:29 +01:00
|
|
|
|
2009-11-27 08:53:48 +01:00
|
|
|
# gitweb descriptions and owners; plain text, keyed by "$repo.git"
|
2009-11-12 10:19:39 +01:00
|
|
|
my %desc = ();
|
2009-11-27 08:53:48 +01:00
|
|
|
my %owner = ();
|
2009-11-12 10:19:39 +01:00
|
|
|
|
2011-08-27 17:59:02 +02:00
|
|
|
# backward compat for delegation
|
|
|
|
my $subconf_seen = 0;
|
|
|
|
|
2009-08-23 11:25:50 +02:00
|
|
|
# ----------------------------------------------------------------------------
|
|
|
|
# subroutines
|
|
|
|
# ----------------------------------------------------------------------------
|
|
|
|
|
2009-09-15 17:37:00 +02:00
|
|
|
sub expand_list
|
2009-08-23 10:16:45 +02:00
|
|
|
{
|
|
|
|
my @list = @_;
|
|
|
|
my @new_list = ();
|
|
|
|
|
|
|
|
for my $item (@list)
|
|
|
|
{
|
2010-10-24 14:36:42 +02:00
|
|
|
if ($item =~ /^@/ and $item ne '@all') # nested group
|
2009-08-23 10:16:45 +02:00
|
|
|
{
|
2009-11-03 15:54:53 +01:00
|
|
|
die "$ABRT undefined group $item\n" unless $groups{$item};
|
2009-08-23 10:16:45 +02:00
|
|
|
# add those names to the list
|
2009-10-02 18:24:23 +02:00
|
|
|
push @new_list, sort keys %{ $groups{$item} };
|
2009-08-23 10:16:45 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
push @new_list, $item;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return @new_list;
|
|
|
|
}
|
|
|
|
|
2011-04-01 03:09:04 +02:00
|
|
|
sub device_inode {
|
|
|
|
my $file = shift;
|
|
|
|
return join("/", (stat $file)[0,1]);
|
|
|
|
}
|
|
|
|
|
2009-08-23 10:16:45 +02:00
|
|
|
# ----------------------------------------------------------------------------
|
|
|
|
# "compile" GL conf
|
|
|
|
# ----------------------------------------------------------------------------
|
|
|
|
|
2011-04-01 03:09:04 +02:00
|
|
|
# detect recursion in include files; see processing of "include" statement later
|
2011-08-27 17:59:02 +02:00
|
|
|
my %included;
|
2011-04-01 03:09:04 +02:00
|
|
|
$included{device_inode("conf/gitolite.conf")}++;
|
|
|
|
|
2011-08-27 17:59:02 +02:00
|
|
|
my %prefixed_groupname = ();
|
|
|
|
|
2010-07-28 00:00:36 +02:00
|
|
|
sub check_fragment_repo_disallowed
|
|
|
|
{
|
|
|
|
# trying to set access for $repo (='foo')...
|
|
|
|
my ($fragment, $repo) = @_;
|
|
|
|
|
|
|
|
# processing the master config, not a fragment
|
|
|
|
return 0 if $fragment eq 'master';
|
|
|
|
# fragment is also called 'foo' (you're allowed to have a
|
|
|
|
# fragment that is only concerned with one repo)
|
|
|
|
return 0 if $fragment eq $repo;
|
|
|
|
# same thing in big-config-land; foo is just @foo now
|
|
|
|
return 0 if $GL_BIG_CONFIG and ("\@$fragment" eq $repo);
|
|
|
|
my @matched = grep { $repo =~ /^$_$/ }
|
|
|
|
grep { $groups{"\@$fragment"}{$_} eq 'master' }
|
|
|
|
sort keys %{ $groups{"\@$fragment"} };
|
|
|
|
return 0 if @matched > 0;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2010-09-04 11:33:06 +02:00
|
|
|
sub parse_conf_line
|
|
|
|
{
|
|
|
|
my ($line, $fragment, $repos_p, $ignored_p) = @_;
|
|
|
|
|
|
|
|
# user or repo groups
|
2010-11-09 13:07:55 +01:00
|
|
|
if ($line =~ /^(@\S+) = ?(.*)/)
|
2010-09-04 11:33:06 +02:00
|
|
|
{
|
|
|
|
# store the members of each group as hash key. Keep track of when
|
|
|
|
# the group was *first* created by using $fragment as the *value*
|
|
|
|
do { $groups{$1}{$_} ||= $fragment } for ( expand_list( split(' ', $2) ) );
|
2010-11-09 13:07:55 +01:00
|
|
|
# create the group hash even if empty
|
|
|
|
$groups{$1} = {} unless $groups{$1};
|
2011-10-05 18:31:49 +02:00
|
|
|
die "$ABRT bad group '$1'\n" unless $1 =~ $REPONAME_PATT;
|
2010-09-04 11:33:06 +02:00
|
|
|
}
|
|
|
|
# repo(s)
|
|
|
|
elsif ($line =~ /^repo (.*)/)
|
|
|
|
{
|
|
|
|
# grab the list...
|
|
|
|
@{ $repos_p } = split ' ', $1;
|
2010-10-24 14:36:42 +02:00
|
|
|
# ...expand groups in the default case
|
|
|
|
@{ $repos_p } = expand_list ( @{ $repos_p } ) unless $GL_BIG_CONFIG;
|
|
|
|
# ...sanity check
|
|
|
|
for (@{ $repos_p }) {
|
2011-03-08 02:06:23 +01:00
|
|
|
print STDERR "$WARN explicit '.git' extension ignored for $_.git\n" if s/\.git$//;
|
2011-10-05 18:31:49 +02:00
|
|
|
die "$ABRT bad reponame '$_'\n"
|
2010-10-24 14:36:42 +02:00
|
|
|
if ($GL_WILDREPOS and $_ !~ $REPOPATT_PATT);
|
2011-10-05 18:31:49 +02:00
|
|
|
die "$ABRT bad reponame '$_' or you forgot to set \$GL_WILDREPOS\n"
|
2010-10-24 14:36:42 +02:00
|
|
|
if (not $GL_WILDREPOS and $_ !~ $REPONAME_PATT);
|
2010-09-04 11:33:06 +02:00
|
|
|
}
|
|
|
|
s/\bCREAT[EO]R\b/\$creator/g for @{ $repos_p };
|
|
|
|
}
|
|
|
|
# actual permission line
|
|
|
|
elsif ($line =~ /^(-|C|R|RW\+?(?:C?D?|D?C?)) (.* )?= (.+)/)
|
|
|
|
{
|
|
|
|
my $perms = $1;
|
|
|
|
my @refs; @refs = split( ' ', $2 ) if $2;
|
|
|
|
@refs = expand_list ( @refs );
|
|
|
|
my @users = split ' ', $3;
|
|
|
|
die "$ABRT \$GL_WILDREPOS is not set, you cant use 'C' in config\n" if $perms eq 'C' and not $GL_WILDREPOS;
|
|
|
|
|
|
|
|
# if no ref is given, this PERM applies to all refs
|
|
|
|
@refs = qw(refs/.*) unless @refs;
|
|
|
|
# deprecation warning
|
2011-03-08 02:06:23 +01:00
|
|
|
map { print STDERR "WARNING: old syntax 'PATH/' found; please use new syntax 'NAME/'\n" if s(^PATH/)(NAME/) } @refs;
|
2010-09-04 11:33:06 +02:00
|
|
|
# fully qualify refs that dont start with "refs/" or "NAME/";
|
|
|
|
# prefix them with "refs/heads/"
|
|
|
|
@refs = map { m(^(refs|NAME)/) or s(^)(refs/heads/); $_ } @refs;
|
|
|
|
@refs = map { s(/USER/)(/\$gl_user/); $_ } @refs;
|
|
|
|
|
|
|
|
# expand the user list, unless it is just "@all"
|
2010-10-24 14:36:42 +02:00
|
|
|
@users = expand_list ( @users ) unless $GL_BIG_CONFIG;
|
2011-10-05 18:31:49 +02:00
|
|
|
do { die "$ABRT bad username '$_'\n" unless $_ =~ $USERNAME_PATT } for @users;
|
2010-09-04 11:33:06 +02:00
|
|
|
|
|
|
|
s/\bCREAT[EO]R\b/~\$creator/g for @users;
|
|
|
|
|
|
|
|
# ok, we can finally populate the %repos hash
|
|
|
|
for my $repo (@{ $repos_p }) # each repo in the current stanza
|
|
|
|
{
|
|
|
|
# if we're processing a delegated config file (not the master
|
|
|
|
# config), we need to prevent attempts by that admin to obtain
|
|
|
|
# rights on stuff outside his domain
|
|
|
|
|
|
|
|
# trying to set access for $repo (='foo')...
|
|
|
|
if (check_fragment_repo_disallowed( $fragment, $repo ))
|
|
|
|
{
|
2011-08-27 17:59:02 +02:00
|
|
|
my $repo = $repo;
|
|
|
|
$repo =~ s/^\@$fragment\./locally modified \@/;
|
2010-09-04 11:33:06 +02:00
|
|
|
$ignored_p->{$fragment}{$repo} = 1;
|
|
|
|
next;
|
|
|
|
}
|
|
|
|
for my $user (@users)
|
|
|
|
{
|
|
|
|
# lint check, to catch pubkey/username typos
|
|
|
|
if ($user =~ /^@/ and $user ne '@all') {
|
|
|
|
# this is a usergroup, not a normal user; happens with GL_BIG_CONFIG
|
|
|
|
if (exists $groups{$user}) {
|
|
|
|
$user_list{$_}++ for keys %{ $groups{$user} };
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
$user_list{$user}++;
|
|
|
|
}
|
|
|
|
|
|
|
|
# for 1st level check (see faq/tips doc)
|
|
|
|
$repos{$repo}{C}{$user} = 1, next if $perms eq 'C';
|
|
|
|
$repos{$repo}{R}{$user} = 1 if $perms =~ /R/;
|
|
|
|
$repos{$repo}{W}{$user} = 1 if $perms =~ /W|D/;
|
|
|
|
|
|
|
|
# if the user specified even a single 'D' anywhere, make
|
|
|
|
# that fact easy to find; this changes the meaning of RW+
|
|
|
|
# to no longer permit deletes (see update hook)
|
|
|
|
$repos{$repo}{DELETE_IS_D} = 1 if $perms =~ /D/;
|
|
|
|
$repos{$repo}{CREATE_IS_C} = 1 if $perms =~ /RW.*C/;
|
|
|
|
|
|
|
|
# for 2nd level check, store each "ref, perms" pair in order
|
|
|
|
for my $ref (@refs)
|
|
|
|
{
|
|
|
|
# checking NAME based restrictions is expensive for
|
|
|
|
# the update hook (see the changes to src/hooks/update
|
|
|
|
# in this commit for why) so we would *very* much like
|
|
|
|
# to avoid doing it for the large majority of repos
|
|
|
|
# that do *not* use NAME limits. Setting a flag that
|
|
|
|
# can be checked right away will help us do that
|
|
|
|
$repos{$repo}{NAME_LIMITS} = 1 if $ref =~ /^NAME\//;
|
custom perm categories in setperms (WARNING: PLEASE READ FULL COMMIT MESSAGE)
THE COMPILED CONFIG FILE FORMAT CHANGES WITH THIS VERSION. PLEASE DO
NOT MIX VERSIONS OR DOWNGRADE. Upgrading using normal gitolite upgrade
means should be fine, though.
Originally, we only allowed "R" and "RW" as categories of users supplied
to the `setperms` command. These map respectively to "READERS" and
"WRITERS" in the access rules.
Now:
- we prefer READERS instead of R and WRITERS instead of RW
- we allow the admin to define other categories as she wishes
(example: MANAGERS, TESTERS, etc). These do not have abbreviations,
however, so they must be supplied in full.
PLEASE, *PLEASE*, read the section in doc/wildcard-repositories.mkd for
more info. This is a VERY powerful feature and if you're not careful
you could mess up the ACLs nicely.
Backward compat note: you can continue to use the "R" and "RW"
categories when running the "setperms" command, and gitolite will
internally convert them to READERS and WRITERS categories.
----
implementation notes:
- new RC var called GL_WILDREPOS_PERM_CATS that is a space-sep list of
the allowed categories in a gl-perms file; defaults to "R RW" if not
specified
- wild_repo_rights no longer returns $c, $r, $wC, where $r = $user if
"R $user", $r = '@all' if "R @all", and similarly with $w and "RW".
Instead it returns $c and a new hash that effectively gives the same
info, but expanded to include any other valid categories (listed in
GL_WILDREPOS_PERM_CATS)
- consequently, the arguments that parse_acl takes also change the
same way
- (side note: R and RW are quietly converted to READERS and WRITERS;
however, new categories that you define yourself do not have
abbreviations)
- setperms validates perms to make sure only allowed categories are
used; however even if someone changed them behind the scenes,
wild_repo_rights will also check. This is necessary in case the
admin tightened up GL_WILDREPOS_PERM_CATS after someone had already
setperms-d his repos.
- as a bonus, we eliminate all the post-Dumper shenanigans, at least
for READERS and WRITERS. Those two now look, to the compile script,
just like any other usernames.
2010-11-06 06:16:17 +01:00
|
|
|
my $p_user = $user; $p_user =~ s/creator$/creator - wild/;
|
2010-09-04 11:33:06 +02:00
|
|
|
push @{ $repos{$repo}{$p_user} }, [ $rule_seq++, $ref, $perms ]
|
|
|
|
unless $rurp_seen{$repo}{$p_user}{$ref}{$perms}++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2011-01-01 07:02:58 +01:00
|
|
|
# repo specific 'git config' stuff
|
2010-09-04 11:33:06 +02:00
|
|
|
elsif ($line =~ /^config (.+) = ?(.*)/)
|
|
|
|
{
|
|
|
|
my ($key, $value) = ($1, $2);
|
|
|
|
my @validkeys = split(' ', ($GL_GITCONFIG_KEYS || '') );
|
2011-10-07 15:57:28 +02:00
|
|
|
push @validkeys, "gitolite-options\\..*";
|
2010-09-04 11:33:06 +02:00
|
|
|
my @matched = grep { $key =~ /^$_$/ } @validkeys;
|
2010-10-23 18:28:18 +02:00
|
|
|
die "$ABRT git config $key not allowed\ncheck GL_GITCONFIG_KEYS in the rc file for how to allow it\n" if (@matched < 1);
|
2010-09-04 11:33:06 +02:00
|
|
|
for my $repo (@{ $repos_p }) # each repo in the current stanza
|
|
|
|
{
|
2011-08-17 16:16:07 +02:00
|
|
|
$git_configs{$repo}{$config_seq++}{$key} = $value;
|
2011-08-06 05:13:24 +02:00
|
|
|
|
|
|
|
# force entry in %repos. Without this, a repo para with just a
|
|
|
|
# config line and no ACLs gets ignored in the output
|
|
|
|
$repos{$repo}{HAS_CONFIG} = 1;
|
2010-09-04 11:33:06 +02:00
|
|
|
}
|
|
|
|
}
|
2011-08-27 17:59:02 +02:00
|
|
|
# include and subconf. subconf is just a special case of "include",
|
|
|
|
# saying that the config parse should "switch" contexts
|
|
|
|
elsif ($line =~ /^(include|subconf) "(.+)"/)
|
2010-09-04 11:33:06 +02:00
|
|
|
{
|
2011-08-27 17:59:02 +02:00
|
|
|
my $include_glob = $2;
|
|
|
|
my $subconf = ( $1 eq 'subconf' );
|
|
|
|
die "$ABRT subconf $fragment attempting to run 'subconf'\n" if $subconf and $fragment ne 'master';
|
|
|
|
|
|
|
|
# substitute HOSTNAME word if GL_HOSTNAME defined, otherwise leave as is
|
|
|
|
$include_glob =~ s/\bHOSTNAME\b/$GL_HOSTNAME/ if $GL_HOSTNAME;
|
|
|
|
|
2011-09-10 15:27:42 +02:00
|
|
|
for my $file (glob($include_glob =~ m(^/) ? $include_glob : "$GL_ADMINDIR/conf/$include_glob")) {
|
2011-08-27 17:59:02 +02:00
|
|
|
warn("$WARN included file not found: '$file'\n"), next unless -f $file;
|
2010-09-04 11:33:06 +02:00
|
|
|
|
2011-04-01 03:09:04 +02:00
|
|
|
my $file_id = device_inode($file);
|
|
|
|
warn("$WARN $file already included\n"), next if ($included{$file_id}++);
|
|
|
|
|
2011-08-27 17:59:02 +02:00
|
|
|
if ($subconf) {
|
|
|
|
die "$ABRT subconf filename should end in .conf\n" unless $file =~ /^.*\/(.*).conf$/;
|
|
|
|
parse_conf_file( $file, $1 );
|
|
|
|
$subconf_seen++;
|
|
|
|
} else {
|
|
|
|
parse_conf_file( $file, $fragment );
|
|
|
|
}
|
2011-04-01 03:09:04 +02:00
|
|
|
}
|
2010-09-04 11:33:06 +02:00
|
|
|
}
|
|
|
|
# very simple syntax for the gitweb description of repo; one of:
|
|
|
|
# reponame = "some description string"
|
|
|
|
# reponame "owner name" = "some description string"
|
|
|
|
elsif ($line =~ /^(\S+)(?: "(.*?)")? = "(.*)"$/)
|
|
|
|
{
|
|
|
|
my ($repo, $owner, $desc) = ($1, $2, $3);
|
2011-10-05 18:31:49 +02:00
|
|
|
die "$ABRT bad repo name '$repo'\n" unless $repo =~ $REPONAME_PATT;
|
2010-11-10 13:37:58 +01:00
|
|
|
die "$ABRT $fragment attempting to set description for $repo\n" if check_fragment_repo_disallowed( $fragment, $repo );
|
2010-09-04 11:33:06 +02:00
|
|
|
$desc{"$repo.git"} = $desc;
|
|
|
|
$owner{"$repo.git"} = $owner || '';
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
die "$ABRT can't make head or tail of '$line'\n";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
sub cleanup_conf_line
|
|
|
|
{
|
|
|
|
my ($line) = @_;
|
|
|
|
|
|
|
|
# kill comments, but take care of "#" inside *simple* strings
|
|
|
|
$line =~ s/^((".*?"|[^#"])*)#.*/$1/;
|
|
|
|
# normalise whitespace; keeps later regexes very simple
|
|
|
|
$line =~ s/=/ = /;
|
|
|
|
$line =~ s/\s+/ /g;
|
|
|
|
$line =~ s/^ //;
|
|
|
|
$line =~ s/ $//;
|
|
|
|
return $line;
|
|
|
|
}
|
|
|
|
|
2009-10-02 18:47:51 +02:00
|
|
|
sub parse_conf_file
|
|
|
|
{
|
2009-10-04 06:26:40 +02:00
|
|
|
my ($conffile, $fragment) = @_;
|
|
|
|
# the second arg, $fragment, is passed in as "master" when parsing the
|
|
|
|
# main config, and the fragment name when parsing a fragment. In the
|
|
|
|
# latter case, the parser uses that information to ignore (and warn about)
|
|
|
|
# any repos in the fragment that are not members of the "repo group" of
|
|
|
|
# the same name.
|
|
|
|
my %ignored = ();
|
|
|
|
|
2009-10-02 18:47:51 +02:00
|
|
|
my $conf_fh = wrap_open( "<", $conffile );
|
2009-08-23 10:16:45 +02:00
|
|
|
|
2009-10-02 18:47:51 +02:00
|
|
|
# the syntax is fairly simple, so we parse it inline
|
2009-08-23 10:16:45 +02:00
|
|
|
|
2009-10-02 18:47:51 +02:00
|
|
|
my @repos;
|
2010-09-04 11:33:06 +02:00
|
|
|
my $line;
|
2009-10-02 18:47:51 +02:00
|
|
|
while (<$conf_fh>)
|
2009-08-23 10:16:45 +02:00
|
|
|
{
|
2010-09-04 11:33:06 +02:00
|
|
|
$line = cleanup_conf_line($_);
|
|
|
|
# skip blank lines
|
|
|
|
next unless $line =~ /\S/;
|
2009-09-27 04:32:36 +02:00
|
|
|
|
2011-08-27 17:59:02 +02:00
|
|
|
# this is how we prevent subconf hacking; we internally prefix all
|
|
|
|
# group names *defined* in the subconf (also if they are later used)
|
|
|
|
# with the subconf name.
|
|
|
|
|
|
|
|
# rules for prefixing the subconf name: prefix it if the @group name
|
|
|
|
# has appeared earlier in this file on the *left side*. Prefix all
|
|
|
|
# left side @group names regardless.
|
|
|
|
|
|
|
|
if ($fragment ne 'master') {
|
|
|
|
my $lhs = '';
|
|
|
|
# save 'foo' if it's an '@foo = list' line
|
|
|
|
$lhs = $1 if $line =~ /^@(\S+) = /;
|
|
|
|
# prefix all @group in the line
|
|
|
|
$line =~ s/(^| )(@\S+)(?= |$)/ $1 . ($prefixed_groupname{$fragment}{$2} || $2) /ge;
|
|
|
|
# now prefix the LHS and store it if needed
|
|
|
|
if ($lhs) {
|
|
|
|
$line =~ s/^@\S+ = /"\@$fragment.$lhs = "/e;
|
|
|
|
$prefixed_groupname{$fragment}{"\@$lhs"} = "\@$fragment.$lhs";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-09-04 11:33:06 +02:00
|
|
|
parse_conf_line( $line, $fragment, \@repos, \%ignored );
|
2009-08-24 10:00:58 +02:00
|
|
|
}
|
2011-08-27 17:59:02 +02:00
|
|
|
# backward compat for delegation
|
|
|
|
parse_conf_line( 'subconf "fragments/*.conf"', $fragment, \@repos, \%ignored )
|
|
|
|
if ($conffile eq $GL_CONF and $fragment eq 'master' and not $subconf_seen);
|
|
|
|
|
2009-10-04 06:26:40 +02:00
|
|
|
for my $ig (sort keys %ignored)
|
|
|
|
{
|
|
|
|
warn "\n\t\t***** WARNING *****\n" .
|
2010-09-04 11:33:06 +02:00
|
|
|
"\t$ig.conf attempting to set access for " .
|
|
|
|
join (", ", sort keys %{ $ignored{$ig} }) . "\n";
|
2009-10-04 06:26:40 +02:00
|
|
|
}
|
2009-08-23 10:16:45 +02:00
|
|
|
}
|
|
|
|
|
2009-10-04 06:26:40 +02:00
|
|
|
# parse the main config file
|
|
|
|
parse_conf_file($GL_CONF, 'master');
|
|
|
|
|
2009-08-23 11:25:50 +02:00
|
|
|
# ----------------------------------------------------------------------------
|
2011-01-01 10:44:54 +01:00
|
|
|
# (that ends the config file compiler, though we postpone the writing
|
|
|
|
# for now to deal with the latest GL_BIG_CONFIG innovation!)
|
2009-08-23 11:25:50 +02:00
|
|
|
# ----------------------------------------------------------------------------
|
|
|
|
|
2010-07-23 13:33:21 +02:00
|
|
|
# ----------------------------------------------------------------------------
|
|
|
|
# what's the git version?
|
|
|
|
# ----------------------------------------------------------------------------
|
|
|
|
|
2011-08-25 15:35:29 +02:00
|
|
|
# we don't like stuff older than 1.6.6
|
2009-08-23 11:25:50 +02:00
|
|
|
|
2009-09-21 04:18:30 +02:00
|
|
|
my $git_version = `git --version`;
|
2010-04-20 17:46:24 +02:00
|
|
|
die "
|
|
|
|
*** ERROR ***
|
|
|
|
did not get a proper version number. Please see if git is in the PATH on
|
|
|
|
the server. If it is not, please edit ~/.gitolite.rc on the server and
|
|
|
|
set the \$GIT_PATH variable to the correct value\n
|
|
|
|
" unless $git_version;
|
2009-09-21 04:18:30 +02:00
|
|
|
my ($gv_maj, $gv_min, $gv_patchrel) = ($git_version =~ m/git version (\d+)\.(\d+)\.(\d+)/);
|
2009-11-03 15:54:53 +01:00
|
|
|
die "$ABRT I can't understand $git_version\n" unless ($gv_maj >= 1);
|
2009-09-21 04:18:30 +02:00
|
|
|
$git_version = $gv_maj*10000 + $gv_min*100 + $gv_patchrel; # now it's "normalised"
|
|
|
|
|
2010-05-14 16:51:04 +02:00
|
|
|
die "\n\t\t***** AAARGH! *****\n" .
|
2011-08-25 15:35:29 +02:00
|
|
|
"\tyour git version is older than 1.6.6\n" .
|
2010-05-14 16:51:04 +02:00
|
|
|
"\tsince that is now more than one year old, and gitolite needs some of\n" .
|
|
|
|
"\tthe newer features, please upgrade.\n"
|
2011-08-25 15:35:29 +02:00
|
|
|
if $git_version < 10606; # that's 1.6.6 to you
|
2010-05-14 16:51:04 +02:00
|
|
|
|
2010-07-23 13:33:21 +02:00
|
|
|
# ----------------------------------------------------------------------------
|
2011-01-01 10:44:54 +01:00
|
|
|
# most of the rest of this program can be "switched off"; see
|
|
|
|
# doc/big-config.mkd for details.
|
2010-07-23 13:33:21 +02:00
|
|
|
# ----------------------------------------------------------------------------
|
|
|
|
|
2011-01-01 10:44:54 +01:00
|
|
|
# process the normal repos in %repos. This includes creating them if needed
|
|
|
|
# (and GL_NO_CREATE_REPOS is not set), checking hooks, and finally, if
|
|
|
|
# GL_BIG_CONFIG is set, writing out the one-repo config file for directly
|
|
|
|
# specified repos (i.e., "repo foo", not "@grp = foo" + "repo @grp")
|
|
|
|
do_normal_repos();
|
|
|
|
write_compiled_conf(); # write out the final compiled config
|
|
|
|
|
|
|
|
# ----------------------------------------------------------------------------
|
|
|
|
# process the normal repos in %repos (create, hook, one_repo config...)
|
|
|
|
# ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
sub do_normal_repos
|
|
|
|
{
|
make REPO_BASE absolute early
$ENV{GL_REPO_BASE_ABS} is meant to point to the same directory as
$REPO_BASE, except it is meant to be passed to hooks, ADCs and other
child programs. And since you can't be sure where the child program
starts in, this became an absolute path.
Gradually, however, I started using it wherever I needed an absolute
path (mostly in code that jumps around various directories to do stuff).
Which is silly, because there's no reason $REPO_BASE cannot also be made
an absolute, even if the rc file has a relative path.
So that's what I did now: made $REPO_BASE absolute very early on, and
then systematically changed all uses of the longer form to the shorter
form when appropriate. And so the only thing we now use the longer one
for is to pass to child programs.
(Implementation note: The actual change is not very big, but while I was
about it I decided to make the test suite able to test with an absolute
REPO_BASE also, which is why the commit seems so large.)
----
This all started with a complaint from Damien Regad. He had an
extremely odd setup where his bashrc changed PWD to something other than
$HOME before anything else ran. This caused those two variables to
beceom inconsistent, and he had a 1-line fix he wanted me to apply.
I generally don't like making special fixes for for non-standard setups,
and anyway all he had to do was set the full path to REPO_BASE in the rc
file to get around this. Which is what I told him and he very politely
left it at that.
However, this did get me thinking, and I soon realised I was needlessly
conflating "relative versus absolute" with "able to be passed to child
programs". Fixing that solved his problem also, as a side-effect.
So I guess this is all thanks to Damien!
2011-03-18 06:29:52 +01:00
|
|
|
wrap_chdir($REPO_BASE);
|
2010-05-14 17:10:59 +02:00
|
|
|
|
2011-01-01 10:44:54 +01:00
|
|
|
# start with the ones that are normal repos in %repos
|
2010-05-14 17:10:59 +02:00
|
|
|
my @repos = grep { $_ =~ $REPONAME_PATT and not /^@/ } sort keys %repos;
|
|
|
|
# then, for each repogroup, find the members of the group and add them in
|
|
|
|
map { push @repos, keys %{ $groups{$_} } } grep { /^@/ } keys %repos;
|
|
|
|
# weed out duplicates (the code in the loop below is disk activity!)
|
|
|
|
my %seen = map { $_ => 1 } @repos;
|
|
|
|
@repos = sort keys %seen;
|
|
|
|
|
|
|
|
for my $repo (sort @repos) {
|
2011-01-01 10:44:54 +01:00
|
|
|
next unless $repo =~ $REPONAME_PATT; # skip repo patterns
|
|
|
|
next if $repo =~ m(^\@|EXTCMD/); # skip groups and fake repos
|
|
|
|
|
|
|
|
unless ($GL_NO_CREATE_REPOS) {
|
|
|
|
unless (-d "$repo.git") {
|
|
|
|
print STDERR "creating $repo...\n";
|
|
|
|
new_repo($repo, "$GL_ADMINDIR/hooks/common");
|
|
|
|
# new_repo would have chdir'd us away; come back
|
make REPO_BASE absolute early
$ENV{GL_REPO_BASE_ABS} is meant to point to the same directory as
$REPO_BASE, except it is meant to be passed to hooks, ADCs and other
child programs. And since you can't be sure where the child program
starts in, this became an absolute path.
Gradually, however, I started using it wherever I needed an absolute
path (mostly in code that jumps around various directories to do stuff).
Which is silly, because there's no reason $REPO_BASE cannot also be made
an absolute, even if the rc file has a relative path.
So that's what I did now: made $REPO_BASE absolute very early on, and
then systematically changed all uses of the longer form to the shorter
form when appropriate. And so the only thing we now use the longer one
for is to pass to child programs.
(Implementation note: The actual change is not very big, but while I was
about it I decided to make the test suite able to test with an absolute
REPO_BASE also, which is why the commit seems so large.)
----
This all started with a complaint from Damien Regad. He had an
extremely odd setup where his bashrc changed PWD to something other than
$HOME before anything else ran. This caused those two variables to
beceom inconsistent, and he had a 1-line fix he wanted me to apply.
I generally don't like making special fixes for for non-standard setups,
and anyway all he had to do was set the full path to REPO_BASE in the rc
file to get around this. Which is what I told him and he very politely
left it at that.
However, this did get me thinking, and I soon realised I was needlessly
conflating "relative versus absolute" with "able to be passed to child
programs". Fixing that solved his problem also, as a side-effect.
So I guess this is all thanks to Damien!
2011-03-18 06:29:52 +01:00
|
|
|
wrap_chdir($REPO_BASE);
|
2011-01-01 10:44:54 +01:00
|
|
|
}
|
2010-03-07 14:35:56 +01:00
|
|
|
|
2011-09-03 06:06:24 +02:00
|
|
|
# detect repos copied from elsewhere by absence of (empty)
|
|
|
|
# sentinel file, and if it doesn't exist run the ln -sf
|
2011-01-01 10:44:54 +01:00
|
|
|
unless (-l "$repo.git/hooks/gitolite-hooked") {
|
|
|
|
ln_sf("$GL_ADMINDIR/hooks/common", "*", "$repo.git/hooks");
|
|
|
|
# in case of package install, GL_ADMINDIR is no longer the top cop;
|
|
|
|
# override with the package hooks
|
|
|
|
ln_sf("$GL_PACKAGE_HOOKS/common", "*", "$repo.git/hooks") if $GL_PACKAGE_HOOKS;
|
|
|
|
}
|
2010-05-14 17:10:59 +02:00
|
|
|
}
|
2011-01-01 10:44:54 +01:00
|
|
|
|
|
|
|
# write a one_repo config for normal repos declared directly (not just via a group)
|
|
|
|
write_1_compiled_conf($repo) if $GL_BIG_CONFIG and $repos{$repo} and -d "$repo.git";
|
2010-03-07 14:35:56 +01:00
|
|
|
}
|
2009-12-01 17:24:23 +01:00
|
|
|
}
|
|
|
|
|
2011-01-01 10:44:54 +01:00
|
|
|
sub write_1_compiled_conf
|
|
|
|
{
|
|
|
|
# warning: writes and *deletes* it from %repos and %git_configs
|
|
|
|
my ($repo) = shift;
|
|
|
|
my (%one_repo, %one_git_config);
|
2009-12-07 21:20:29 +01:00
|
|
|
|
2011-01-01 10:44:54 +01:00
|
|
|
open(my $compiled_fh, ">", "$repo.git/gl-conf") or return;
|
2010-07-23 13:33:21 +02:00
|
|
|
|
2011-01-01 10:44:54 +01:00
|
|
|
$one_repo{$repo} = $repos{$repo};
|
|
|
|
delete $repos{$repo};
|
|
|
|
my $dumped_data = Data::Dumper->Dump([\%one_repo], [qw(*one_repo)]);
|
2010-06-25 20:06:15 +02:00
|
|
|
|
2011-01-01 10:44:54 +01:00
|
|
|
if ($git_configs{$repo}) {
|
|
|
|
$one_git_config{$repo} = $git_configs{$repo};
|
|
|
|
delete $git_configs{$repo};
|
|
|
|
$dumped_data .= Data::Dumper->Dump([\%one_git_config], [qw(*one_git_config)]);
|
|
|
|
}
|
|
|
|
|
|
|
|
# the dump uses single quotes, but we convert any strings containing $creator
|
|
|
|
# and $gl_user to double quoted strings. A bit sneaky, but not too much...
|
|
|
|
$dumped_data =~ s/'(?=[^']*\$(?:creator|gl_user))~?(.*?)'/"$1"/g;
|
|
|
|
print $compiled_fh $dumped_data;
|
|
|
|
close $compiled_fh;
|
|
|
|
|
|
|
|
$split_conf{$repo} = 1;
|
|
|
|
}
|
|
|
|
|
2011-01-15 16:39:56 +01:00
|
|
|
sub write_compiled_conf
|
|
|
|
{
|
|
|
|
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([\%git_configs], [qw(*git_configs)]) if %git_configs;
|
|
|
|
# the dump uses single quotes, but we convert any strings containing $creator
|
|
|
|
# and $gl_user to double quoted strings. A bit sneaky, but not too much...
|
|
|
|
$dumped_data =~ s/'(?=[^']*\$(?:creator|gl_user))~?(.*?)'/"$1"/g;
|
|
|
|
print $compiled_fh $dumped_data;
|
|
|
|
if (%groups) {
|
|
|
|
$dumped_data = Data::Dumper->Dump([\%groups], [qw(*groups)]);
|
|
|
|
$dumped_data =~ s/\bCREAT[EO]R\b/\$creator/g;
|
|
|
|
$dumped_data =~ s/'(?=[^']*\$(?:creator|gl_user))~?(.*?)'/"$1"/g;
|
|
|
|
print $compiled_fh $dumped_data;
|
|
|
|
}
|
|
|
|
print $compiled_fh Data::Dumper->Dump([\%split_conf], [qw(*split_conf)]) if %split_conf;
|
|
|
|
close $compiled_fh or die "$ABRT close compiled-conf failed: $!\n";
|
|
|
|
rename "$GL_CONF_COMPILED.new", "$GL_CONF_COMPILED";
|
|
|
|
}
|
|
|
|
|
2011-01-01 10:44:54 +01:00
|
|
|
# ----------------------------------------------------------------------------
|
|
|
|
# get a list of physical repos for later
|
|
|
|
# ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
my @phy_repos = ();
|
2011-01-15 16:39:56 +01:00
|
|
|
@phy_repos = list_phy_repos() unless $GL_NO_DAEMON_NO_GITWEB;
|
gitweb/daemon now work for wild repos also
(thanks to Kevin Fleming for the need/use case)
TODO: tests
TODO: proper documentation; meanwhile, just read this:
- you can give gitweb and daemon read rights to wild card repos also,
and it'll all just work -- when a new repo is 'C'reated, it'll pick
up those rights etc
- you can assign descriptions (and owners) to individual repos as
before, except now you can assign them to repos that actually were
created from wild card patterns. So for example, you can define
rules for
repo foo/..*
and then assign descriptions like
foo/repo1 = "repo one"
foo/repo2 = "repo two"
foo/dil "scott" = "scott's dilbert repo"
However, this only works for repos that already exist, and only when
you push the admin repo.
Thumb rule: have the user create his wild repo, *then* add and push
the admin config file with the description. Not the other way
around.
implementation notes:
- wildcard support for git config revamped, refactored...
it's not just git config that needs wildcard support. daemon and
gitweb access also will be needing it soon, so we start by factoring
out the part that finds the "pattern" given a "real" repo name.
- GL_NO_DAEMON_NO_GITWEB now gates more than just those two things;
see doc/big-config.mkd for details
- we trawl through $GL_REPO_BASE_ABS *once* only, collecting repo
names and tying them to either the same name or to a wild pattern
that the repo name was created from
- nice little subs to setup gitweb, daemon, and git config
- god bless $GL_REPOPATT and the day I decided to set that env var
whenever a user hits a wild repo in any way :-)
- the code in gl-compile-conf is very simple now. Much nicer than
before
2010-07-16 19:31:34 +02:00
|
|
|
|
|
|
|
# NOTE: we're overloading GL_NO_DAEMON_NO_GITWEB to mean "no git config" also.
|
|
|
|
# In fact anything that requires trawling through the existing repos doing
|
|
|
|
# stuff to all of them is skipped if this variable is set. This is primarily
|
|
|
|
# for the Fedora folks, but it should be useful for anyone who has a huge set
|
|
|
|
# of repos and wants to manage gitweb/daemon/etc access via other means (they
|
|
|
|
# typically have the whole thing controlled by a web-app and a database
|
|
|
|
# anyway, and gitolite is only doing the access control and nothing more).
|
2009-12-07 21:20:29 +01:00
|
|
|
|
2009-08-24 10:00:58 +02:00
|
|
|
# ----------------------------------------------------------------------------
|
gitweb/daemon now work for wild repos also
(thanks to Kevin Fleming for the need/use case)
TODO: tests
TODO: proper documentation; meanwhile, just read this:
- you can give gitweb and daemon read rights to wild card repos also,
and it'll all just work -- when a new repo is 'C'reated, it'll pick
up those rights etc
- you can assign descriptions (and owners) to individual repos as
before, except now you can assign them to repos that actually were
created from wild card patterns. So for example, you can define
rules for
repo foo/..*
and then assign descriptions like
foo/repo1 = "repo one"
foo/repo2 = "repo two"
foo/dil "scott" = "scott's dilbert repo"
However, this only works for repos that already exist, and only when
you push the admin repo.
Thumb rule: have the user create his wild repo, *then* add and push
the admin config file with the description. Not the other way
around.
implementation notes:
- wildcard support for git config revamped, refactored...
it's not just git config that needs wildcard support. daemon and
gitweb access also will be needing it soon, so we start by factoring
out the part that finds the "pattern" given a "real" repo name.
- GL_NO_DAEMON_NO_GITWEB now gates more than just those two things;
see doc/big-config.mkd for details
- we trawl through $GL_REPO_BASE_ABS *once* only, collecting repo
names and tying them to either the same name or to a wild pattern
that the repo name was created from
- nice little subs to setup gitweb, daemon, and git config
- god bless $GL_REPOPATT and the day I decided to set that env var
whenever a user hits a wild repo in any way :-)
- the code in gl-compile-conf is very simple now. Much nicer than
before
2010-07-16 19:31:34 +02:00
|
|
|
# various updates to all real repos
|
2009-09-25 08:47:33 +02:00
|
|
|
# ----------------------------------------------------------------------------
|
|
|
|
|
gitweb/daemon now work for wild repos also
(thanks to Kevin Fleming for the need/use case)
TODO: tests
TODO: proper documentation; meanwhile, just read this:
- you can give gitweb and daemon read rights to wild card repos also,
and it'll all just work -- when a new repo is 'C'reated, it'll pick
up those rights etc
- you can assign descriptions (and owners) to individual repos as
before, except now you can assign them to repos that actually were
created from wild card patterns. So for example, you can define
rules for
repo foo/..*
and then assign descriptions like
foo/repo1 = "repo one"
foo/repo2 = "repo two"
foo/dil "scott" = "scott's dilbert repo"
However, this only works for repos that already exist, and only when
you push the admin repo.
Thumb rule: have the user create his wild repo, *then* add and push
the admin config file with the description. Not the other way
around.
implementation notes:
- wildcard support for git config revamped, refactored...
it's not just git config that needs wildcard support. daemon and
gitweb access also will be needing it soon, so we start by factoring
out the part that finds the "pattern" given a "real" repo name.
- GL_NO_DAEMON_NO_GITWEB now gates more than just those two things;
see doc/big-config.mkd for details
- we trawl through $GL_REPO_BASE_ABS *once* only, collecting repo
names and tying them to either the same name or to a wild pattern
that the repo name was created from
- nice little subs to setup gitweb, daemon, and git config
- god bless $GL_REPOPATT and the day I decided to set that env var
whenever a user hits a wild repo in any way :-)
- the code in gl-compile-conf is very simple now. Much nicer than
before
2010-07-16 19:31:34 +02:00
|
|
|
# ----------------------------------------------------------------------------
|
|
|
|
# update repo configurations, gitweb description, daemon export-ok, etc
|
|
|
|
# ----------------------------------------------------------------------------
|
2009-09-25 08:47:33 +02:00
|
|
|
|
gitweb/daemon now work for wild repos also
(thanks to Kevin Fleming for the need/use case)
TODO: tests
TODO: proper documentation; meanwhile, just read this:
- you can give gitweb and daemon read rights to wild card repos also,
and it'll all just work -- when a new repo is 'C'reated, it'll pick
up those rights etc
- you can assign descriptions (and owners) to individual repos as
before, except now you can assign them to repos that actually were
created from wild card patterns. So for example, you can define
rules for
repo foo/..*
and then assign descriptions like
foo/repo1 = "repo one"
foo/repo2 = "repo two"
foo/dil "scott" = "scott's dilbert repo"
However, this only works for repos that already exist, and only when
you push the admin repo.
Thumb rule: have the user create his wild repo, *then* add and push
the admin config file with the description. Not the other way
around.
implementation notes:
- wildcard support for git config revamped, refactored...
it's not just git config that needs wildcard support. daemon and
gitweb access also will be needing it soon, so we start by factoring
out the part that finds the "pattern" given a "real" repo name.
- GL_NO_DAEMON_NO_GITWEB now gates more than just those two things;
see doc/big-config.mkd for details
- we trawl through $GL_REPO_BASE_ABS *once* only, collecting repo
names and tying them to either the same name or to a wild pattern
that the repo name was created from
- nice little subs to setup gitweb, daemon, and git config
- god bless $GL_REPOPATT and the day I decided to set that env var
whenever a user hits a wild repo in any way :-)
- the code in gl-compile-conf is very simple now. Much nicer than
before
2010-07-16 19:31:34 +02:00
|
|
|
my %projlist = ();
|
2009-09-25 08:47:33 +02:00
|
|
|
|
gitweb/daemon now work for wild repos also
(thanks to Kevin Fleming for the need/use case)
TODO: tests
TODO: proper documentation; meanwhile, just read this:
- you can give gitweb and daemon read rights to wild card repos also,
and it'll all just work -- when a new repo is 'C'reated, it'll pick
up those rights etc
- you can assign descriptions (and owners) to individual repos as
before, except now you can assign them to repos that actually were
created from wild card patterns. So for example, you can define
rules for
repo foo/..*
and then assign descriptions like
foo/repo1 = "repo one"
foo/repo2 = "repo two"
foo/dil "scott" = "scott's dilbert repo"
However, this only works for repos that already exist, and only when
you push the admin repo.
Thumb rule: have the user create his wild repo, *then* add and push
the admin config file with the description. Not the other way
around.
implementation notes:
- wildcard support for git config revamped, refactored...
it's not just git config that needs wildcard support. daemon and
gitweb access also will be needing it soon, so we start by factoring
out the part that finds the "pattern" given a "real" repo name.
- GL_NO_DAEMON_NO_GITWEB now gates more than just those two things;
see doc/big-config.mkd for details
- we trawl through $GL_REPO_BASE_ABS *once* only, collecting repo
names and tying them to either the same name or to a wild pattern
that the repo name was created from
- nice little subs to setup gitweb, daemon, and git config
- god bless $GL_REPOPATT and the day I decided to set that env var
whenever a user hits a wild repo in any way :-)
- the code in gl-compile-conf is very simple now. Much nicer than
before
2010-07-16 19:31:34 +02:00
|
|
|
# for each real repo (and remember this will be empty, thus skipping all this,
|
|
|
|
# if $GL_NO_DAEMON_NO_GITWEB is on!)
|
2010-02-03 09:13:47 +01:00
|
|
|
|
2010-08-25 19:40:31 +02:00
|
|
|
# note: we do them in 2 separate loops to avoid breaking the optimisation in
|
|
|
|
# sub parse_acl (look for variable $saved_crwu)
|
gitweb/daemon now work for wild repos also
(thanks to Kevin Fleming for the need/use case)
TODO: tests
TODO: proper documentation; meanwhile, just read this:
- you can give gitweb and daemon read rights to wild card repos also,
and it'll all just work -- when a new repo is 'C'reated, it'll pick
up those rights etc
- you can assign descriptions (and owners) to individual repos as
before, except now you can assign them to repos that actually were
created from wild card patterns. So for example, you can define
rules for
repo foo/..*
and then assign descriptions like
foo/repo1 = "repo one"
foo/repo2 = "repo two"
foo/dil "scott" = "scott's dilbert repo"
However, this only works for repos that already exist, and only when
you push the admin repo.
Thumb rule: have the user create his wild repo, *then* add and push
the admin config file with the description. Not the other way
around.
implementation notes:
- wildcard support for git config revamped, refactored...
it's not just git config that needs wildcard support. daemon and
gitweb access also will be needing it soon, so we start by factoring
out the part that finds the "pattern" given a "real" repo name.
- GL_NO_DAEMON_NO_GITWEB now gates more than just those two things;
see doc/big-config.mkd for details
- we trawl through $GL_REPO_BASE_ABS *once* only, collecting repo
names and tying them to either the same name or to a wild pattern
that the repo name was created from
- nice little subs to setup gitweb, daemon, and git config
- god bless $GL_REPOPATT and the day I decided to set that env var
whenever a user hits a wild repo in any way :-)
- the code in gl-compile-conf is very simple now. Much nicer than
before
2010-07-16 19:31:34 +02:00
|
|
|
|
2011-01-01 10:44:54 +01:00
|
|
|
for my $repo (@phy_repos) {
|
make REPO_BASE absolute early
$ENV{GL_REPO_BASE_ABS} is meant to point to the same directory as
$REPO_BASE, except it is meant to be passed to hooks, ADCs and other
child programs. And since you can't be sure where the child program
starts in, this became an absolute path.
Gradually, however, I started using it wherever I needed an absolute
path (mostly in code that jumps around various directories to do stuff).
Which is silly, because there's no reason $REPO_BASE cannot also be made
an absolute, even if the rc file has a relative path.
So that's what I did now: made $REPO_BASE absolute very early on, and
then systematically changed all uses of the longer form to the shorter
form when appropriate. And so the only thing we now use the longer one
for is to pass to child programs.
(Implementation note: The actual change is not very big, but while I was
about it I decided to make the test suite able to test with an absolute
REPO_BASE also, which is why the commit seems so large.)
----
This all started with a complaint from Damien Regad. He had an
extremely odd setup where his bashrc changed PWD to something other than
$HOME before anything else ran. This caused those two variables to
beceom inconsistent, and he had a 1-line fix he wanted me to apply.
I generally don't like making special fixes for for non-standard setups,
and anyway all he had to do was set the full path to REPO_BASE in the rc
file to get around this. Which is what I told him and he very politely
left it at that.
However, this did get me thinking, and I soon realised I was needlessly
conflating "relative versus absolute" with "able to be passed to child
programs". Fixing that solved his problem also, as a side-effect.
So I guess this is all thanks to Damien!
2011-03-18 06:29:52 +01:00
|
|
|
wrap_chdir("$REPO_BASE/$repo.git");
|
gitweb/daemon now work for wild repos also
(thanks to Kevin Fleming for the need/use case)
TODO: tests
TODO: proper documentation; meanwhile, just read this:
- you can give gitweb and daemon read rights to wild card repos also,
and it'll all just work -- when a new repo is 'C'reated, it'll pick
up those rights etc
- you can assign descriptions (and owners) to individual repos as
before, except now you can assign them to repos that actually were
created from wild card patterns. So for example, you can define
rules for
repo foo/..*
and then assign descriptions like
foo/repo1 = "repo one"
foo/repo2 = "repo two"
foo/dil "scott" = "scott's dilbert repo"
However, this only works for repos that already exist, and only when
you push the admin repo.
Thumb rule: have the user create his wild repo, *then* add and push
the admin config file with the description. Not the other way
around.
implementation notes:
- wildcard support for git config revamped, refactored...
it's not just git config that needs wildcard support. daemon and
gitweb access also will be needing it soon, so we start by factoring
out the part that finds the "pattern" given a "real" repo name.
- GL_NO_DAEMON_NO_GITWEB now gates more than just those two things;
see doc/big-config.mkd for details
- we trawl through $GL_REPO_BASE_ABS *once* only, collecting repo
names and tying them to either the same name or to a wild pattern
that the repo name was created from
- nice little subs to setup gitweb, daemon, and git config
- god bless $GL_REPOPATT and the day I decided to set that env var
whenever a user hits a wild repo in any way :-)
- the code in gl-compile-conf is very simple now. Much nicer than
before
2010-07-16 19:31:34 +02:00
|
|
|
# daemon is easy
|
2011-01-15 16:39:56 +01:00
|
|
|
setup_daemon_access($repo);
|
2010-08-25 19:40:31 +02:00
|
|
|
}
|
gitweb/daemon now work for wild repos also
(thanks to Kevin Fleming for the need/use case)
TODO: tests
TODO: proper documentation; meanwhile, just read this:
- you can give gitweb and daemon read rights to wild card repos also,
and it'll all just work -- when a new repo is 'C'reated, it'll pick
up those rights etc
- you can assign descriptions (and owners) to individual repos as
before, except now you can assign them to repos that actually were
created from wild card patterns. So for example, you can define
rules for
repo foo/..*
and then assign descriptions like
foo/repo1 = "repo one"
foo/repo2 = "repo two"
foo/dil "scott" = "scott's dilbert repo"
However, this only works for repos that already exist, and only when
you push the admin repo.
Thumb rule: have the user create his wild repo, *then* add and push
the admin config file with the description. Not the other way
around.
implementation notes:
- wildcard support for git config revamped, refactored...
it's not just git config that needs wildcard support. daemon and
gitweb access also will be needing it soon, so we start by factoring
out the part that finds the "pattern" given a "real" repo name.
- GL_NO_DAEMON_NO_GITWEB now gates more than just those two things;
see doc/big-config.mkd for details
- we trawl through $GL_REPO_BASE_ABS *once* only, collecting repo
names and tying them to either the same name or to a wild pattern
that the repo name was created from
- nice little subs to setup gitweb, daemon, and git config
- god bless $GL_REPOPATT and the day I decided to set that env var
whenever a user hits a wild repo in any way :-)
- the code in gl-compile-conf is very simple now. Much nicer than
before
2010-07-16 19:31:34 +02:00
|
|
|
|
2011-01-01 10:44:54 +01:00
|
|
|
for my $repo (@phy_repos) {
|
make REPO_BASE absolute early
$ENV{GL_REPO_BASE_ABS} is meant to point to the same directory as
$REPO_BASE, except it is meant to be passed to hooks, ADCs and other
child programs. And since you can't be sure where the child program
starts in, this became an absolute path.
Gradually, however, I started using it wherever I needed an absolute
path (mostly in code that jumps around various directories to do stuff).
Which is silly, because there's no reason $REPO_BASE cannot also be made
an absolute, even if the rc file has a relative path.
So that's what I did now: made $REPO_BASE absolute very early on, and
then systematically changed all uses of the longer form to the shorter
form when appropriate. And so the only thing we now use the longer one
for is to pass to child programs.
(Implementation note: The actual change is not very big, but while I was
about it I decided to make the test suite able to test with an absolute
REPO_BASE also, which is why the commit seems so large.)
----
This all started with a complaint from Damien Regad. He had an
extremely odd setup where his bashrc changed PWD to something other than
$HOME before anything else ran. This caused those two variables to
beceom inconsistent, and he had a 1-line fix he wanted me to apply.
I generally don't like making special fixes for for non-standard setups,
and anyway all he had to do was set the full path to REPO_BASE in the rc
file to get around this. Which is what I told him and he very politely
left it at that.
However, this did get me thinking, and I soon realised I was needlessly
conflating "relative versus absolute" with "able to be passed to child
programs". Fixing that solved his problem also, as a side-effect.
So I guess this is all thanks to Damien!
2011-03-18 06:29:52 +01:00
|
|
|
wrap_chdir("$REPO_BASE/$repo.git");
|
gitweb/daemon now work for wild repos also
(thanks to Kevin Fleming for the need/use case)
TODO: tests
TODO: proper documentation; meanwhile, just read this:
- you can give gitweb and daemon read rights to wild card repos also,
and it'll all just work -- when a new repo is 'C'reated, it'll pick
up those rights etc
- you can assign descriptions (and owners) to individual repos as
before, except now you can assign them to repos that actually were
created from wild card patterns. So for example, you can define
rules for
repo foo/..*
and then assign descriptions like
foo/repo1 = "repo one"
foo/repo2 = "repo two"
foo/dil "scott" = "scott's dilbert repo"
However, this only works for repos that already exist, and only when
you push the admin repo.
Thumb rule: have the user create his wild repo, *then* add and push
the admin config file with the description. Not the other way
around.
implementation notes:
- wildcard support for git config revamped, refactored...
it's not just git config that needs wildcard support. daemon and
gitweb access also will be needing it soon, so we start by factoring
out the part that finds the "pattern" given a "real" repo name.
- GL_NO_DAEMON_NO_GITWEB now gates more than just those two things;
see doc/big-config.mkd for details
- we trawl through $GL_REPO_BASE_ABS *once* only, collecting repo
names and tying them to either the same name or to a wild pattern
that the repo name was created from
- nice little subs to setup gitweb, daemon, and git config
- god bless $GL_REPOPATT and the day I decided to set that env var
whenever a user hits a wild repo in any way :-)
- the code in gl-compile-conf is very simple now. Much nicer than
before
2010-07-16 19:31:34 +02:00
|
|
|
# gitweb is a little more complicated. Here're some notes:
|
|
|
|
# - "setup_gitweb_access" also sets "owner", despite the name
|
|
|
|
# - specifying a description also counts as enabling gitweb
|
|
|
|
# - description and owner are not specified for wildrepos; they're
|
|
|
|
# specified for *actual* repos, even if the repo was created by a
|
2011-01-27 14:57:36 +01:00
|
|
|
# wild card spec and "C" permissions. If you see the docs for the
|
|
|
|
# gitolite.conf file, you will see that repo owner/desc don't go
|
gitweb/daemon now work for wild repos also
(thanks to Kevin Fleming for the need/use case)
TODO: tests
TODO: proper documentation; meanwhile, just read this:
- you can give gitweb and daemon read rights to wild card repos also,
and it'll all just work -- when a new repo is 'C'reated, it'll pick
up those rights etc
- you can assign descriptions (and owners) to individual repos as
before, except now you can assign them to repos that actually were
created from wild card patterns. So for example, you can define
rules for
repo foo/..*
and then assign descriptions like
foo/repo1 = "repo one"
foo/repo2 = "repo two"
foo/dil "scott" = "scott's dilbert repo"
However, this only works for repos that already exist, and only when
you push the admin repo.
Thumb rule: have the user create his wild repo, *then* add and push
the admin config file with the description. Not the other way
around.
implementation notes:
- wildcard support for git config revamped, refactored...
it's not just git config that needs wildcard support. daemon and
gitweb access also will be needing it soon, so we start by factoring
out the part that finds the "pattern" given a "real" repo name.
- GL_NO_DAEMON_NO_GITWEB now gates more than just those two things;
see doc/big-config.mkd for details
- we trawl through $GL_REPO_BASE_ABS *once* only, collecting repo
names and tying them to either the same name or to a wild pattern
that the repo name was created from
- nice little subs to setup gitweb, daemon, and git config
- god bless $GL_REPOPATT and the day I decided to set that env var
whenever a user hits a wild repo in any way :-)
- the code in gl-compile-conf is very simple now. Much nicer than
before
2010-07-16 19:31:34 +02:00
|
|
|
# into the "repo foo" section; they're essentialy independent.
|
|
|
|
# Anyway, I believe it doesn't make sense to have all wild repos
|
|
|
|
# (for some pattern) to have the same description and owner.
|
2011-01-15 16:39:56 +01:00
|
|
|
$projlist{"$repo.git"} = 1 if setup_gitweb_access($repo, $desc{"$repo.git"} || '', $owner{"$repo.git"} || '');
|
2010-07-19 13:17:38 +02:00
|
|
|
|
|
|
|
# git config
|
|
|
|
# implementation note: this must happen *after* one of the previous 2
|
|
|
|
# calls (setup daemon or gitweb). The reason is that they call
|
|
|
|
# "can_read", which eventually calls parse_acl with the right "creator"
|
2010-08-25 19:40:31 +02:00
|
|
|
# set for the *current* repo, which in turn stores translated values for
|
2011-01-01 07:02:58 +01:00
|
|
|
# $creator in the git_configs hash, which, (phew!) is needed for a match
|
|
|
|
# that eventually gets you a valid $git_configs{} below
|
2011-01-15 16:39:56 +01:00
|
|
|
setup_git_configs($repo, \%git_configs) if $git_configs{$repo};
|
2009-11-27 08:53:48 +01:00
|
|
|
}
|
2009-09-25 08:47:33 +02:00
|
|
|
|
2011-03-10 17:18:28 +01:00
|
|
|
# write out the project list, but not if GL_NO_DAEMON_NO_GITWEB is set
|
|
|
|
unless ($GL_NO_DAEMON_NO_GITWEB) {
|
2011-10-01 16:02:21 +02:00
|
|
|
setup_web_access(\%projlist);
|
|
|
|
|
gitweb/daemon now work for wild repos also
(thanks to Kevin Fleming for the need/use case)
TODO: tests
TODO: proper documentation; meanwhile, just read this:
- you can give gitweb and daemon read rights to wild card repos also,
and it'll all just work -- when a new repo is 'C'reated, it'll pick
up those rights etc
- you can assign descriptions (and owners) to individual repos as
before, except now you can assign them to repos that actually were
created from wild card patterns. So for example, you can define
rules for
repo foo/..*
and then assign descriptions like
foo/repo1 = "repo one"
foo/repo2 = "repo two"
foo/dil "scott" = "scott's dilbert repo"
However, this only works for repos that already exist, and only when
you push the admin repo.
Thumb rule: have the user create his wild repo, *then* add and push
the admin config file with the description. Not the other way
around.
implementation notes:
- wildcard support for git config revamped, refactored...
it's not just git config that needs wildcard support. daemon and
gitweb access also will be needing it soon, so we start by factoring
out the part that finds the "pattern" given a "real" repo name.
- GL_NO_DAEMON_NO_GITWEB now gates more than just those two things;
see doc/big-config.mkd for details
- we trawl through $GL_REPO_BASE_ABS *once* only, collecting repo
names and tying them to either the same name or to a wild pattern
that the repo name was created from
- nice little subs to setup gitweb, daemon, and git config
- god bless $GL_REPOPATT and the day I decided to set that env var
whenever a user hits a wild repo in any way :-)
- the code in gl-compile-conf is very simple now. Much nicer than
before
2010-07-16 19:31:34 +02:00
|
|
|
}
|
|
|
|
|
2009-09-25 08:47:33 +02:00
|
|
|
# ----------------------------------------------------------------------------
|
2009-08-24 10:00:58 +02:00
|
|
|
# "compile" ssh authorized_keys
|
|
|
|
# ----------------------------------------------------------------------------
|
|
|
|
|
2010-07-25 17:25:32 +02:00
|
|
|
unless ($GL_NO_SETUP_AUTHKEYS) {
|
2011-01-15 16:39:56 +01:00
|
|
|
setup_authkeys($GL_KEYDIR, \%user_list);
|
2009-08-24 10:00:58 +02:00
|
|
|
}
|