thanks to j416 for catching this...
13 KiB
repositories named with wildcards
IMPORTANT NOTE:
This feature may be somewhat "brittle" in terms of security. Creating repositories based on wild cards, giving "ownership" to the specific user who created it, allowing him/her to hand out permissions to other users to collaborate, all these are possible. And any of these could have a bug in it. I haven't found any yet, but that doesn't mean there aren't any.
In this document:
- quick introduction
- rc file setting required
- examples of wildcard repos
- side-note: valid regexes
- side-note: line-anchored regexes
- handing out rights to wildcard-matched repos
- (admin) adding other categories than READERS and WRITERS
- setting a gitweb description for a wildcard-matched repo
- reporting
- deleting a wild repo
- how it actually works
This document is mostly "by example".
quick introduction
The wildrepos feature allows you to specify access control rules using regular
expression patterns, so you can have many actual repos being served by a
single set of rules in the config file. The regex pattern can also include
the word CREATOR
in it, allowing you to parametrise the name of the user
creating the repo. The examples below will make this clearer.
rc file setting required
This feature requires that you set $GL_WILDREPOS
to "1" in ~/.gitolite.rc
on the server. Please search for that variable in doc/gitolite.rc.mkd
for more information on this.
examples of wildcard repos
As the introduction said, you can include the word CREATOR
in the regex
pattern, though it is not mandatory. We'll look at examples of both types of
usage.
Which of these alternatives you choose depends on your needs, and the social aspects of your environment. Including the creator name in the pattern keeps users rigidly separated from each others repos, and is good for a largely autonomous collection of users with a high probability of repo name clashes.
Omitting the creator name from the pattern puts the repos in a common namespace, and is suitable for environments where it is not very important to keep track of who actually created the repo (except for granting access), but needs more communication / co-operation among the users to avoid repo name clashes.
wildcard repos with creator name in them
Here's an example snippet:
@prof = u1
@TAs = u2 u3
@students = u4 u5 u6
repo assignments/CREATOR/a[0-9][0-9]
C = @students
RW+ = CREATOR
RW = WRITERS @TAs
R = READERS @prof
For now, ignore the special usernames READERS and WRITERS, and just create a new repo, as user "u4" (a student):
$ git clone git@server:assignments/u4/a12
Initialized empty Git repository in /home/sitaram/t/a12/.git/
Initialized empty Git repository in /home/gitolite/repositories/assignments/u4/a12.git/
warning: You appear to have cloned an empty repository.
Notice the two empty repo inits, and the order in which they occur ;-)
wildcard repos without creator name in them
Here's how the same example would look if you did not want the CREATOR's name to be part of the actual repo name.
repo assignments/a[0-9][0-9]
C = @students
RW+ = CREATOR
RW = WRITERS @TAs
R = READERS @prof
We haven't changed anything except the repo name pattern. This means that the
first student that creates, say, assignments/a12
becomes the owner.
Mistakes (such as claiming a12 instead of a13) need to be rectified by an
admin logging on to the back end, though it's not too difficult.
You could also repace the C line like this:
C = @TAs
and have a TA create the repos in advance.
In either case, they could then use the setperms
feature to specify which
users are "READERS" and which are "WRITERS". See later for details.
side-note: valid regexes
Due to projects like gtk+
, the +
character is now considered a valid
character for an ordinary repo. Therefore, a pattern like foo/.+
does not
look like a regex to gitolite. Use foo/..*
if you want that.
Also, ..*
by itself is not considered a valid repo pattern. Try
[a-zA-Z0-9].*
.
side-note: line-anchored regexes
A regex like
repo assignments/S[0-9]+/A[0-9]+
would match assignments/S02/A37
. It will not match assignments/S02/ABC
,
or assignments/S02/a37
, obviously.
But you may be surprised to find that it does not match even
assignments/S02/A37/B99
. This is because internally, gitolite
line-anchors the given regex; so that regex actually becomes
^assignments/S[0-9]+/A[0-9]+$
-- notice the line beginning and ending
metacharacters.
contrast with refexes
Just for interest, note that this is in contrast to the refexes for the normal
"branch" permissions, as described in doc/gitolite.conf.mkd
and elsewhere.
These "refexes" are only anchored at the start; a pattern like
refs/heads/master
actually can match refs/heads/master01/bar
as well, even
if no one will actually push such a branch! You can anchor both sides if you
really care, by using master$
instead of master
, but that is not the
default for refexes.
handing out rights to wildcard-matched repos
In the examples above, we saw two special "user" names: READERS and WRITERS. The permissions they have are controlled by the config file, but who is part of this list is controlled by the person who created the repository.
The use case is that, although our toy example has only 3 students, in reality there will be a few dozen, but each assignment will be worked on only by a handful from among those. This allows the creator to take ad hoc sets of users from among the actual users in the system, and place them into one of two categories (in this example, READERS and WRITERS respectively). In theory you could do the same thing by creating lots of little "assignment-NN" groups in the config file but that may be a little too cumbersome for non-secret environments.
Create a small text file that contains the permissions you desire:
$ cat > myperms
READERS u5
WRITERS u6
(hit ctrl-d here)
...and use the new "setperms" command to set permissions for your repo:
$ ssh git@server setperms assignments/u4/a12 < myperms
New perms are:
READERS u5
WRITERS u6
'setperms' will helpfully print what the new permissions are but you can also use 'getperms' to check:
$ ssh git@server getperms assignments/u4/a12
READERS u5
WRITERS u6
The following points are important:
- note the syntax of the commands; it's not a "git" command, and there's no
:
like in a repo URL. The first space-separated word is READERS or WRITERS, and the rest are simple usernames.
(admin) adding other categories than READERS and WRITERS
Let's say your needs are more complex and you need more categories of users. For example, you might like to have a setup where only a tester can update tags, and only a manager can delete branches:
repo foo/..*
C = u1
RW refs/tags/ = TESTERS
- refs/tags/ = @all
RW+ = WRITERS
RW = INTERNS
R = READERS
RW+D = MANAGERS
As you can see, someone pre-creates the repo and assigns rights to various
people, say by sending something like this to setperms
:
READERS wally
WRITERS dilbert alice
MANAGERS phb
INTERNS ashok
TESTERS ashok
You can enable this by setting the GL_WILDREPOS_PERM_CATS
variable in the rc
file. The rc file documentation (doc/gitolite.rc.mkd
) explains how.
IMPORTANT WARNING ABOUT THIS FEATURE
Please make sure that none of the category names conflict with any of the
usernames in the system. For example, if you have a user called "foo",
make sure you do not include "foo" as a valid category in
$GL_WILDREPOS_PERM_CATS
.
You can keep things sane by using UPPERCASE names for categories, while keeping all your usernames lowercase; then you don't have to worry about this problem.
setting a gitweb description for a wildcard-matched repo
Similar to the getperms/setperms commands, there are the getdesc/setdesc commands, thanks to Teemu.
reporting
In order to see what repositories were created from a wildcard, use the "expand" command, described briefly in doc/report-output.mkd.
deleting a wild repo
See repo deletion for more on this. Note that this requires you to install/setup "adc"s (admin defined commands). See doc/admin-defined-commands.mkd for how to do that.
how it actually works
This section tells you what is happening inside gitolite so you can understand this feature better. Let's use the config example at the beginning of this document:
repo assignments/CREATOR/a[0-9][0-9]
C = @students
RW+ = CREATOR
RW = WRITERS @TAs
R = READERS @prof
First we find the set of rules to apply. This involves replacing the special words CREATOR, WRITERS, and READERS with appropriate usernames to derive an "effective" ruleset for the repo in question.
For a new repo, replace the word CREATOR in all repo patterns and rules with the name of the invoking user.
(Note: this is why you should never use
C = CREATOR
; it becomesC = invoking_user
! Unless you really want to allow all users to create repos, you should restrict "C" perms to an actual user or set of users, like in the examples in this document).
For an existing repo, do the same but replace with the name of the user who actually created the repo (this name is recorded in a special file in the repo directory when the repo is first created, so it is available).
Now find a repo pattern that matches the actual reponame being pushed -- this tells you which set of rules to apply. There can be multiple matches; if so, they will all be applied in the sequence they appear in the config file.
If the invoking user has been put in the "WRITERS" category using setperms
, all
permissions for the the user WRITERS are given to the invoking username (and
similarly for READERS).
At this point we have an effective ruleset, and the normal access rules (R, RW, etc) apply, with the addition that the invoking user needs "C" access to be able to create a repo.
(Note: "C" rights do not automatically give the CREATOR any other rights; they must be specifically given.
RW+ = CREATOR
is recommended in most situations, as you can see in our example).
Assuming user "u4" trying to push-create a new repo called
assignments/u4/a23
, this is what the effective ruleset looks like:
repo assignments/u4/a23
C = @students
RW+ = u4
RW = @TAs
R = @prof
If u4 puts u5 in the "WRITERS" category using setperms
, and u5 tries to
access that repo, the ruleset looks like:
repo assignments/u4/a23
C = @students
RW+ = u4
RW = u5 @TAs
R = @prof
I hope that helps.
Enjoy, and please use with care. This is pretty powerful stuff. As they say: if you break it, you get to keep both pieces :)