Merge branch 'master' into wildrepos
master brought in: - full email addresses as usernames - repo-specific git config Conflicts: doc/3-faq-tips-etc.mkd src/gitolite.pm src/gl-compile-conf
This commit is contained in:
commit
ff28acb059
|
@ -6,9 +6,13 @@
|
||||||
# the description string for gitweb)
|
# the description string for gitweb)
|
||||||
# - comments in the normal shell-ish style; no surprises there
|
# - comments in the normal shell-ish style; no surprises there
|
||||||
# - there are NO continuation lines of any kind
|
# - there are NO continuation lines of any kind
|
||||||
# - user/repo names as simple as possible
|
# - user/repo names as simple as possible; they must start with an
|
||||||
# (usernames: only alphanumerics, ".", "_", "-";
|
# alphanumeric, but after that they can also contain ".", "_", "-".
|
||||||
# reponames: same, plus "/", but not at the start)
|
# - usernames can optionally be followed by an "@" and a domainname
|
||||||
|
# containing at least one "." (this allows you to use an email
|
||||||
|
# address as someone's username)
|
||||||
|
# - reponames can contain "/" characters (this allows you to
|
||||||
|
# put your repos in a tree-structure for convenience)
|
||||||
|
|
||||||
# objectives, over and above gitosis:
|
# objectives, over and above gitosis:
|
||||||
# - simpler syntax
|
# - simpler syntax
|
||||||
|
@ -87,7 +91,8 @@
|
||||||
repo gitolite-admin
|
repo gitolite-admin
|
||||||
RW+ = @admins
|
RW+ = @admins
|
||||||
|
|
||||||
# "@all" is a special, predefined, group name
|
# "@all" is a special, predefined, group name of all users
|
||||||
|
# (everyone who has a pubkey in keydir)
|
||||||
repo testing
|
repo testing
|
||||||
RW+ = @all
|
RW+ = @all
|
||||||
|
|
||||||
|
@ -181,3 +186,26 @@ repo linux perl
|
||||||
# give gitweb access as described above if you're specifying a description
|
# give gitweb access as described above if you're specifying a description
|
||||||
|
|
||||||
gitolite "Sitaram Chamarty" = "fast, secure, access control for git in a corporate environment"
|
gitolite "Sitaram Chamarty" = "fast, secure, access control for git in a corporate environment"
|
||||||
|
|
||||||
|
# REPO SPECIFIC GITCONFIG
|
||||||
|
# -----------------------
|
||||||
|
|
||||||
|
# (Thanks to teemu dot matilainen at iki dot fi)
|
||||||
|
|
||||||
|
# this should be specified within a "repo" stanza
|
||||||
|
|
||||||
|
# syntax:
|
||||||
|
# config sectionname.keyname = [optional value_string]
|
||||||
|
|
||||||
|
# example usage: if you placed a hook in src/hooks that requires configuration
|
||||||
|
# information that is specific to each repo, you could do this:
|
||||||
|
|
||||||
|
repo gitolite
|
||||||
|
config hooks.mailinglist = gitolite-commits@example.tld
|
||||||
|
config hooks.emailprefix = "[gitolite] "
|
||||||
|
config foo.bar = ""
|
||||||
|
config foo.baz =
|
||||||
|
|
||||||
|
# This does either a plain "git config section.key value" (for the first 3
|
||||||
|
# examples above) or "git config --unset-all section.key" (for the last
|
||||||
|
# example). Other forms (--add, the value_regex, etc) are not supported.
|
||||||
|
|
|
@ -37,13 +37,16 @@ Assumptions/pre-requisites:
|
||||||
* git is installed on that server (and so is perl)
|
* git is installed on that server (and so is perl)
|
||||||
* you have a userid on that server
|
* you have a userid on that server
|
||||||
* you have ssh-pubkey (**password-less**) login to that userid
|
* you have ssh-pubkey (**password-less**) login to that userid
|
||||||
* (if you have only password access, run `ssh-keygen -t rsa` to create a
|
* if you have only password access, run `ssh-keygen -t rsa` to create a
|
||||||
new keypair if needed, then run `ssh-copy-id user@host`)
|
new keypair if needed, then run `ssh-copy-id user@host`. If you do
|
||||||
|
not have `ssh-copy-id`, read doc/3-faq-tips-etc.mkd and look for
|
||||||
|
`ssh-copy-id` in that file for instructions
|
||||||
* you have a clone or an archive of gitolite somewhere on your workstation
|
* you have a clone or an archive of gitolite somewhere on your workstation
|
||||||
|
* if you don't have one, just run `git clone git://github.com/sitaramc/gitolite`
|
||||||
|
|
||||||
If so, just `cd` to that clone and run `src/gl-easy-install` and follow the
|
Once you have all this, just `cd` to that clone and run `src/gl-easy-install`
|
||||||
prompts! (Running it without any arguments shows you usage plus other useful
|
and follow the prompts! (Running it without any arguments shows you usage
|
||||||
info).
|
plus other useful info).
|
||||||
|
|
||||||
#### typical example run
|
#### typical example run
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ In this document:
|
||||||
* adding users and repos
|
* adding users and repos
|
||||||
* specifying gitweb and daemon access
|
* specifying gitweb and daemon access
|
||||||
* custom hooks
|
* custom hooks
|
||||||
|
* custom git config
|
||||||
|
|
||||||
### administer
|
### administer
|
||||||
|
|
||||||
|
@ -90,3 +91,25 @@ just run easy install once again; it'll do it to existing repos also.
|
||||||
implements all the branch-level permissions in gitolite. If you fiddle with
|
implements all the branch-level permissions in gitolite. If you fiddle with
|
||||||
the hooks directory, please make sure you do not mess with this file
|
the hooks directory, please make sure you do not mess with this file
|
||||||
accidentally, or all your fancy per-branch permissions will stop working.**
|
accidentally, or all your fancy per-branch permissions will stop working.**
|
||||||
|
|
||||||
|
#### custom git config
|
||||||
|
|
||||||
|
The custom hooks feature is a blunt instrument -- all repos get the hook you
|
||||||
|
specified and will run it. In order to make it a little more fine-grained,
|
||||||
|
you could set your hooks to only work if a certain "gitconfig" variable was
|
||||||
|
set. Which means we now need a way to specify "git config" settings on a per
|
||||||
|
repository basis.
|
||||||
|
|
||||||
|
Thanks to Teemu (teemu dot matilainen at iki dot fi), gitolite now does this
|
||||||
|
very easily. For security reasons, this can only be done from the master
|
||||||
|
config file (i.e., if you're using delegation, the delegated admins cannot
|
||||||
|
specify git config settings).
|
||||||
|
|
||||||
|
Please see `conf/example.conf` for syntax. Note that this only supports the
|
||||||
|
basic forms of the "git config" command:
|
||||||
|
|
||||||
|
git config section.key value # value may be an empty string
|
||||||
|
git config --unset-all section.key
|
||||||
|
|
||||||
|
It does not (currently) support other options like `--add`, the `value_regex`,
|
||||||
|
etc.
|
||||||
|
|
|
@ -19,22 +19,32 @@ In this document:
|
||||||
* what repos do I have access to?
|
* what repos do I have access to?
|
||||||
* "exclude" (or "deny") rules
|
* "exclude" (or "deny") rules
|
||||||
* "personal" branches
|
* "personal" branches
|
||||||
|
* custom hooks and custom git config
|
||||||
* repos named with wildcards
|
* repos named with wildcards
|
||||||
* design choices
|
* design choices
|
||||||
* keeping the parser and the access control separate
|
* keeping the parser and the access control separate
|
||||||
|
|
||||||
### common errors and mistakes
|
### common errors and mistakes
|
||||||
|
|
||||||
* forgetting to suffix `.git` to the end of the reponame in the `git clone`.
|
|
||||||
This suffix is *not* used in the gitolite config file for the sake of
|
|
||||||
clarity and cleaner syntax, but don't let that fool you. It's a
|
|
||||||
convention in the git world that **bare repos** end with `.git`.
|
|
||||||
|
|
||||||
* adding `repositories/` at the start of the repo name in the `git clone`.
|
* adding `repositories/` at the start of the repo name in the `git clone`.
|
||||||
This error is typically made by the *admin* himself -- because he knows
|
This error is typically made by the *admin* himself -- because he knows
|
||||||
what `$REPO_BASE` is set to and thinks he has to provide that prefix on
|
what `$REPO_BASE` is set to and thinks he has to provide that prefix on
|
||||||
the client side also :-) In fact gitolite prepends `$REPO_BASE` when it
|
the client side also :-) In fact gitolite prepends `$REPO_BASE`
|
||||||
is required anyway, so you shouldn't do the same thing!
|
internally, so you shouldn't also do the same thing!
|
||||||
|
|
||||||
|
* being able to clone but getting errors on push. Most likely caused by a
|
||||||
|
combination of:
|
||||||
|
|
||||||
|
* you already have shell access to the server, not just "gitolite"
|
||||||
|
access, *and*
|
||||||
|
|
||||||
|
* you cloned using `git clone git@server:repositories/repo.git` (notice
|
||||||
|
there's an extra "repositories/" in there?)
|
||||||
|
|
||||||
|
In other words, you used a key that completely bypassed gitolite and went
|
||||||
|
straight to the shell to do the clone.
|
||||||
|
|
||||||
|
Please see doc/6-ssh-troubleshooting.mkd for what all this means.
|
||||||
|
|
||||||
### git version dependency
|
### git version dependency
|
||||||
|
|
||||||
|
@ -67,6 +77,27 @@ normal way, since it's not empty anymore.
|
||||||
|
|
||||||
### other errors, warnings, notes...
|
### other errors, warnings, notes...
|
||||||
|
|
||||||
|
* don't have `ssh-copy-id`? This is broadly what that command does, if you
|
||||||
|
want to replicate it manually. The input is your pubkey, typically
|
||||||
|
`~/.ssh/id_rsa.pub` from your client/workstation.
|
||||||
|
|
||||||
|
* it copies it to the server as some file
|
||||||
|
|
||||||
|
* it appends that file to `~/.ssh/authorized_keys` on the server
|
||||||
|
(creating it if it doesn't already exist)
|
||||||
|
|
||||||
|
* it then makes sure that all these files/directories have go-w perms
|
||||||
|
set (assuming user is "git"):
|
||||||
|
|
||||||
|
/home/git/.ssh/authorized_keys
|
||||||
|
/home/git/.ssh
|
||||||
|
/home/git
|
||||||
|
|
||||||
|
[Actually, sshd requires that even directories *above* ~ (/, /home,
|
||||||
|
typically) also must be `go-w`, but that needs root. And typically
|
||||||
|
they're already set that way anyway. (Or if they're not, you've got
|
||||||
|
bigger problems than gitolite install not working!)]
|
||||||
|
|
||||||
* cloning an empty repo is only possible with clients greater than 1.6.2.
|
* cloning an empty repo is only possible with clients greater than 1.6.2.
|
||||||
So at least one of your clients needs to have a recent git. Once at least
|
So at least one of your clients needs to have a recent git. Once at least
|
||||||
one commit has been made, older clients can also use it
|
one commit has been made, older clients can also use it
|
||||||
|
@ -345,12 +376,36 @@ gitolite knows these two keys belong to the same person.
|
||||||
|
|
||||||
Note that you don't say "sitaram@laptop" and so on in the **config** file --
|
Note that you don't say "sitaram@laptop" and so on in the **config** file --
|
||||||
as far as the config file is concerned there's just **one** user called
|
as far as the config file is concerned there's just **one** user called
|
||||||
"sitaram" -- so you only say "sitaram" there. Only the **pubkey files** have
|
"sitaram" -- so you only say "sitaram" there.
|
||||||
the extra "@" stuff.
|
|
||||||
|
|
||||||
I think this is easier to maintain if you have to delete or change one of
|
I think this is easier to maintain if you have to delete or change one of
|
||||||
those keys.
|
those keys.
|
||||||
|
|
||||||
|
However, now that `sitaramc@gmail.com` is also a valid username, we need to
|
||||||
|
distinguish between `sitaramc@gmail.com.pub` and `sitaramc@desktop.pub`. We
|
||||||
|
do that by requiring that the multi-key suffix you use (like "desktop" and
|
||||||
|
"laptop") should not have a `"."` in it. If it does, it looks like an email
|
||||||
|
address. The following table lists sample pubkey filenames and the
|
||||||
|
corresponding derived usernames (which is what goes into the
|
||||||
|
`conf/gitolite.conf` file):
|
||||||
|
|
||||||
|
* old style multikeys; not mistaken for emails because there is no "." in
|
||||||
|
hostname part
|
||||||
|
|
||||||
|
sitaramc.pub sitaramc
|
||||||
|
sitaramc@laptop.pub sitaramc
|
||||||
|
sitaramc@desktop.pub sitaramc
|
||||||
|
|
||||||
|
* new style, email keys; there is a "." in hostname part; so it's an email
|
||||||
|
address
|
||||||
|
|
||||||
|
sitaramc@gmail.com.pub sitaramc@gmail.com
|
||||||
|
|
||||||
|
* multikeys *with* email address
|
||||||
|
|
||||||
|
sitaramc@gmail.com@laptop.pub sitaramc@gmail.com
|
||||||
|
sitaramc@gmail.com@desktop.pub sitaramc@gmail.com
|
||||||
|
|
||||||
#### support for git installed outside default PATH
|
#### support for git installed outside default PATH
|
||||||
|
|
||||||
The normal solution is to add to the system default PATH somehow, either by
|
The normal solution is to add to the system default PATH somehow, either by
|
||||||
|
@ -507,6 +562,12 @@ first check:
|
||||||
|
|
||||||
Just don't *show* the user this config file; it might sound insulting :-)
|
Just don't *show* the user this config file; it might sound insulting :-)
|
||||||
|
|
||||||
|
#### custom hooks and custom git config
|
||||||
|
|
||||||
|
You can specify hooks that you want to propagate to all repos, as well as
|
||||||
|
per-repo "gitconfig" settings. Please see `doc/2-admin.mkd` and
|
||||||
|
`conf/example.conf` for details.
|
||||||
|
|
||||||
#### repos named with wildcards
|
#### repos named with wildcards
|
||||||
|
|
||||||
**This feature only exists in the "wildrepos" branch!** Please see
|
**This feature only exists in the "wildrepos" branch!** Please see
|
||||||
|
|
|
@ -24,9 +24,9 @@ $WARN = "\n\t\t***** WARNING *****\n ";
|
||||||
$R_COMMANDS=qr/^(git[ -]upload-pack|git[ -]upload-archive)$/;
|
$R_COMMANDS=qr/^(git[ -]upload-pack|git[ -]upload-archive)$/;
|
||||||
$W_COMMANDS=qr/^git[ -]receive-pack$/;
|
$W_COMMANDS=qr/^git[ -]receive-pack$/;
|
||||||
|
|
||||||
# note that REPONAME_PATT allows a "/" also, which USERNAME_PATT doesn't
|
# note that REPONAME_PATT allows "/", while USERNAME_PATT allows "@"
|
||||||
$REPONAME_PATT=qr(^\@?[0-9a-zA-Z][0-9a-zA-Z._/-]*$); # very simple pattern
|
$REPONAME_PATT=qr(^\@?[0-9a-zA-Z][0-9a-zA-Z._/-]*$); # very simple pattern
|
||||||
$USERNAME_PATT=qr(^\@?[0-9a-zA-Z][0-9a-zA-Z._-]*$); # very simple pattern
|
$USERNAME_PATT=qr(^\@?[0-9a-zA-Z][0-9a-zA-Z._\@-]*$); # very simple pattern
|
||||||
# same as REPONAME, plus some common regex metas
|
# same as REPONAME, plus some common regex metas
|
||||||
$REPOPATT_PATT=qr(^\@?[0-9a-zA-Z][\\^.$|()[\]*+?{}0-9a-zA-Z._/-]*$);
|
$REPOPATT_PATT=qr(^\@?[0-9a-zA-Z][\\^.$|()[\]*+?{}0-9a-zA-Z._/-]*$);
|
||||||
|
|
||||||
|
|
|
@ -36,11 +36,11 @@ $Data::Dumper::Sortkeys = sub { return [ reverse sort keys %{$_[0]} ]; };
|
||||||
# - anytime a pubkey is added/deleted
|
# - anytime a pubkey is added/deleted
|
||||||
# - anytime gitolite.conf is changed
|
# - anytime gitolite.conf is changed
|
||||||
# input:
|
# input:
|
||||||
# - GL_CONF (default: ~/.gitolite/gitolite.conf)
|
# - GL_CONF (default: ~/.gitolite/conf/gitolite.conf)
|
||||||
# - GL_KEYDIR (default: ~/.gitolite/keydir)
|
# - GL_KEYDIR (default: ~/.gitolite/keydir)
|
||||||
# output:
|
# output:
|
||||||
# - ~/.ssh/authorized_keys (dictated by sshd)
|
# - ~/.ssh/authorized_keys (dictated by sshd)
|
||||||
# - GL_CONF_COMPILED (default: ~/.gitolite/gitolite.conf-compiled.pm)
|
# - GL_CONF_COMPILED (default: ~/.gitolite/conf/gitolite.conf-compiled.pm)
|
||||||
# security:
|
# security:
|
||||||
# - touches a very critical system file that manages the restrictions on
|
# - touches a very critical system file that manages the restrictions on
|
||||||
# incoming users. Be sure to audit AUTH_COMMAND and AUTH_OPTIONS (see
|
# incoming users. Be sure to audit AUTH_COMMAND and AUTH_OPTIONS (see
|
||||||
|
@ -111,6 +111,9 @@ my %rurp_seen = ();
|
||||||
# catch usernames<->pubkeys mismatches; search for "lint" below
|
# catch usernames<->pubkeys mismatches; search for "lint" below
|
||||||
my %user_list = ();
|
my %user_list = ();
|
||||||
|
|
||||||
|
# repo configurations
|
||||||
|
my %repo_config = ();
|
||||||
|
|
||||||
# gitweb descriptions and owners; plain text, keyed by "$repo.git"
|
# gitweb descriptions and owners; plain text, keyed by "$repo.git"
|
||||||
my %desc = ();
|
my %desc = ();
|
||||||
my %owner = ();
|
my %owner = ();
|
||||||
|
@ -129,7 +132,7 @@ sub expand_list
|
||||||
|
|
||||||
for my $item (@list)
|
for my $item (@list)
|
||||||
{
|
{
|
||||||
die "$ABRT bad user or repo name $item\n" unless $item =~ $REPOPATT_PATT;
|
die "$ABRT bad user or repo name $item\n" unless $item =~ $REPOPATT_PATT or $item =~ $USERNAME_PATT;
|
||||||
if ($item =~ /^@/) # nested group
|
if ($item =~ /^@/) # nested group
|
||||||
{
|
{
|
||||||
die "$ABRT undefined group $item\n" unless $groups{$item};
|
die "$ABRT undefined group $item\n" unless $groups{$item};
|
||||||
|
@ -182,7 +185,6 @@ sub parse_conf_file
|
||||||
# store the members of each group as hash key. Keep track of when
|
# store the members of each group as hash key. Keep track of when
|
||||||
# the group was *first* created by using $fragment as the *value*
|
# the group was *first* created by using $fragment as the *value*
|
||||||
do { $groups{$1}{$_} ||= $fragment } for ( expand_list( split(' ', $2) ) );
|
do { $groups{$1}{$_} ||= $fragment } for ( expand_list( split(' ', $2) ) );
|
||||||
# again, we take the more "relaxed" pattern
|
|
||||||
die "$ABRT bad group $1\n" unless $1 =~ $REPONAME_PATT;
|
die "$ABRT bad group $1\n" unless $1 =~ $REPONAME_PATT;
|
||||||
}
|
}
|
||||||
# repo(s)
|
# repo(s)
|
||||||
|
@ -278,6 +280,16 @@ sub parse_conf_file
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
# configuration
|
||||||
|
elsif (/^config (.+) = ?(.*)/)
|
||||||
|
{
|
||||||
|
my ($key, $value) = ($1, $2);
|
||||||
|
die "$WARN $fragment attempting to set repo configuration\n" if $fragment ne 'master';
|
||||||
|
for my $repo (@repos) # each repo in the current stanza
|
||||||
|
{
|
||||||
|
$repo_config{$repo}{$key} = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
# very simple syntax for the gitweb description of repo; one of:
|
# very simple syntax for the gitweb description of repo; one of:
|
||||||
# reponame = "some description string"
|
# reponame = "some description string"
|
||||||
# reponame "owner name" = "some description string"
|
# reponame "owner name" = "some description string"
|
||||||
|
@ -379,6 +391,22 @@ warn "\n\t\t***** WARNING *****\n" .
|
||||||
"\t\"git version dependency\" in doc/3-faq-tips-etc.mkd\n"
|
"\t\"git version dependency\" in doc/3-faq-tips-etc.mkd\n"
|
||||||
if $git_version < 10602; # that's 1.6.2 to you
|
if $git_version < 10602; # that's 1.6.2 to you
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
# update repo configurations
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
for my $repo (keys %repo_config) {
|
||||||
|
wrap_chdir("$repo_base_abs/$repo.git");
|
||||||
|
while ( my ($key, $value) = each(%{ $repo_config{$repo} }) ) {
|
||||||
|
if ($value) {
|
||||||
|
$value =~ s/^"(.*)"$/$1/;
|
||||||
|
system("git", "config", $key, $value);
|
||||||
|
} else {
|
||||||
|
system("git", "config", "--unset-all", $key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# ----------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------
|
||||||
# handle gitweb and daemon
|
# handle gitweb and daemon
|
||||||
# ----------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------
|
||||||
|
@ -450,7 +478,7 @@ for my $pubkey (glob("*"))
|
||||||
print STDERR "WARNING: pubkey files should end with \".pub\", ignoring $pubkey\n";
|
print STDERR "WARNING: pubkey files should end with \".pub\", ignoring $pubkey\n";
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
my $user = $pubkey; $user =~ s/(\@.+)?\.pub$//;
|
my $user = $pubkey; $user =~ s/(\@[^.]+)?\.pub$//;
|
||||||
# lint check 2
|
# lint check 2
|
||||||
print STDERR "WARNING: pubkey $pubkey exists but user $user not in config\n"
|
print STDERR "WARNING: pubkey $pubkey exists but user $user not in config\n"
|
||||||
unless $user_list{$user};
|
unless $user_list{$user};
|
||||||
|
|
Loading…
Reference in a new issue