lots of doc changes reflecting "push to admin" is default now :)

- added comments to easy install to help do it manually
  - README: some stuff moved to tips doc, brief summary of extras
    (over gitosis) added
  - INSTALL: major revamp, easy install and manual install,
    much shorter and much more readable!

plus other docs changed as needed, and updated the tips doc to roll in
some details from "update.mkd" in the "ml" branch
This commit is contained in:
Sitaram Chamarty 2009-10-11 08:31:59 +05:30
parent d0d9cbe3af
commit d78bbe8c3e
9 changed files with 309 additions and 316 deletions

View file

@ -9,17 +9,16 @@
----
Gitolite is the bare essentials of gitosis, with a completely different
config file that allows (at last!) access control down to the branch level,
including specifying who can and cannot *rewind* a given branch. It is
released under GPL v2. See COPYING for details.
Gitolite is a rewrite of gitosis, with a completely different config file that
allows (at last!) access control down to the branch level, including
specifying who can and cannot *rewind* a given branch.
In this document:
* why
* what's gone
* what's new
* the workflow
* what's extra
* security
* contact and license
----
@ -32,30 +31,15 @@ a typical $DAYJOB setting, there are some issues:
and be done
* often, "python-setuptools" isn't installed (and on a Solaris9 I was trying
to help remotely, we never did manage to install it eventually)
* or you don't have root access, or the ability to add users
* you don't have root access, or the ability to add users (this is also true
for people who have just one userid on a hosting provider)
* the most requested feature (see "what's new?") had to be written anyway
### what's gone
While I was pondering the need to finally learn python[1] , I also realised
that:
* no one in $DAYJOB type environments will use or approve access methods
that work without any authentication, so I didn't need gitweb/daemon
support in the tool or in the config file.
Update 2009-09-24: I don't use this feature but someone wanted it, so I
added it... see the "faq, tips, etc" document for more
* the idea that you admin it by pushing to a special repo is nice, but not
really necessary because of how rarely these changes are made, especially
considering how much code is involved in that piece
All of this pointed to a rewrite. In perl, naturally :-)
### what's new
### what's extra
Per-branch permissions. You will not believe how often I am asked this at
**Per-branch permissions**. You will not believe how often I am asked this at
$DAYJOB. This is almost the single reason I started *thinking* about rolling
my own gitosis in the first place.
@ -65,50 +49,42 @@ deleting a branch (which is really just an extreme form of rewind). I needed
something in between allowing anyone to do it (the default) and disabling it
completely (`receive.denyNonFastForwards` or `receive.denyDeletes`).
Take a look at the example config file in the repo to see how I do this. I
copied the basic idea from `update-hook-example.txt` (it's one of the "howto"s
that come with the git source tree). However, please note the difference in
the size and complexity of the *operational code* between the update hook in
that example, and in mine :-) The reason is in the next section.
Here're **some more features**. All of them are documented in detail
somewhere in the `doc/` subdirectory.
### the workflow
* simpler, yet far more powerful, config file syntax, including specifying
gitweb/daemon access. You'll need this power if you manage lots of users
+ repos + combinations of access
* config file syntax gets checked upfront, and much more thoroughly
* if your requirements are still too complex, you can split up the config
file and delegate authority over parts of it
* more comprehensive logging [aka: management does not think "blame" is just
a synonym for "annotate" :-)]
* "personal namespace" prefix for each dev
* migration guide and simple converter for gitosis conf file
* "exclude" (or "deny" rights in the config file) -- this is the "rebel"
branch in the repository, and always will be ;-)
In order to get per-branch access, you *must* use an update hook. However,
that only gets invoked on a push; "read" access still has to be controlled
right at the beginning, before git even enters the scene (just the way gitosis
currently works).
### security
So: either split the access control into two config files, or have two
completely different programs *both* parse the same one and pick what they
want. Crap... I definitely don't want the hook doing any parsing, (and it
would be nice if the auth-control program didn't have to either).
Due to the environment in which this was created and the need it fills, I
consider this a "security" program, albeit a very modest one. The code is
very small and easily reviewable -- the 2 programs that actually control
access when a user logs in total about 200 lines of code (about
80 lines according to "sloccount").
So I changed the workflow completely:
For the first person to find a security hole in it, defined as allowing a
normal user (not the gitolite admin) to read a repo, or write/rewind a ref,
that the config file says he shouldn't, and caused by a bug in *code* that is
in the "master" branch, (not in the other branches, or the configuration file
or in Unix, perl, shell, etc.)... well I can't afford 1000 USD rewards like
djb, so you'll have to settle for 1000 INR (Indian Rupees) as a "token" prize
:-)
* all admin changes happen *on the server*, in a special directory that
contains the config and the users' pubkeys. But there's no commit and
push afterward
* instead, after making changes, you "compile" the configuration. This
refreshes `~/.ssh/authorized_keys`, as well as puts a parsed form of the
access list in a file for the other two pieces to use.
----
The pre-parsed form is basically a huge perl variable. It's human readable
too (never mind what the python guys say!)
### contact and license
So the admin knows immediately if the config file had any problems, which is
good. Also, the relatively complex parse code is not part of the actual
access control points, which are:
* the program that is run via `~/.ssh/authorized_keys` (I call it
`gl-auth-command`, equivalent to `gitosis-serve`); this decides whether
git should even be allowed to run (basic R/W/no access)
* the update-hook on each repo, which decides the per-branch permissions
### footnotes
[1] I hate whitespace to mean anything significant except for text; this is a
personal opinion *only*, so pythonistas please back off :-)
### contact
Gitolite is released under GPL v2. See COPYING for details.
sitaramc@gmail.com

