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
|
|
|
|
|
|
|
# === add-auth-keys ===
|
|
|
|
|
2009-08-26 02:47:27 +02:00
|
|
|
# part of the gitolite (GL) suite
|
2009-08-23 07:35:14 +02:00
|
|
|
|
2009-08-23 10:16:45 +02:00
|
|
|
# (1) - "compiles" ~/.ssh/authorized_keys from the list of pub-keys
|
|
|
|
# (2) - also "compiles" the user-friendly GL conf file into something easier
|
|
|
|
# to parse. We're doing this because both the gl-auth-command and the
|
|
|
|
# (gl-)update hook need this, and it seems easier to do this than
|
|
|
|
# replicate the parsing code in both those places. As a bonus, it's
|
|
|
|
# probably more efficient.
|
2009-09-25 08:47:33 +02:00
|
|
|
# (3) - finally does what I have resisted doing all along -- handle gitweb and
|
|
|
|
# git-daemon access. It won't *setup* gitweb/daemon for you -- you have
|
|
|
|
# to that yourself. What this does is make sure that "repo.git"
|
|
|
|
# contains the file "git-daemon-export-ok" (for daemon case) and the
|
|
|
|
# line "repo.git" exists in the "projects.list" file (for gitweb case).
|
2009-08-23 10:16:45 +02:00
|
|
|
|
2009-08-23 07:35:14 +02:00
|
|
|
# how run: manual, by GL admin
|
2009-08-23 10:16:45 +02:00
|
|
|
# when:
|
2009-08-23 11:25:50 +02:00
|
|
|
# - anytime a pubkey is added/deleted
|
2009-08-26 02:47:27 +02:00
|
|
|
# - anytime gitolite.conf is changed
|
2009-08-23 10:16:45 +02:00
|
|
|
# input:
|
2009-12-04 16:04:40 +01:00
|
|
|
# - GL_CONF (default: ~/.gitolite/conf/gitolite.conf)
|
2009-08-26 02:47:27 +02:00
|
|
|
# - GL_KEYDIR (default: ~/.gitolite/keydir)
|
2009-08-23 10:16:45 +02:00
|
|
|
# output:
|
2009-08-23 11:25:50 +02:00
|
|
|
# - ~/.ssh/authorized_keys (dictated by sshd)
|
2009-12-04 16:04:40 +01:00
|
|
|
# - GL_CONF_COMPILED (default: ~/.gitolite/conf/gitolite.conf-compiled.pm)
|
2009-08-23 07:35:14 +02:00
|
|
|
# security:
|
|
|
|
# - touches a very critical system file that manages the restrictions on
|
|
|
|
# incoming users. Be sure to audit AUTH_COMMAND and AUTH_OPTIONS (see
|
|
|
|
# below) on any change to this script
|
|
|
|
# - no security checks within program. The GL admin runs this manually
|
|
|
|
|
2009-08-23 10:16:45 +02:00
|
|
|
# warnings:
|
2009-08-23 07:35:14 +02:00
|
|
|
# - if the "start" line exists, but the "end" line does not, you lose the
|
|
|
|
# rest of the existing authkey file. In general, "don't do that (TM)",
|
|
|
|
# but we do have a "vim -d" popping up so you can see the changes being
|
|
|
|
# made, just in case...
|
|
|
|
|
2009-08-23 11:25:50 +02:00
|
|
|
# ----------------------------------------------------------------------------
|
|
|
|
# common definitions
|
|
|
|
# ----------------------------------------------------------------------------
|
|
|
|
|
2009-10-25 13:03:06 +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-12-04 05:21:22 +01:00
|
|
|
# these are set by the "rc" file
|
2010-06-25 20:06:15 +02:00
|
|
|
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);
|
2009-12-04 05:21:22 +01:00
|
|
|
# and these are set by gitolite.pm
|
2010-07-25 17:25:32 +02:00
|
|
|
our ($REPONAME_PATT, $REPOPATT_PATT, $USERNAME_PATT, $ABRT, $WARN);
|
2009-09-15 17:32:23 +02:00
|
|
|
|
2009-10-25 03:59:52 +01:00
|
|
|
# the common setup module is in the same directory as this running program is
|
|
|
|
my $bindir = $0;
|
|
|
|
$bindir =~ s/\/[^\/]+$//;
|
2010-02-09 12:30:01 +01:00
|
|
|
$bindir = "$ENV{PWD}/$bindir" unless $bindir =~ /^\//;
|
2009-10-25 03:59:52 +01:00
|
|
|
require "$bindir/gitolite.pm";
|
|
|
|
|
|
|
|
# ask where the rc file is, get it, and "do" it
|
|
|
|
&where_is_rc();
|
2009-11-03 15:54:53 +01:00
|
|
|
die "$ABRT parse $ENV{GL_RC} failed: " . ($! or $@) unless do $ENV{GL_RC};
|
2009-08-23 11:25:50 +02:00
|
|
|
|
2009-10-13 06:32:45 +02:00
|
|
|
# add a custom path for git binaries, if specified
|
|
|
|
$ENV{PATH} .= ":$GIT_PATH" if $GIT_PATH;
|
|
|
|
|
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).
|
2009-11-23 18:15:00 +01:00
|
|
|
our %groups = ();
|
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 :)
|
2009-08-25 05:38:11 +02:00
|
|
|
my %repos = ();
|
2009-10-05 16:51:33 +02:00
|
|
|
|
(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
|
|
|
# rule sequence number
|
|
|
|
my $rule_seq = 0;
|
|
|
|
|
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 = ();
|
|
|
|
|
2010-05-21 10:38:05 +02:00
|
|
|
our $current_data_version; # this comes from gitolite.pm
|
|
|
|
|
2009-10-05 16:51:33 +02:00
|
|
|
# catch usernames<->pubkeys mismatches; search for "lint" below
|
|
|
|
my %user_list = ();
|
2009-08-23 10:16:45 +02:00
|
|
|
|
2009-12-07 21:20:29 +01:00
|
|
|
# repo configurations
|
|
|
|
my %repo_config = ();
|
|
|
|
|
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
|
|
|
|
2009-09-21 11:11:37 +02:00
|
|
|
# set the umask before creating any files
|
|
|
|
umask($REPO_UMASK);
|
2009-08-25 03:36:36 +02:00
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
if ($item =~ /^@/) # nested group
|
|
|
|
{
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
# ----------------------------------------------------------------------------
|
|
|
|
# "compile" GL conf
|
|
|
|
# ----------------------------------------------------------------------------
|
|
|
|
|
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;
|
|
|
|
while (<$conf_fh>)
|
2009-08-23 10:16:45 +02:00
|
|
|
{
|
2010-01-23 10:27:22 +01:00
|
|
|
# kill comments, but take care of "#" inside *simple* strings
|
|
|
|
s/^((".*?"|[^#"])*)#.*/$1/;
|
2009-10-02 18:47:51 +02:00
|
|
|
# normalise whitespace; keeps later regexes very simple
|
|
|
|
s/=/ = /;
|
|
|
|
s/\s+/ /g;
|
|
|
|
s/^ //;
|
|
|
|
s/ $//;
|
|
|
|
# and blank lines
|
|
|
|
next unless /\S/;
|
|
|
|
|
|
|
|
# user or repo groups
|
|
|
|
if (/^(@\S+) = (.*)/)
|
|
|
|
{
|
2010-05-12 18:39:51 +02:00
|
|
|
die "$ABRT defining groups is not allowed inside fragments\n"
|
|
|
|
if $GL_BIG_CONFIG and $fragment ne 'master';
|
2009-10-04 06:26:40 +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) ) );
|
2009-11-03 15:54:53 +01:00
|
|
|
die "$ABRT bad group $1\n" unless $1 =~ $REPONAME_PATT;
|
2009-10-02 18:47:51 +02:00
|
|
|
}
|
|
|
|
# repo(s)
|
|
|
|
elsif (/^repo (.*)/)
|
|
|
|
{
|
2010-05-10 08:16:47 +02:00
|
|
|
# grab the list...
|
2009-10-02 18:47:51 +02:00
|
|
|
@repos = split ' ', $1;
|
2010-03-23 17:50:34 +01:00
|
|
|
unless (@repos == 1 and $repos[0] eq '@all') {
|
2010-05-10 08:16:47 +02:00
|
|
|
# ...expand groups in the default case
|
|
|
|
@repos = expand_list ( @repos ) unless $GL_BIG_CONFIG;
|
|
|
|
# ...sanity check
|
2010-04-25 10:19:19 +02:00
|
|
|
for (@repos) {
|
|
|
|
die "$ABRT bad reponame $_\n"
|
|
|
|
if ($GL_WILDREPOS and $_ !~ $REPOPATT_PATT);
|
|
|
|
die "$ABRT bad reponame $_ or you forgot to set \$GL_WILDREPOS\n"
|
|
|
|
if (not $GL_WILDREPOS and $_ !~ $REPONAME_PATT);
|
|
|
|
}
|
2009-12-21 00:55:45 +01:00
|
|
|
}
|
2010-04-25 19:09:27 +02:00
|
|
|
s/\bCREAT[EO]R\b/\$creator/g for @repos;
|
2009-10-02 18:47:51 +02:00
|
|
|
}
|
|
|
|
# actual permission line
|
2010-06-18 16:44:40 +02:00
|
|
|
elsif (/^(-|C|R|RW\+?(?:C?D?|D?C?)) (.* )?= (.+)/)
|
2009-08-23 10:16:45 +02:00
|
|
|
{
|
2009-10-02 18:47:51 +02:00
|
|
|
my $perms = $1;
|
|
|
|
my @refs; @refs = split(' ', $2) if $2;
|
2010-02-13 15:30:45 +01:00
|
|
|
@refs = expand_list ( @refs );
|
2009-10-02 18:47:51 +02:00
|
|
|
my @users = split ' ', $3;
|
2010-04-25 10:19:19 +02:00
|
|
|
die "$ABRT \$GL_WILDREPOS is not set, you cant use 'C' in config\n" if $perms eq 'C' and not $GL_WILDREPOS;
|
2009-10-02 18:47:51 +02:00
|
|
|
|
|
|
|
# if no ref is given, this PERM applies to all refs
|
|
|
|
@refs = qw(refs/.*) unless @refs;
|
2010-01-09 15:27:44 +01:00
|
|
|
# deprecation warning
|
|
|
|
map { warn "WARNING: old syntax 'PATH/' found; please use new syntax 'NAME/'\n" if s(^PATH/)(NAME/) } @refs;
|
2010-01-07 13:29:34 +01:00
|
|
|
# fully qualify refs that dont start with "refs/" or "NAME/";
|
2009-11-16 15:35:08 +01:00
|
|
|
# prefix them with "refs/heads/"
|
2010-01-07 13:29:34 +01:00
|
|
|
@refs = map { m(^(refs|NAME)/) or s(^)(refs/heads/); $_ } @refs;
|
2010-03-16 02:56:33 +01:00
|
|
|
@refs = map { s(/USER/)(/\$gl_user/); $_ } @refs;
|
2009-10-02 18:47:51 +02:00
|
|
|
|
|
|
|
# expand the user list, unless it is just "@all"
|
|
|
|
@users = expand_list ( @users )
|
2010-05-10 08:16:47 +02:00
|
|
|
unless ($GL_BIG_CONFIG or (@users == 1 and $users[0] eq '@all'));
|
2009-11-03 15:54:53 +01:00
|
|
|
do { die "$ABRT bad username $_\n" unless $_ =~ $USERNAME_PATT } for @users;
|
2009-10-02 18:47:51 +02:00
|
|
|
|
2010-04-25 19:09:27 +02:00
|
|
|
s/\bCREAT[EO]R\b/~\$creator/g for @users;
|
2009-12-05 14:08:46 +01:00
|
|
|
s/\bREADERS\b/\$readers/g for @users;
|
|
|
|
s/\bWRITERS\b/\$writers/g for @users;
|
|
|
|
|
2009-10-02 18:47:51 +02:00
|
|
|
# ok, we can finally populate the %repos hash
|
|
|
|
for my $repo (@repos) # each repo in the current stanza
|
2009-08-23 10:16:45 +02:00
|
|
|
{
|
2009-10-04 06:26:40 +02:00
|
|
|
# if we're processing a delegated config file (not the master
|
2009-12-05 14:08:46 +01:00
|
|
|
# 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 (
|
|
|
|
# processing the master config, not a fragment
|
|
|
|
( $fragment eq 'master' ) or
|
|
|
|
# fragment is also called 'foo' (you're allowed to have a
|
|
|
|
# fragment that is only concerned with one repo)
|
|
|
|
( $fragment eq $repo ) or
|
2010-05-12 18:39:51 +02:00
|
|
|
# same thing in big-config-land; foo is just @foo now
|
|
|
|
( $GL_BIG_CONFIG and "\@$fragment" eq $repo ) or
|
2009-12-05 14:08:46 +01:00
|
|
|
# fragment is called "bar" and "@bar = foo" has been
|
|
|
|
# defined in the master config
|
|
|
|
( ($groups{"\@$fragment"}{$repo} || '') eq 'master' )
|
|
|
|
) {
|
|
|
|
# all these are fine
|
|
|
|
} else {
|
|
|
|
# this is a little more complex
|
|
|
|
|
|
|
|
# fragment is called "bar", one or more "@bar = regex"
|
|
|
|
# have been specified in master, and "foo" matches some
|
|
|
|
# such "regex"
|
|
|
|
my @matched = grep { $repo =~ /^$_$/ }
|
|
|
|
grep { $groups{"\@$fragment"}{$_} eq 'master' }
|
|
|
|
sort keys %{ $groups{"\@$fragment"} };
|
|
|
|
if (@matched < 1) {
|
2009-10-04 06:26:40 +02:00
|
|
|
$ignored{$fragment}{$repo} = 1;
|
|
|
|
next;
|
|
|
|
}
|
|
|
|
}
|
2009-10-02 18:47:51 +02:00
|
|
|
for my $user (@users)
|
|
|
|
{
|
2010-06-02 07:18:28 +02:00
|
|
|
# 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}++;
|
|
|
|
}
|
2009-09-27 04:32:36 +02:00
|
|
|
|
2009-10-02 18:47:51 +02:00
|
|
|
# for 1st level check (see faq/tips doc)
|
2009-12-05 14:08:46 +01:00
|
|
|
$repos{$repo}{C}{$user} = 1, next if $perms eq 'C';
|
2009-10-02 18:47:51 +02:00
|
|
|
$repos{$repo}{R}{$user} = 1 if $perms =~ /R/;
|
2010-03-30 16:31:49 +02:00
|
|
|
$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)
|
2010-04-15 03:02:39 +02:00
|
|
|
$repos{$repo}{DELETE_IS_D} = 1 if $perms =~ /D/;
|
2010-06-18 16:44:40 +02:00
|
|
|
$repos{$repo}{CREATE_IS_C} = 1 if $perms =~ /RW.*C/;
|
2009-09-18 14:30:14 +02:00
|
|
|
|
2009-10-02 18:47:51 +02:00
|
|
|
# for 2nd level check, store each "ref, perms" pair in order
|
|
|
|
for my $ref (@refs)
|
|
|
|
{
|
2010-01-07 13:29:34 +01:00
|
|
|
# checking NAME based restrictions is expensive for
|
2009-11-16 15:35:08 +01:00
|
|
|
# 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
|
2010-01-07 13:29:34 +01:00
|
|
|
# that do *not* use NAME limits. Setting a flag that
|
2009-11-16 15:35:08 +01:00
|
|
|
# can be checked right away will help us do that
|
2010-01-07 13:29:34 +01:00
|
|
|
$repos{$repo}{NAME_LIMITS} = 1 if $ref =~ /^NAME\//;
|
(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 $p_user = $user; $p_user =~ s/(creator|readers|writers)$/$1 - wild/;
|
|
|
|
push @{ $repos{$repo}{$p_user} }, [ $rule_seq++, $ref, $perms ]
|
|
|
|
unless $rurp_seen{$repo}{$p_user}{$ref}{$perms}++;
|
2009-10-02 18:47:51 +02:00
|
|
|
}
|
2009-08-23 10:16:45 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-12-07 21:20:29 +01:00
|
|
|
# configuration
|
|
|
|
elsif (/^config (.+) = ?(.*)/)
|
|
|
|
{
|
|
|
|
my ($key, $value) = ($1, $2);
|
2010-02-07 08:39:16 +01:00
|
|
|
my @validkeys = split (' ', ($GL_GITCONFIG_KEYS || ''));
|
|
|
|
my @matched = grep { $key =~ /^$_$/ } @validkeys;
|
|
|
|
die "$ABRT git config $key not allowed\n" if (@matched < 1);
|
2009-12-07 21:20:29 +01:00
|
|
|
for my $repo (@repos) # each repo in the current stanza
|
|
|
|
{
|
|
|
|
$repo_config{$repo}{$key} = $value;
|
2010-06-25 20:06:15 +02:00
|
|
|
print STDERR "$WARN git config set for $repo but \$GL_GITCONFIG_WILD not set\n" unless $repo =~ $REPONAME_PATT or $GL_GITCONFIG_WILD;
|
2009-12-07 21:20:29 +01:00
|
|
|
}
|
|
|
|
}
|
2010-01-05 19:34:40 +01:00
|
|
|
# include
|
|
|
|
elsif (/^include "(.+)"/)
|
|
|
|
{
|
|
|
|
my $file = $1;
|
|
|
|
$file = "$GL_ADMINDIR/conf/$file" unless $file =~ /^\//;
|
|
|
|
die "$WARN $fragment attempting to include configuration\n" if $fragment ne 'master';
|
|
|
|
die "$ABRT included file not found: '$file'\n" unless -f $file;
|
|
|
|
|
|
|
|
parse_conf_file($file, $fragment);
|
|
|
|
}
|
2009-11-27 08:53:48 +01:00
|
|
|
# very simple syntax for the gitweb description of repo; one of:
|
|
|
|
# reponame = "some description string"
|
|
|
|
# reponame "owner name" = "some description string"
|
|
|
|
elsif (/^(\S+)(?: "(.*?)")? = "(.*)"$/)
|
2009-11-12 10:19:39 +01:00
|
|
|
{
|
2009-11-27 08:53:48 +01:00
|
|
|
my ($repo, $owner, $desc) = ($1, $2, $3);
|
2009-11-12 10:19:39 +01:00
|
|
|
die "$ABRT bad repo name $repo\n" unless $repo =~ $REPONAME_PATT;
|
|
|
|
die "$WARN $fragment attempting to set description for $repo\n" if
|
|
|
|
$fragment ne 'master' and $fragment ne $repo and ($groups{"\@$fragment"}{$repo} || '') ne 'master';
|
2009-11-27 08:53:48 +01:00
|
|
|
$desc{"$repo.git"} = $desc;
|
|
|
|
$owner{"$repo.git"} = $owner || '';
|
2009-11-12 10:19:39 +01:00
|
|
|
}
|
2009-10-02 18:47:51 +02:00
|
|
|
else
|
|
|
|
{
|
2009-11-03 15:54:53 +01:00
|
|
|
die "$ABRT can't make head or tail of '$_'\n";
|
2009-10-02 18:47:51 +02:00
|
|
|
}
|
2009-08-24 10:00:58 +02:00
|
|
|
}
|
2009-10-04 06:26:40 +02:00
|
|
|
for my $ig (sort keys %ignored)
|
|
|
|
{
|
|
|
|
warn "\n\t\t***** WARNING *****\n" .
|
|
|
|
"\t$ig.conf attempting to set access for " .
|
|
|
|
join (", ", sort keys %{ $ignored{$ig} }) . "\n";
|
|
|
|
}
|
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');
|
|
|
|
|
|
|
|
# parse any delegated fragments
|
|
|
|
wrap_chdir($GL_ADMINDIR);
|
|
|
|
for my $fragment_file (glob("conf/fragments/*.conf"))
|
|
|
|
{
|
2009-11-23 18:15:00 +01:00
|
|
|
# we already check (elsewhere) that a fragment called "foo" will not try
|
|
|
|
# to specify access control for a repo whose name is not "foo" or is not
|
|
|
|
# part of a group called "foo" created by master
|
|
|
|
|
|
|
|
# meanwhile, I found a possible attack where the admin for group B creates
|
|
|
|
# a "convenience" group of (a subset of) his users, and then the admin for
|
|
|
|
# repo group A (alphabetically before B) adds himself to that same group
|
|
|
|
# in his own fragment.
|
|
|
|
|
|
|
|
# as a result, admin_A now has access to group B repos :(
|
|
|
|
|
|
|
|
# so now we lock the groups hash to the value it had after parsing
|
|
|
|
# "master", and localise any changes to it by this fragment so that they
|
|
|
|
# don't propagate to the next fragment. Thus, each fragment now has only
|
|
|
|
# those groups that are defined in "master" and itself
|
|
|
|
|
|
|
|
local %groups = %groups;
|
|
|
|
|
2009-10-04 06:26:40 +02:00
|
|
|
my $fragment = $fragment_file;
|
|
|
|
$fragment =~ s/^conf\/fragments\/(.*).conf$/$1/;
|
|
|
|
parse_conf_file($fragment_file, $fragment);
|
|
|
|
}
|
2009-10-02 18:47:51 +02:00
|
|
|
|
2010-07-30 21:16:26 +02:00
|
|
|
my $compiled_fh = wrap_open( ">", "$GL_CONF_COMPILED.new" );
|
2010-05-21 10:38:05 +02:00
|
|
|
my $data_version = $current_data_version;
|
|
|
|
print $compiled_fh Data::Dumper->Dump([$data_version], [qw(*data_version)]);
|
2009-12-05 14:08:46 +01:00
|
|
|
my $dumped_data = Data::Dumper->Dump([\%repos], [qw(*repos)]);
|
2010-06-25 20:06:15 +02:00
|
|
|
$dumped_data .= Data::Dumper->Dump([\%repo_config], [qw(*repo_config)]) if %repo_config;
|
2010-04-25 19:09:27 +02:00
|
|
|
# the dump uses single quotes, but we convert any strings containing $creator,
|
2009-12-05 14:08:46 +01:00
|
|
|
# $readers, $writers, to double quoted strings. A wee bit sneaky, but not too
|
|
|
|
# much...
|
2010-05-18 12:45:23 +02:00
|
|
|
$dumped_data =~ s/'(?=[^']*\$(?:creator|readers|writers|gl_user))~?(.*?)'/"$1"/g;
|
2009-12-05 14:08:46 +01:00
|
|
|
print $compiled_fh $dumped_data;
|
2010-05-10 08:16:47 +02:00
|
|
|
print $compiled_fh Data::Dumper->Dump([\%groups], [qw(*groups)]) if $GL_BIG_CONFIG and %groups;
|
2009-11-03 15:54:53 +01:00
|
|
|
close $compiled_fh or die "$ABRT close compiled-conf failed: $!\n";
|
2010-07-30 21:16:26 +02:00
|
|
|
rename "$GL_CONF_COMPILED.new", "$GL_CONF_COMPILED";
|
2009-08-23 11:25:50 +02:00
|
|
|
|
|
|
|
# ----------------------------------------------------------------------------
|
2010-07-23 13:33:21 +02:00
|
|
|
# (that ends the config file compiler and write)
|
2009-08-23 11:25:50 +02:00
|
|
|
# ----------------------------------------------------------------------------
|
|
|
|
|
2010-07-23 13:33:21 +02:00
|
|
|
# ----------------------------------------------------------------------------
|
|
|
|
# what's the git version?
|
|
|
|
# ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
# we don't like stuff older than 1.6.2
|
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" .
|
|
|
|
"\tyour git version is older than 1.6.2\n" .
|
|
|
|
"\tsince that is now more than one year old, and gitolite needs some of\n" .
|
|
|
|
"\tthe newer features, please upgrade.\n"
|
|
|
|
if $git_version < 10602; # that's 1.6.2 to you
|
|
|
|
|
2010-07-23 13:33:21 +02:00
|
|
|
|
|
|
|
|
|
|
|
# ----------------------------------------------------------------------------
|
|
|
|
# the rest of this program can be "switched off"; see doc/big-config.mkd for
|
|
|
|
# details.
|
|
|
|
# ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
# ----------------------------------------------------------------------------
|
|
|
|
# any new repos to be created?
|
|
|
|
# ----------------------------------------------------------------------------
|
|
|
|
|
2009-12-01 17:24:23 +01:00
|
|
|
# repo-base needs to be an absolute path for this loop to work right
|
|
|
|
# so if it was not already absolute, prefix $HOME.
|
2010-06-29 07:25:36 +02:00
|
|
|
$ENV{GL_REPO_BASE_ABS} = ( $REPO_BASE =~ m(^/) ? $REPO_BASE : "$ENV{HOME}/$REPO_BASE" );
|
2009-12-01 17:24:23 +01:00
|
|
|
|
2010-07-23 13:33:21 +02:00
|
|
|
unless ($GL_NO_CREATE_REPOS) {
|
2010-06-29 07:25:36 +02:00
|
|
|
wrap_chdir("$ENV{GL_REPO_BASE_ABS}");
|
2010-05-14 17:10:59 +02:00
|
|
|
|
|
|
|
# autocreate repos. Start with the ones that are normal repos in %repos
|
|
|
|
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) {
|
|
|
|
next unless $repo =~ $REPONAME_PATT;
|
|
|
|
next if $repo =~ m(^\@|EXTCMD/); # these are not real 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
|
2010-06-29 07:25:36 +02:00
|
|
|
wrap_chdir("$ENV{GL_REPO_BASE_ABS}");
|
2010-05-14 17:10:59 +02:00
|
|
|
}
|
2010-03-07 14:35:56 +01:00
|
|
|
|
2010-05-14 17:10:59 +02:00
|
|
|
# when repos are copied over from elsewhere, one had to run easy install
|
|
|
|
# once again to make the new (OS-copied) repo contain the proper update
|
|
|
|
# hook. Perhaps we can make this easier now, and eliminate the easy
|
|
|
|
# install, with a quick check (and a new, empty, "hook" as a sentinel)
|
|
|
|
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-03-07 14:35:56 +01:00
|
|
|
}
|
2009-12-01 17:24:23 +01:00
|
|
|
}
|
|
|
|
|
2009-12-07 21:20:29 +01: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
|
|
|
# collect repo_patt for each actual repo
|
2009-12-07 21:20:29 +01: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
|
|
|
# go through each actual repo on disk, and match it to either its own name in
|
|
|
|
# the config (non-wild) or a wild pattern that matches it. Lots of things
|
|
|
|
# later will need this correspondence so we may as well snarf it in one shot
|
2010-07-23 13:33:21 +02:00
|
|
|
|
2010-06-25 20:06:15 +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 %repo_patts = ();
|
|
|
|
%repo_patts = &collect_repo_patts(\%repos) unless $GL_NO_DAEMON_NO_GITWEB;
|
|
|
|
|
|
|
|
# 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
|
|
|
# all these require a "chdir" to the repo, so we club them for efficiency
|
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!)
|
|
|
|
for my $repo (keys %repo_patts) {
|
|
|
|
my $repo_patt = $repo_patts{$repo}; # if non-wild, $repo_patt will be eq $repo anyway
|
2010-02-03 09:13:47 +01: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
|
|
|
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};
|
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
|
|
|
# daemon is easy
|
|
|
|
&setup_daemon_access($repo, $repos{$repo_patt}{'R'}{'daemon'} || '');
|
|
|
|
|
|
|
|
# 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
|
|
|
|
# wild card spec and "C" permissions. If you see the
|
|
|
|
# conf/example.conf file, you will see that repo owner/desc don't go
|
|
|
|
# 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.
|
|
|
|
if ($repos{$repo_patt}{'R'}{'gitweb'} or $desc{"$repo.git"}) {
|
|
|
|
$projlist{"$repo.git"} = 1;
|
|
|
|
&setup_gitweb_access($repo, 1, $desc{"$repo.git"} || '', $owner{"$repo.git"} || '');
|
|
|
|
} else {
|
|
|
|
&setup_gitweb_access($repo, 0, '', '');
|
2010-05-16 02:48:08 +02:00
|
|
|
}
|
2009-11-27 08:53:48 +01:00
|
|
|
}
|
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
|
|
|
# write out the project list
|
|
|
|
my $projlist_fh = wrap_open( ">", $PROJECTS_LIST);
|
|
|
|
for my $proj (sort keys %projlist) {
|
|
|
|
print $projlist_fh "$proj\n";
|
|
|
|
}
|
|
|
|
close $projlist_fh;
|
|
|
|
|
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) {
|
|
|
|
&setup_authkeys($bindir, $GL_KEYDIR, \%user_list);
|
2009-08-24 10:00:58 +02:00
|
|
|
}
|