uses "git clone -l" then manually sets up the gl-creater and hooks (thanks to Jeff and the kde gang for asking ;-)
242 lines
9.2 KiB
Markdown
242 lines
9.2 KiB
Markdown
# admin defined commands
|
|
|
|
**WARNING: Use this feature only if you really really know what you're doing.
|
|
If you come back to me saying this feature caused a problem, I will only
|
|
laugh. The worse the problem, the louder I will laugh. You won't actually
|
|
hear me laughing, but you'll feel it in your bones, trust me!**
|
|
|
|
There may be other such **WARNING** sections below. **Read all of them**.
|
|
|
|
----
|
|
|
|
In this document:
|
|
|
|
* <a href="#background">background</a>
|
|
* <a href="#setting_it_up">setting it up</a>
|
|
* <a href="#anatomy_of_a_command">anatomy of a command</a>
|
|
* <a href="#example_uses_and_sample_commands_in_contrib">example uses and sample commands in contrib</a>
|
|
* <a href="#fork">fork</a>
|
|
* <a href="#rmrepo">rmrepo</a>
|
|
* <a href="#enable_disable_push_access_temporarily">enable/disable push access temporarily</a>
|
|
* <a href="#bonus_restricted_admin">(bonus) restricted admin</a>
|
|
|
|
----
|
|
|
|
<a name="background"></a>
|
|
|
|
### background
|
|
|
|
Gitolite was named to be short for "gitosis-lite". Someone now wants to turn
|
|
it into a "github-lite" :-) and even had some code to start me off thinking.
|
|
|
|
Since my first impulse on being asked for a feature is to say no, I was
|
|
casting about for a reason when he gave me one: he first made some noises
|
|
about perl, then said something about rewriting it all in scheme. Nice... I
|
|
resisted the urge to point him to [this][xkcd224], told him that's a great
|
|
idea and he should go for it, mentally blessing him for letting me off the
|
|
hook on coding it ;-) [Laziness][lazy] *is* the first virtue you know!
|
|
|
|
[xkcd224]: http://xkcd.com/224/
|
|
[lazy]: http://c2.com/cgi/wiki?LazinessImpatienceHubris
|
|
|
|
And that was that. For a couple of days.
|
|
|
|
Soon, though, I realised that there could be a pretty big bonus in this for
|
|
tightly controlled setups, so I went and coded it all anyway. See the section
|
|
on "restricted admin" for what's really exciting about this for *me*.
|
|
|
|
----
|
|
|
|
It may be a good idea to read [doc/4-wildcard-repositories.mkd][wild] before
|
|
you continue here though, because most of the uses of this feature also need
|
|
wildcard repos. (This also means you must set `$GL_WILDREPOS` to "1" in the
|
|
rc file).
|
|
|
|
[wild]: http://github.com/sitaramc/gitolite/blob/pu/doc/4-wildcard-repositories.mkd
|
|
|
|
The wildcard repo feature is a way to create repositories matching a pattern
|
|
(even if it as simple as `personal/CREATOR/.+`), and a way to specify two
|
|
categories of permissions for each such user-created repo.
|
|
|
|
What we want now is more than that, as you'll see in the examples below. And
|
|
I'm sure if you think of more uses you'll send them to me as "contrib"
|
|
entries, right?
|
|
|
|
<a name="setting_it_up"></a>
|
|
|
|
### setting it up
|
|
|
|
This can only be setup by someone who has shell access to the server. Edit
|
|
the rc file and update the `$GL_ADC_PATH` variable to point to, say,
|
|
`/home/git/bin/adc`. *Nothing happens unless this variable is set and
|
|
pointing to a directory*. Then put in whatever such commands you create into
|
|
that directory. If you have a command called "foo" in that directory, then a
|
|
user can invoke it by saying:
|
|
|
|
ssh git@server foo argument list
|
|
|
|
**WARNING: When gitolite takes control, this directory is checked first, and
|
|
if the requested command exists, it is executed. It is therefore quite easy
|
|
to inadvertently *hide* some of the "official" commands (like "info",
|
|
"expand", "setperms", etc., or worse, say "git-upload-pack"!) by creating
|
|
executable files with those names in this directory. So don't do that -- you
|
|
have been warned!**
|
|
|
|
<a name="anatomy_of_a_command"></a>
|
|
|
|
### anatomy of a command
|
|
|
|
You can basically do whatever you want in such a command -- go wild! It's
|
|
upto you to check the permissions of *each* repo that the user is manipulating
|
|
using your command -- you can `rm -rf $GL_REPO_BASE_ABS` if you like and
|
|
gitolite wouldn't stop you.
|
|
|
|
The current directory (`$PWD`) will be set to the `$HOME` of `git@server` (or
|
|
whatever id you're using). It won't be any specific repo, it won't even be
|
|
the base directory of all the repos.
|
|
|
|
Gitolite defines a few environment variables, as well as allows you to
|
|
directly query the ownership and access permissions of any repository.
|
|
|
|
The environment variables available are:
|
|
|
|
* `GL_USER` -- the name of the user invoking the command
|
|
* `GL_BINDIR` -- the directory containing all the binaries (in particular,
|
|
`gitolite.pm`, which is all we really care about here)
|
|
* `GL_REPO_BASE_ABS` -- the absolute path of the base directory containing
|
|
all the repos
|
|
|
|
There are a few other variables also available but the above are the only ones
|
|
you should rely on. Please treat any other variables you notice as being
|
|
internal/undocumented/subject to change.
|
|
|
|
[Implementation note: some of the distro packagers don't seem to like
|
|
`GL_BINDIR`. I have not tested this in those scenarios, but they probably put
|
|
`gitolite.pm` somewhere in perl's lib path anyway, so it ought to work].
|
|
|
|
In addition, all the arguments of the command are also available to you, so
|
|
you can define your own command syntaxes. Gitolite checks these arguments to
|
|
make sure they fit a somewhat conservative pattern (see `$REPOPATT_PATT` in
|
|
`src/gitolite.pm`), so take that into consideration when designing your
|
|
commands and usage.
|
|
|
|
Finally, you can call gitolite to query ownership and permissions for the
|
|
current user (which may not necessarily be the owner). This is done loosely
|
|
as follows (don't use this exact code yet though):
|
|
|
|
perl -I$HOME/.gitolite/src -Mgitolite -e "cli_repo_rights('reponame')"
|
|
|
|
which will print two space-separated words, something like `_____R__W u1` or
|
|
maybe `____@R_@W <gitolite>`. (The former is the response for a wildcard repo
|
|
created by user `u1`, the latter is for a non-wildcard repo)
|
|
|
|
But that's cumbersome. There's a bash shell function called
|
|
`get_rights_and_owner` in `contrib/adc/adc.common-functions` that is much more
|
|
convenient. See any of the other samples for how to use it.
|
|
|
|
If you don't like this, roll your own. If you don't like bash, do the eqvt in
|
|
your language of choice.
|
|
|
|
<a name="example_uses_and_sample_commands_in_contrib"></a>
|
|
|
|
### example uses and sample commands in contrib
|
|
|
|
<a name="fork"></a>
|
|
|
|
#### fork
|
|
|
|
A user would use the fork command like this:
|
|
|
|
ssh git@server fork from to
|
|
|
|
where "from" is a repo to which the user invoking the fork has "R" access, and
|
|
"to" is a repo that does not yet exist and to which he has "C" access.
|
|
|
|
(Reminder: these access checks are done by the "fork" script, **not** within
|
|
gitolite -- once again, you are responsible for making sure your scripts
|
|
maintain the security of the system!)
|
|
|
|
Strictly speaking this command is not really needed. Even without all this
|
|
"admin-defined commands" setup you could still do the following, purely from
|
|
the client side:
|
|
|
|
git clone git@server:from
|
|
cd from
|
|
git remote add new git@server:to
|
|
git push new refs/*:refs/*
|
|
|
|
or some such incantation.
|
|
|
|
<a name="rmrepo"></a>
|
|
|
|
#### rmrepo
|
|
|
|
This is one thing that you really could not do before this setup was created.
|
|
Use it like this:
|
|
|
|
ssh git@server rmrepo reponame
|
|
|
|
The script checks to make sure that the repo being deleted was *created* by
|
|
the user invoking it.
|
|
|
|
<a name="enable_disable_push_access_temporarily"></a>
|
|
|
|
#### enable/disable push access temporarily
|
|
|
|
If you want to disable push access to gitolite temporarily (maybe for
|
|
maintenance), anyone with write access to the gitolite-admin repo can do this:
|
|
|
|
ssh git@server able dis @all # able dis ==> dis able
|
|
|
|
To re-enable after the maint work is done:
|
|
|
|
ssh git@server able en @all # able en ==> en able
|
|
|
|
You can also do this for one or more individual repos; in place of `@all`,
|
|
just use a space separated list of reponames (exactly as they would appear in
|
|
the config file). Wildcards are not supported; patches welcome ;-)
|
|
|
|
**NOTE: This needs a specific secondary update hook**. Creating a secondary
|
|
update hook is described in the sections on "custom hooks" and "hook chaining"
|
|
in doc/2. You need code like this in `update.secondary` (don't forget to
|
|
`chmod +x` the file):
|
|
|
|
#!/bin/bash
|
|
|
|
for f in $HOME/.gitolite.down $PWD/.gitolite.down
|
|
do
|
|
if [ -f $f ]
|
|
then
|
|
echo >&2
|
|
echo '*** ABORT ***' >&2
|
|
echo >&2
|
|
cat $f >&2
|
|
exit 1
|
|
fi
|
|
done
|
|
|
|
exit 0
|
|
|
|
<a name="bonus_restricted_admin"></a>
|
|
|
|
#### (bonus) restricted admin
|
|
|
|
It's rather important to me (and presumably others in the "corporate" world)
|
|
to separate permission to push to the "gitolite-admin" repo from unrestricted
|
|
shell access to the server. This issue has been visited often in the past.
|
|
|
|
Until now, though, this was binary -- you either had full shell access or none
|
|
at all. If there were tasks that legitimately needed to be done from the
|
|
shell on the server, it often meant you had to break that separation or load
|
|
the few people who did have shell access already.
|
|
|
|
Now, however, it is possible to provide scripts to do what you want, and put
|
|
them in `$GL_ADC_PATH`. `contrib/adc/restrict-admin` is a commented sample --
|
|
as you can see, it cleverly makes use of the fact that you can now check for
|
|
the invoking uses access to any repo in the system. In this case it checks if
|
|
he has "W" access to the gitolite-admin repo, and if he does, allows the
|
|
script to proceed.
|
|
|
|
[Note that this particular use does not require `$GL_WILDREPOS` to be enabled,
|
|
because it's not using any wildcard repos].
|