View file

@ -5,7 +5,7 @@
# this file is meant to be pulled into a perl program using "do" or "require".
# You do NOT need to know perl to edit the paths; it should be fairly
# self-explanatory
# self-explanatory and easy to maintain perl syntax :-)
# --------------------------------------

View file

@ -1,9 +1,24 @@
# installing gitolite
This document tells you how to install gitolite. After the install is done,
you may want to see the "admin" document for adding users, repos, etc.
There's an easy install script for Linux, and for other Unixes there's a
slightly more manual process. Both are explained here.
In this document:
* easy install
* manual install
* other notes
* next steps
----
### easy install
There is now an easy install script that makes installing very easy for the
common case. **This script is meant to be run on your workstation, not on the
There is an easy install script that makes installing very easy for the common
case. **This script is meant to be run on your workstation, not on the
server!** It will take care of all the server side work, *and* get you
"push-to-admin" too :-) In short, it does **everything**!
@ -35,110 +50,26 @@ info).
#### disadvantages
* has been tested only with Linux. However, the script now makes a much
better "document" on what actually needs to be done, so people installing
on non-Linux machines can probably follow the steps in the script and
install if they wish. Sort of "simulate" it... :)
* has been tested only with Linux
### manual install
If for some reason you cannot use the easy-install method, (for example,
you're on a non-Linux machine) read on. Unlike the easy install, all the
below stuff is meant to be run on the server.
you're on a non-Linux machine), it's not very complicated. Just open the file
`src/00-easy-install.sh` in a nice, syntax coloring, text editor, and follow
the instructions marked "MANUAL" :-)
#### pre-requisites on the server
### other notes
If you managed to install git, you might already have what gitolite needs:
* git itself, the more recent the better
* perl, typically installed with git, since git sort of needs it; any
version that includes `Data::Dumper`[1] will do.
* one user account on the server, with password access [2]
A major objective is to allow use by people without root access, permissions
to create other userids, etc. Even if you have root, please add a user just
for gitolite and do all this from that user.
#### getting a tar file from a clone
You can clone the repo from github, then execute a make command to extract a
tar file of the branch you want. Please use the make command, not a plain
"git archive". The comments in the `Makefile` will explain why.
git clone git://github.com/sitaramc/gitolite.git
cd gitolite
make master.tar
# or maybe "make rebel.tar" or "make pu.tar"
#### install from tar file
* make a temp directory somewhere, cd to it, and unpack the tar file
* run `src/install.pl` and follow the prompts
**When you are told to edit some file, please read the comments in the file**.
And if you can make some time to read the documentation, please do.
Especially if you have problems.
Notes:
* At present the location of `~/.gitolite.rc` is fixed (maybe later I'll
change it to a "git config" variable but I don't see much need right now)
If you edit it and change any paths, be sure to keep the perl syntax --
you *don't* have to know perl to do so, it's fairly easy to guess in this
limited case. And of course, make sure you adjust the commands shown
above to suit the new locations
* If you edit `~/.gitolite.rc` and change any paths, be sure to keep the
perl syntax -- you *don't* have to know perl to do so, it's fairly easy to
guess in this limited case
* the config file is (by default) at `~/.gitolite/conf/gitolite.conf`,
though you can change its location in the "rc" file. Edit the file as you
wish. The comments in the file ought to be clear enough but let me know
if not
wish. The comments in the example file (`conf/example.conf`) ought to be
clear enough but let me know if not
* if you want to bring in existing (bare, server) repos into gitolite, this
should work (refer to `~/.gitolite.rc` for *your* values of the pathnames
below):
* backup the repo, then move it to `$BASE_REPO`
* copy `$GL_ADMINDIR/src/update-hook.pl` to
`[reponame].git/hooks/update` -- if you don't do this, per branch
restrictions will not work
* then update the keys and the config file and "compile" (see "admin"
document)
### next steps
### Footnotes:
[1] Actually, due to the way gitolite is architected, you can manage
without `Data::Dumper` on the server if you have no choice. Only
`gl-compile-conf` needs it, so just run that on some other machine and copy
the two output files across. Cumbersome but doable... the advantage of
separating all the hard work into a manually-run piece :)
[2] If you have *only* pubkey access, and **no** password access, then your
pubkey is already in the server's `~/.ssh/authorized_keys`. If you also need
to access git as a developer (clone, push, etc), do *not* submit this same
pubkey to gitolite -- it won't work.
Instead, create a different keypair for your "developer" role (by, e.g.,
`ssh-keygen -t rsa -f ~/.ssh/gitdev`), then give `~/.ssh/gitdev.pub` to
gitolite as "yourname.pub", just like you would do for any other user.
Then you create a suitable `~/.ssh/config` to use the correct key
automatically, something like this:
host gitadm
hostname my.server
user my_userid_on_server
host gitdev
hostname my.server
user my_userid_on_server
identityfile ~/.ssh/gitdev
From now on, `ssh gitadm` will get you a command line on the server, to do
gitolite admin and other work. And your repository URLs would look like
`gitdev:reponame.git`. Very, very, simple...
And as with gitosis, there's more "ssh" magic than "git" magic here :-)
----
gitolite is released under the GPL v2 license. See COPYING for details
See the "admin" document for how to add users, etc.

View file

@ -1,11 +1,19 @@
# upgrading gitolite atomically
Upgrading is done **manually, on the server** (except the last step, which is
on your admin repo clone), even if you installed it using the easy install
script on the client. First, it's not as difficult as an install so you don't
really need a script. Second, you may have customised the "rc" file
(`~/.gitolite.rc` on the server) and I'm reluctant to mess with that in an
automated way.
### general upgrade notes
If you follow the steps below, you can make the upgrade "atomic", so you don't
have to do it at a "quiet" time or something.
1. untar the new version to some temp directory and `cd` to it
1. copy a tar file containing the new version to the server, untar it to some
temp directory and `cd` to it
2. *prepare* the new version of `~/.gitolite.rc`. It **must** have **all**
the variables defined in `conf/example.gitolite.rc` (the "new" rc file),
@ -31,12 +39,11 @@ have to do it at a "quiet" time or something.
src/install.pl
5. compile the config once again, in case the *internal* format of the
compiled config file (`$GL_CONF_COMPILED`) has changed
compiled config file (`$GL_CONF_COMPILED`) has changed.
src/gl-compile-conf
(if you've already setup "push-to-admin", this step should be replaced by
a "git push". Make a dummy commit if needed, to make the push happen).
To do this, you have to do a "git push" on the client side. That might
require a dummy change (maybe add a blank line somewhere) because
otherwise the push will not happen.
And you're done.
@ -45,6 +52,27 @@ And you're done.
If any extra steps beyond the generic ones above are needed, they will be
listed here, newest first.
#### upgrading from 410c9ba
Between 410c9ba and this version, gitolite managed to make "push to admin" the
default for new installs, but in a much more painless way. If you're
upgrading, you're not forced to use "push to admin", but I'd suggest you:
* make sure you have password-less (pubkey) login to a command line on your
server
* save your `~/.gitolite.rc`, `keydir/*.pub` and your `conf/gitolite.conf`
files from the server, bring them to your workstation
* then run `src/00-easy-install.sh` on the workstation, as if it were a
fresh install
* when the editor pops up to edit the rc file, delete all the lines in
it and copy them from the saved `~/.gitolite.rc`
* at the end of the script, after the gitolite-admin repo has been
cloned successfully, copy the saved `conf/gitolite.conf` and
`keydir/*.pub` to the clone, then add, commit, and push
Gitolite also learnt to delegate parts of the config to other users. See
`doc/5-delegation.mkd` for details.
#### upgrading from 8217ef9
Between 8217ef9 and this version, gitolite learnt to handle gitweb/daemon

View file

@ -3,14 +3,9 @@
[TODO: make the migration tool fix up gitweb and daemon control also...]
Migrating from gitosis to gitolite is pretty easy, because the basic design is
the same. The differences are:
the same.
* gitolite does not use a special repo for the configuration, pubkeys, etc.
You can choose to version that directory but it is not required that you
do so
Here's how we migrated my work repos (note: substitute real paths, from your
`~/.gitolite.rc`, for `$REPO_BASE` and `$GL_ADMINDIR` below):
Here's how we migrated my work repos:
1. login as the `git` user on the server, and get a bash shell prompt
@ -18,10 +13,17 @@ Here's how we migrated my work repos (note: substitute real paths, from your
else. This will prevent users from pushing anything while you do the
backup, migration, etc.
3. For added safety, **delete** the post-update hook that gitosis-admin
3. **edit** `~/.ssh/authorized_keys` and **carefully** remove all the lines
containing "gitosis-serve", as well as the marker line that says
"auto-generated by gitosis, DO NOT REMOVE", then save the file. If the
file did not have any other keys and is now empty, don't worry -- save it
anyway because gitolite expects the file to be present (even if it is
empty).
4. For added safety, **delete** the post-update hook that gitosis-admin
installed
rm $REPO_BASE/gitosis-admin.git/hooks/post-update
rm ~/repositories/gitosis-admin.git/hooks/post-update
or at least rename it to `.sample` like all the other hooks hanging
around, or edit it and comment out the line that calls `gitosis-run-hook
@ -30,39 +32,34 @@ Here's how we migrated my work repos (note: substitute real paths, from your
If you do not do this, an accidental push to the gitosis-admin repo will
mess up your `~/.ssh/authorized_keys` file
4. take a **backup** of the `$REPO_BASE` directory
5. take a **backup** of the `~/repositories` directory
5. untar gitolite to some temporary directory and follow the instructions to
**install** it using `src/install.pl`
Now, log off the server and get back to the client:
6. **convert** your gitosis config file:
1. follow instructions to install gitolite; see install document. Make sure
that you **don't** change the default path for `$REPO_BASE`!
cd $GL_ADMINDIR
src/conf-convert.pl < ~/.gitosis.conf > conf/gitolite.conf
2. **convert** your gitosis config file. Substitute the path for your
gitosis-admin clone in `$GSAC` below, and similarly the path for your
gito**lite**-admin clone in `$GLAC`
be sure to check the file to make sure it converted correctly
src/conf-convert.pl < $GSAC/gitosis.conf > $GLAC/gitolite.conf
7. **copy** the update hook to each of the existing repos (if you have repos
in subdirectories, this won't work as is; adapt it):
Be sure to check the file to make sure it converted correctly
for i in $REPO_BASE/*.git
do
cp src/update-hook.pl $i/hooks/update
done
3. **copy** the keys from gitosis's keydir (same meanings for GSAC and GLAC)
8. **copy** the keys from gitosis's keydir
cp $GSAC/keydir/* $GLAC/keydir
cp $REPO_BASE/gitosis-admin.git/gitosis-export/keydir/* keydir
9. **Important: expand** any multi-key files you may have. See the "faq,
4. **Important: expand any multi-key files you may have**. See the "faq,
tips, etc" document in the doc directory for an explanation of what
multi-keys are, how gitosis does them and how gitolite does it
differently.
You can split the keys manually, or use the following code (just
copy-paste it into your xterm):
copy-paste it into your xterm after "cd"-ing to your gitolite-admin repo
clone):
cd $GL_ADMINDIR
wc -l keydir/*.pub | grep -v total | grep -v -w 1 | while read a b
do
i=1
@ -82,12 +79,4 @@ Here's how we migrated my work repos (note: substitute real paths, from your
"sitaram@laptop.pub" and "sitaram@desktop.pub" or whatever. *Please check
the files to make sure this worked properly*
10. **edit** `~/.ssh/authorized_keys` and **carefully** remove all the lines
containing "gitosis-serve", as well as the marker line that says
"auto-generated by gitosis, DO NOT REMOVE", then save the file. If the
file did not have any other keys and is now empty, don't worry -- save it
anyway because gitolite expects the file to be present (even if it is
empty).
At this point you're ready to "compile" the configuration. See the "admin"
document for what to do, and how to check the outputs, etc.
5. Check all your changes to your gitolite-admin clone, commit, and push

View file

@ -22,15 +22,15 @@ Please read on to see how to do this correctly.
extension, like `sitaram.pub` or `john-smith.pub`. You can also use
periods and underscores
* copy all these `*.pub` files to `$GL_KEYDIR`
* copy all these `*.pub` files to `keydir` in your gitolite-admin repo clone
* the config file (`$GL_CONF`) is very well commented, please take a couple
of minutes to read it. Then edit it and
* edit the config file (`conf/gitolite.conf` in your admin repo clone). See
`conf/example.conf` in the gitolite source for details on what goes in
that file, syntax, etc. Just add new repos as needed, and add new users
and give them permissions as required. The users names should be exactly
the same as their keyfile names, but without the `.pub` extension
* add new repos as needed
* add new users and give them permissions as required. The users names
should be exactly the same as their keyfile names, but without the
`.pub` extension
* when done, commit your changes and push
#### specifying gitweb and daemon access
@ -51,41 +51,6 @@ one-time setup you must do separately. All this does is:
value you specified for `$projects_list` when setting up gitweb)
* for daemon, create the file `git-daemon-export-ok` in the repository
`src/gl-compile-conf` will keep these files consistent with the config
settings -- this includes removing such settings if you remove "read"
permissions for the special usernames.
#### compiling
* backup your `~/.ssh/authorized_keys` file if you feel nervous :-)
* that's "backup" as in "copy", not "move". The next step won't work if
the file doesn't exist. Even an empty one is fine but it must be
present
* if you don't have an `~/.ssh/authorized_keys` file at all, you may
have logged in with a password, which in turn might mean you are not
familiar with ssh and authkeys etc. If so, please read up at least
[this](http://sitaramc.github.com/0-installing/9-gitolite-basics.html#IMPORTANT_overview_of_ssh),
and preferably also the man pages for sshd and sshd\_config, to make
sure you understand the security implications of what you are doing.
Once you have understood that, create at least an empty
`~/.ssh/authorized_keys` file before proceeding to the next step
* cd to `$GL_ADMINDIR` and run `src/gl-compile-conf`
That should be it, really. However, if you want to be doubly sure, or maybe
the first couple of times you use it, you may want to check these:
* check the outputs
* `~/.ssh/authorized_keys` should contain one line for each "user" pub
key added, between two "marker" lines (which you should please please
not remove!). The line should contain a "command=" pointing to a
`$GL_ADMINDIR/src/gl-auth-command` file, then some sshd restrictions, the
key, etc.
* `$GL_CONF_COMPILED` should contain an expanded list of the access
control rules. It may look a little long, but it's fairly intuitive!
* if the run threw up any "initialising empty repo" messages, check the
individual repos (inside `$REPO_BASE`) if you wish. Especially make sure
the `$REPO_BASE/[reponame].git/hooks/update` got copied OK and is
executable
The "compile" script will keep these files consistent with the config settings
-- this includes removing such settings if you remove "read" permissions for
the special usernames.

View file

@ -5,19 +5,21 @@ In this document:
* common errors and mistakes
* git version dependency
* other errors, warnings, notes...
* getting a tar file from a clone
* differences from gitosis
* simpler syntax
* two levels of access rights checking
* error checking the config file
* delegating parts of the config file
* easier to specify gitweb/daemon access
* built-in logging
* better logging
* one user, many keys
* who am I?
* other cool things
* developer specific branches
* "personal" branches
* design choices
* why we don't do "excludes"
* keeping the parser and the access control separate
### common errors and mistakes
@ -37,10 +39,10 @@ In this document:
Here's a workaround for a version dependency that the normal flow of gitolite
has.
When you edit your config file to create a new repo, and run
`src/gl-compile-conf`, gitolite creates an empty, bare repo for you.
Normally, you're expected to clone this on the client side, and start working
-- make your first commit(s), then push, etc.
When you edit your config file to create a new repo, and push the changes to
the server, gitolite creates an empty, bare repo for you. Normally, you're
expected to clone this on the client side, and start working -- make your
first commit(s), then push, etc.
However, cloning an empty repo requires a server side git version that is at
least 1.6.2. Gitolite detects this when creating a repo, and warns you.
@ -74,21 +76,27 @@ normal way, since it's not empty anymore.
* if you specify a repo that is not at the top level `$REPO_BASE`, be sure
to manually create the intermediate directories first. For instance if
you specify a new repo called "a/b/c" to the config file and "compile",
the "compile" script will just `mkdir a/b/c.git`, assuming "a/b" has
already been created
* if you run `git init` inside `$GL_ADMINDIR` (that is, make it a normal,
non-bare, repo), then, everytime you "compile" (run
`src/gl-compile-conf`), any changes to `conf` and `keydir` will
automatically be committed. This is a simple safety net in case you
accidentally delete the whole config or something. Also see
[4-push-to-admin.mkd](http://github.com/sitaramc/gitolite/blob/pu/doc/4-push-to-admin.mkd)
if you really know what you're doing and want "push to admin"
you specify a new repo called "a/b/c" to the config file and push, the
"compile" script will just `mkdir a/b/c.git`, assuming "a/b" has already
been created
* gitweb not able to read your repos? You can change the umask for newly
created repos to something more relaxed -- see the `~/.gitolite.rc` file
### getting a tar file from a clone
You can clone the repo from github or indefero, then execute a make command to
extract a tar file of the branch you want. Please use the make command, not a
plain "git archive", because the Makefile adds a file called
`.GITOLITE-VERSION` that will help you identify which version you are using.
git clone git://github.com/sitaramc/gitolite.git
# (OR)
git clone git://sitaramc.indefero.net/sitaramc/gitolite.git
cd gitolite
make master.tar
# or maybe "make rebel.tar" or "make pu.tar"
### differences from gitosis
Apart from the big ones listed in the top level README, and subjective ones
@ -176,9 +184,8 @@ gitosis does not do any. I just found out that if you mis-spell `members` as
`member`, gitosis will silently ignore it, and leave you wondering why access
was denied.
In gitolite, you have to "compile" the config file first (this step takes the
place of the commit+push in gitosis), and keyword typos *are* caught so you
know right away.
Gitolite "compiles" the config file first and keyword typos *are* caught so
you know right away.
#### delegating parts of the config file
@ -219,24 +226,21 @@ bits and pieces. Here's an example, using short repo names for convenience:
repo r2
# ...and so on...
#### built-in logging
### better logging
...just in case of emergency :-)
If you have been too liberal with the permission to rewind, it has built-in
logging as an emergency fallback if someone goes too far, or for audit
purposes [`*`]. The logfile names and location are configurable, and can
include the year/month/day etc in the filename for easy archival or further
processing. The log file even tells you which pattern in the config file
matched to allow that specific access to proceed.
Let's say you gave a dev the right to rewind a branch and he went and rewound
it all the way, or pushed something drastically different on it. Now you need
to recover the commit that got wiped out.
> [`*`] setting `core.logAllRefUpdates true` does provide a safety net
> against over-zealous rewinds, but it does not tell you "who". And
> strangely, management does not seem to share the view that "blame" is just
> a synonym for "annotate" ;-)]
If you'd remembered to `git config core.logAllRefUpdates` for that repo, or
globally, you'd be fine -- the reflog will tell you. Otherwise you'd be left
grubbing around in `git fsck --unreachable` a bit :-(
And even if you recover the correct commit, you'll never know *who* did it --
not unless you add a one-line patch to gitosis, plus a `post-receive` hook to
every repository.
With gitolite, there's a log file in `$GL_ADMINDIR` that contains lines like
this:
The log lines look like this:
2009-09-19.10:24:37 + b4e76569659939 4fb16f2a88d8b5 myrepo refs/heads/master user2 refs/heads/master
@ -283,33 +287,31 @@ In gitolite, it's simple: just ask nicely :-)
### other cool things
#### developer specific branches
### "personal" branches
So I know what gitolite calls me. Big deal... who cares?
"personal" branches are great for corporate environments, where
unauthenticated pull/clone is a no-no. Since a dev workstation cannot do
authentication, even work shared just between 2 devs has to go *via* the
server. This causes the same branch name clutter as in a centralised VCS,
plus setting up permissions for this becomes a chore for the admin.
Here is an idea: give every developer a personal "scratch" namespace within
which she can create, rewind, or delete any branch. For example, I would own
anything under
gitolite lets you define a "personal" or "scratch" namespace prefix for
each developer (e.g., `refs/personal/<devname>/*`), with full
permissions for that dev and read-only for everyone else. And you get
this without adding a single line to the access config file -- pretty
much fire and forget as far as the admin is concerned, even if there is
constant churn in the project teams.
$PERSONAL_BRANCH_PREFIX/sitaram/
Not bad for something that took just *one* line of code to implement.
And that's one clean, readable, line, by the way ;-)
The admin could set `$PERSONAL_BRANCH_PREFIX` in the rc file and communicate
The admin would set `$PERSONAL_BRANCH_PREFIX` in the rc file and communicate
this to all users. It could be something like `refs/heads/personal`, which
means all such branches will show up in `git branch` lookups and `git clone`
will fetch them. Or he could use, say, `refs/personal`, which means it won't
show up in any normal "branch-y" commands and stuff, and generally be much
less noisy.
Yes, I know git is all about allowing private branches, but in a corporate
environment it's not always possible to pull from a co-worker, for the same
reasons you don't have anonymous access (like the git:// protocol). A normal
developer workstation cannot do authentication, so how would they know who's
pulling? This is a perfect way to share code *without* cluttering the global
namespace, and each developer controls his/her own set of branches!
The amount of code needed? *One line!* I'll spend about 3x more on declaring
and initialising the new variable, and 30x more on documenting it :-)
**Note that a user who has NO write access cannot have personal branches**; if
you read the section (above) on "two levels of access rights checking" you'll
understand why.
@ -343,6 +345,9 @@ Just don't *show* the user this config file; it might sound insulting :-)
#### why we don't do "excludes"
[umm... having said all this, I implemented it anyway; see the "rebel"
branch!]
I found an error in the example conf file. This snippet *seems* to say that
"bruce" can write versioned tags (`refs/tags/v[0-9].*`), but the other
staffers can't:
@ -387,3 +392,24 @@ The lack of overlap between refexes ensures ***no confusion*** in specifying,
understanding, and ***auditing***, what is allowed and what is not.
And in security, "no confusion" is a good thing :-)
#### keeping the parser and the access control separate
There are two programs concerned with access control:
* `gl-auth-command`, the program that is run via `~/.ssh/authorized_keys`;
this decides whether git should even be allowed to run (basic R/W/no
access). (This one cannot decide on the branch-level access; it is not
known at this point what branch is being accessed)
* the update-hook on each repo, which decides the per-branch permissions
I have chosen to keep the relatively complex task of parsing the config file
out of them to keep them simpler (and faster). So any changes to the config
have to be first "compiled", and the access control programs use this
"compiled" version of the config. (The compile step also refreshes
`~/.ssh/authorized_keys`).
If you choose the "easy install" method, all this is quite transparent to you
anyway. If you cannot use the easy install and must install manually, I have
clear instructions on how to set it up.

View file

@ -1,5 +1,10 @@
# "push to admin" in gitolite
**WARNING: THIS DOCUMENT IS OBSOLETE. DO NOT USE. IT IS RETAINED ONLY FOR
HISTORICAL PURPOSES**. Gitolite now does "push-to-admin" by default, and does
it very easily and simply by front-loading the ssh problem. See the install
doc for details.
----
Gitosis's default mode of admin is by cloning and pushing the `gitosis-admin`

View file

@ -2,9 +2,13 @@
# easy install for gitolite
# this runs on the client side, and itself takes care of all the server side
# you run this on the client side, and it takes care of all the server side
# work. You don't have to do anything on the server side directly
# to do a manual install (since I have tested this only on Linux), open this
# script in a nice, syntax coloring, text editor and follow the instructions
# prefixed by the word "MANUAL" in the comments below :-)
# run without any arguments for "usage" info
# important setting: bail on any errors (else we have to check every single
@ -63,6 +67,9 @@ EOFU
[[ "$1" =~ [^a-zA-Z0-9._-] ]] && die "user '$1' invalid"
[[ "$3" =~ [^a-zA-Z0-9._-] ]] && die "admin_name '$3' invalid"
# MANUAL: (info) we'll use "git" as the user, "server" as the host, and
# "sitaram" as the admin_name in example commands shown below, if any
user=$1
host=$2
admin_name=$3
@ -71,8 +78,9 @@ admin_name=$3
# basic sanity checks
# ----------------------------------------------------------------------
# are we in the right directory? We should have all the gitolite sources
# here...
# MANUAL: make sure you're in the gitolite directory, at the top level.
# The following files should all be visible:
ls src/gl-auth-command \
src/gl-compile-conf \
src/install.pl \
@ -81,16 +89,23 @@ ls src/gl-auth-command \
conf/example.gitolite.rc >/dev/null ||
die "cant find at least some files in gitolite sources/config; aborting"
# do we have pubkey auth on the server
# MANUAL: make sure you have password-less (pubkey) auth on the server. That
# is, running "ssh git@server" should log in straight away, without asking for
# a password
ssh -o PasswordAuthentication=no $user@$host pwd >/dev/null ||
die "pubkey access didn't work; please set it up using 'ssh-copy-id' or something"
# can the "gitolite-admin" repo be safely created in $HOME
# MANUAL: make sure there's no "gitolite-admin" directory in $HOME (actually
# for the manual flow this doesn't matter so much!)
[[ -d $HOME/gitolite-admin ]] &&
die "please delete or move aside the \$HOME/gitolite-admin directory"
# cool; now let's create a new key for you as a "gitolite user" (as opposed to
# a gitolite admin who needs to login to the server and get a command line)
# MANUAL: create a new key for you as a "gitolite user" (as opposed to you as
# the "gitolite admin" who needs to login to the server and get a command
# line). For example, "ssh-keygen -t rsa ~/.ssh/sitaram"; this would create
# two files in ~/.ssh (sitaram and sitaram.pub)
[[ -f $HOME/.ssh/$admin_name.pub ]] && die "pubkey $HOME/.ssh/$admin_name.pub exists; can't proceed"
prompt "the next command will create a new keypair for your gitolite access
@ -111,6 +126,15 @@ prompt "the next command will create a new keypair for your gitolite access
ssh-keygen -t rsa -f $HOME/.ssh/$admin_name || die "ssh-keygen failed for some reason..."
# MANUAL: copy the pubkey created to the server, say to /tmp. This would be
# "scp ~/.ssh/sitaram.pub git@server:/tmp" (the script does this at a later
# stage, you do it now for convenience). Note: only the pubkey (sitaram.pub).
# Do NOT copy the ~/.ssh/sitaram file -- that is a private key!
# MANUAL: if you're running ssh-agent (see if you have an environment variable
# called SSH_AGENT_PID in your "env"), you should add this new key. The
# command is "ssh-add ~/.ssh/sitaram"
if [[ -n $SSH_AGENT_PID ]]
then
prompt "you're running ssh-agent. We'll try and do an ssh-add of the
@ -121,7 +145,17 @@ then
ssh-add $HOME/.ssh/$admin_name
fi
# ok the gitolite key is done; create a stanza for it in ~/.ssh/config
# MANUAL: you now need to add some lines to the end of your ~/.ssh/config
# file. If the file doesn't exist, create it. Make sure the file is "chmod
# 644".
# The lines to be included look like this:
# host gitolite
# hostname server
# user git
# identityfile ~/.ssh/sitaram
echo "
host gitolite
hostname $host
@ -153,10 +187,22 @@ rm $HOME/.ssh/.gl-stanza
# client side stuff almost done; server side now
# ----------------------------------------------------------------------
# setup the gitolite sources and conf on the server
# MANUAL: copy the gitolite directories "src", "conf", and "doc" to the
# server, to a directory called (for example) "gitolite-install". You may
# have to create the directory first.
ssh $user@$host mkdir -p gitolite-install
rsync -a src conf doc $user@$host:gitolite-install/
# MANUAL: now log on to the server (ssh git@server) and get a command line.
# This step is for your convenience; the script does it all from the client
# side but that may be too much typing for manual use ;-)
# MANUAL: cd to the "gitolite-install" directory where the sources are. Then
# copy conf/example.gitolite.rc as ~/.gitolite.rc and edit it if you wish to
# change any paths. Make a note of the GL_ADMINDIR and REPO_BASE paths; you
# will need them later
# give the user an opportunity to change the rc
cp conf/example.gitolite.rc .gitolite.rc
# hey here it means "release candidate" ;-)
@ -183,10 +229,17 @@ relevant for a manual install, not this one..."
GL_ADMINDIR=$(ssh $user@$host "perl -e 'do \".gitolite.rc\"; print \$GL_ADMINDIR'")
REPO_BASE=$( ssh $user@$host "perl -e 'do \".gitolite.rc\"; print \$REPO_BASE'")
# run the install script on the server
# MANUAL: still in the "gitolite-install" directory? Good. Run
# "src/install.pl"
ssh $user@$host "cd gitolite-install; src/install.pl"
# setup the initial config file
# MANUAL: setup the initial config file. Edit $GL_ADMINDIR/conf/gitolite.conf
# and add at least the following lines to it:
# repo gitolite-admin
# RW+ = sitaram
echo "#gitolite conf
#please see conf/example.conf for details on syntax and features
@ -203,28 +256,48 @@ scp gitolite.conf $user@$host:$GL_ADMINDIR/conf/
scp $HOME/.ssh/$admin_name.pub $user@$host:$GL_ADMINDIR/keydir
# run the compile script on the server
# MANUAL: cd to $GL_ADMINDIR and run "src/gl-compile-conf"
ssh $user@$host "cd $GL_ADMINDIR; src/gl-compile-conf"
# ----------------------------------------------------------------------
# hey lets go the whole hog on this; setup push-to-admin!
# ----------------------------------------------------------------------
# setup the initial commit for the admin repo
# MANUAL: make the first commit in the admin repo. This is a little more
# complex, so read carefully and substitute the correct paths. What you have
# to do is:
# cd $REPO_BASE/gitolite-admin.git
# GIT_WORK_TREE=$GL_ADMINDIR git add conf/gitolite.conf keydir
# GIT_WORK_TREE=$GL_ADMINDIR git commit -am start
# Substitute $GL_ADMINDIR and $REPO_BASE appropriately. Note there is no
# space around the "=" in the second and third lines.
echo "cd $REPO_BASE/gitolite-admin.git
GIT_WORK_TREE=$GL_ADMINDIR git add conf/gitolite.conf keydir
GIT_WORK_TREE=$GL_ADMINDIR git commit -am start
" | ssh $user@$host
# MANUAL: now that the admin repo is created, you have to set the hooks
# properly. The install program does this. So cd back to the
# "gitolite-install" directory and run "src/install.pl"
ssh $user@$host "cd gitolite-install; src/install.pl"
prompt "now we will clone the gitolite-admin repo to your workstation
and see if it all hangs together. We'll do this in your \$HOME for now,
and you can move it elsewhere later if you wish to."
# MANUAL: you're done! Log out of the server, come back to your workstation,
# and clone the admin repo using "git clone gitolite:gitolite-admin.git"!
cd $HOME
git clone gitolite:gitolite-admin.git
# MANUAL: be sure to read the message below; this applies to you too...
echo
echo
echo ------------------------------------------------------------------------