Merge branch 'easy-install'
This commit is contained in:
commit
2fdd7b34f5
108
README.mkd
108
README.mkd
|
@ -3,19 +3,22 @@
|
|||
> [IMPORTANT: There is now an "upgrade" document in the "doc" directory;
|
||||
> please read if upgrading gitolite]
|
||||
|
||||
> [Update 2009-10-10: apart from all the nifty new features, there's now an
|
||||
> "easy install" script in the src directory. Please see the INSTALL
|
||||
> document in the doc directory for details]
|
||||
|
||||
----
|
||||
|
||||
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
|
||||
|
||||
----
|
||||
|
||||
|
@ -28,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.
|
||||
|
||||
|
@ -61,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
|
||||
|
|
|
@ -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 :-)
|
||||
|
||||
# --------------------------------------
|
||||
|
||||
|
@ -88,6 +88,16 @@ $PERSONAL="";
|
|||
# NOTE: whatever value you choose, for security reasons it is better to make
|
||||
# it fully qualified -- that is, starting with "refs/"
|
||||
|
||||
# --------------------------------------
|
||||
|
||||
# if git on your server is on a standard path (that is
|
||||
# ssh git@server git --version
|
||||
# works), leave this setting as is. Otherwise, choose one of the
|
||||
# alternatives, or write your own
|
||||
|
||||
$GIT_PATH="";
|
||||
# $GIT_PATH="/opt/bin/";
|
||||
|
||||
# --------------------------------------
|
||||
# per perl rules, this should be the last line in such a file:
|
||||
1;
|
||||
|
|
|
@ -1,98 +1,75 @@
|
|||
# installing gitolite
|
||||
|
||||
### pre-requisites
|
||||
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.
|
||||
|
||||
If you managed to install git, you might already have what gitolite needs:
|
||||
There's an easy install script for Linux, and for other Unixes there's a
|
||||
slightly more manual process. Both are explained here.
|
||||
|
||||
* 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]
|
||||
In this document:
|
||||
|
||||
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"
|
||||
|
||||
### quick 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
|
||||
|
||||
* 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
|
||||
|
||||
* 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)
|
||||
|
||||
### 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 :-)
|
||||
* easy install
|
||||
* manual install
|
||||
* other notes
|
||||
* next steps
|
||||
|
||||
----
|
||||
|
||||
gitolite is released under the GPL v2 license. See COPYING for details
|
||||
### easy install
|
||||
|
||||
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**!
|
||||
|
||||
Assumptions:
|
||||
|
||||
* you have a server to host gitolite
|
||||
* git is installed on that server (and so is perl)
|
||||
* you have a userid on that server
|
||||
* you have ssh-pubkey (password-less) login to that userid
|
||||
* (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`)
|
||||
* you have a clone or an archive of gitolite somewhere on your workstation
|
||||
|
||||
If so, just `cd` to that clone and run `src/00-easy-install.sh` and follow the
|
||||
prompts! (Running it without any arguments shows you usage plus other useful
|
||||
info).
|
||||
|
||||
#### advantages over the older install methods
|
||||
|
||||
* all ssh problems reduced to **just one pre-requisite**: enable ssh pubkey
|
||||
(password-less) access to the server from your workstation first
|
||||
* the script takes care of all the server side work
|
||||
* when done:
|
||||
* you get two different pubkeys (the original one for command line
|
||||
access as before, plus a new one, created by the script, for gitolite
|
||||
access)
|
||||
* you can admin gitolite by commit+push a "gitolite-admin" repo, just
|
||||
like gitosis (i.e., full "push to admin" power!)
|
||||
|
||||
#### disadvantages
|
||||
|
||||
* 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), 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" :-)
|
||||
|
||||
### other notes
|
||||
|
||||
* 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 example file (`conf/example.conf`) ought to be
|
||||
clear enough but let me know if not
|
||||
|
||||
### next steps
|
||||
|
||||
See the "admin" document for how to add users, etc.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -5,19 +5,22 @@ 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
|
||||
* support for git installed outside default PATH
|
||||
* 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 +40,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 +77,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 +185,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 +227,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
|
||||
|
||||
|
@ -259,9 +264,35 @@ each of my pubkeys. In gitolite, we keep them separate: "sitaram@laptop.pub"
|
|||
and "sitaram@desktop.pub". The part before the "@" is the username, so
|
||||
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 --
|
||||
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
|
||||
the extra "@" stuff.
|
||||
|
||||
I think this is easier to maintain if you have to delete or change one of
|
||||
those keys.
|
||||
|
||||
#### support for git installed outside default PATH
|
||||
|
||||
The normal solution is to add to the system default PATH somehow, either by
|
||||
munging `/etc/profile` or by enabling `PermitUserEnvironment` in
|
||||
`/etc/ssh/sshd_config` and then setting the PATH in `~/.ssh/.environment`.
|
||||
All these are security risks because they allow a lot more than just you and
|
||||
your git install :-)
|
||||
|
||||
And if you don't have root, you can't do this anyway.
|
||||
|
||||
The only solution till now has been to ask every client to set the config
|
||||
parameters `remote.<name>.receivepack` and `remote.<name>.uploadpack`. But
|
||||
telling *every* client to do so is a pain...
|
||||
|
||||
Gitolite lets you specify the directory in which git binaries are to be found,
|
||||
via a new variable (`$GIT_PATH`) in the "rc" file. If this variable is
|
||||
non-empty, it will be appended to the PATH environment variable before
|
||||
attempting to run git stuff.
|
||||
|
||||
Very easy, very simple, and completely transparent to the users :-)
|
||||
|
||||
#### who am I?
|
||||
|
||||
As a developer, I send a file called `id_rsa.pub` to the gitolite admin. He
|
||||
|
@ -283,33 +314,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.
|
||||
|
@ -341,8 +370,31 @@ Just don't *show* the user this config file; it might sound insulting :-)
|
|||
|
||||
### design choices
|
||||
|
||||
#### 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.
|
||||
|
||||
#### 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 +439,5 @@ 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 :-)
|
||||
|
||||
|
||||
|
|
|
@ -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`
|
||||
|
|
362
src/00-easy-install.sh
Executable file
362
src/00-easy-install.sh
Executable file
|
@ -0,0 +1,362 @@
|
|||
#!/bin/bash
|
||||
|
||||
# easy install for gitolite
|
||||
|
||||
# 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
|
||||
# command!)
|
||||
set -e
|
||||
|
||||
die() { echo "$@"; echo; echo "run $0 again without any arguments for help and tips"; exit 1; }
|
||||
prompt() {
|
||||
echo
|
||||
echo
|
||||
echo ------------------------------------------------------------------------
|
||||
echo " $1"
|
||||
echo
|
||||
read -p '...press enter to continue or Ctrl-C to bail out'
|
||||
}
|
||||
usage() {
|
||||
cat <<EOFU
|
||||
Usage: $0 user host port admin_name
|
||||
- "user" is the username on the server where you will be installing gitolite
|
||||
- "host" is that server's hostname (or IP address is also fine)
|
||||
- "port" is optional
|
||||
- "admin_name" is *your* name as you want it to appear in the eventual
|
||||
gitolite config file
|
||||
|
||||
Example usage: $0 git my.git.server sitaram
|
||||
|
||||
Output:
|
||||
- a proper gitolite admin repo in $HOME/gitolite-admin
|
||||
|
||||
Notes:
|
||||
- "user" and "admin_name" must be simple names -- no special characters etc
|
||||
please (only alphanumerics, dot, hyphen, underscore)
|
||||
- traditionally, the "user" is "git", but it can be anything you want
|
||||
- "admin_name" should be your name, for clarity, or whoever will be the
|
||||
gitolite admin
|
||||
|
||||
Pre-requisites:
|
||||
- you must run this from the gitolite working tree top level directory.
|
||||
This means you run this as "src/00-easy-install.sh"
|
||||
- you must already have pubkey based access to user@host. If you currently
|
||||
only have password access, use "ssh-copy-id" or something. Somehow get to
|
||||
the point where you can type "ssh user@host" and get a command line. Run
|
||||
this program only after that is done
|
||||
|
||||
Errors:
|
||||
- if you get a "pubkey [...filename...] exists" error, it is either leftover
|
||||
from a previous, failed, run, or a genuine file you need. Decide which it
|
||||
is, and remove it and retry, or use a different "admin_name", respectively.
|
||||
|
||||
EOFU
|
||||
exit 1;
|
||||
}
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# basic sanity / argument checks
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
# MANUAL: this *must* be run as "src/00-easy-install.sh", not by cd-ing to src
|
||||
# and then running "./00-easy-install.sh"
|
||||
|
||||
[[ $0 =~ ^src/00-easy-install.sh$ ]] ||
|
||||
{
|
||||
echo "please cd to the gitolite repo top level directory and run this as
|
||||
'src/00-easy-install.sh'"
|
||||
exit 1;
|
||||
}
|
||||
|
||||
# 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
|
||||
|
||||
[[ -z $3 ]] && usage
|
||||
user=$1
|
||||
host=$2
|
||||
admin_name=$3
|
||||
# but if the 3rd arg is a number, that's a port number, and the 4th arg is the
|
||||
# admin_name
|
||||
port=22
|
||||
[[ $3 =~ ^[0-9]+$ ]] && {
|
||||
port=$3
|
||||
[[ -z $4 ]] && usage
|
||||
admin_name=$4
|
||||
}
|
||||
|
||||
[[ "$user" =~ [^a-zA-Z0-9._-] ]] && die "user '$user' invalid"
|
||||
[[ "$admin_name" =~ [^a-zA-Z0-9._-] ]] && die "admin_name '$admin_name' invalid"
|
||||
|
||||
# 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 \
|
||||
src/update-hook.pl \
|
||||
conf/example.conf \
|
||||
conf/example.gitolite.rc >/dev/null ||
|
||||
die "cant find at least some files in gitolite sources/config; aborting"
|
||||
|
||||
# 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 -p $port -o PasswordAuthentication=no $user@$host true ||
|
||||
die "pubkey access didn't work; please set it up using 'ssh-copy-id' or something"
|
||||
|
||||
# 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"
|
||||
|
||||
# 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)
|
||||
|
||||
prompt "the next command will create a new keypair for your gitolite access
|
||||
|
||||
The pubkey will be $HOME/.ssh/$admin_name.pub. You will have to
|
||||
choose a passphrase or hit enter for none. I recommend not having a
|
||||
passphrase for now, and adding one with 'ssh-keygen -p' *as soon as*
|
||||
all the setup is done and you've successfully cloned and pushed the
|
||||
gitolite-admin repo.
|
||||
|
||||
After that, I suggest you (1) install 'keychain' or something
|
||||
similar, and (2) add the following command to your bashrc (since
|
||||
this is a non-default key)
|
||||
|
||||
ssh-add \$HOME/.ssh/$admin_name
|
||||
|
||||
This makes using passphrases very convenient."
|
||||
|
||||
if [[ -f $HOME/.ssh/$admin_name.pub ]]
|
||||
then
|
||||
prompt "Hmmm... pubkey $HOME/.ssh/$admin_name.pub exists; should I just re-use it?
|
||||
Be sure you remember the passphrase, if you gave one when you created it!"
|
||||
else
|
||||
ssh-keygen -t rsa -f $HOME/.ssh/$admin_name || die "ssh-keygen failed for some reason..."
|
||||
fi
|
||||
|
||||
# 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 ssh-add -l &>/dev/null
|
||||
then
|
||||
prompt "you're running ssh-agent. We'll try and do an ssh-add of the
|
||||
private key we just created, otherwise this key won't get picked up. If
|
||||
you specified a passphrase in the previous step, you'll get asked for one
|
||||
now -- type in the same one."
|
||||
|
||||
ssh-add $HOME/.ssh/$admin_name
|
||||
fi
|
||||
|
||||
# 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
|
||||
# user git
|
||||
# hostname server
|
||||
# port 22
|
||||
# identityfile ~/.ssh/sitaram
|
||||
|
||||
echo "
|
||||
host gitolite
|
||||
user $user
|
||||
hostname $host
|
||||
port $port
|
||||
identityfile ~/.ssh/$admin_name" > $HOME/.ssh/.gl-stanza
|
||||
|
||||
if grep 'host *gitolite' $HOME/.ssh/config &>/dev/null
|
||||
then
|
||||
prompt "your \$HOME/.ssh/config already has settings for gitolite. I will
|
||||
assume they're correct, but if they're not, please edit that file, delete
|
||||
that paragraph (that line and the following few lines), Ctrl-C, and rerun.
|
||||
|
||||
In case you want to check right now (from another terminal) if they're
|
||||
correct, here's what they are *supposed* to look like:
|
||||
$(cat ~/.ssh/.gl-stanza)"
|
||||
|
||||
else
|
||||
prompt "creating settings for your gitolite access in $HOME/.ssh/config;
|
||||
these are the lines that will be appended to your ~/.ssh/config:
|
||||
$(cat ~/.ssh/.gl-stanza)"
|
||||
|
||||
cat $HOME/.ssh/.gl-stanza >> $HOME/.ssh/config
|
||||
# if the file didn't exist at all, it might have the wrong permissions
|
||||
chmod 644 $HOME/.ssh/config
|
||||
fi
|
||||
rm $HOME/.ssh/.gl-stanza
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# client side stuff almost done; server side now
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
# 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 -p $port $user@$host mkdir -p gitolite-install
|
||||
rsync -e "ssh -p $port" -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
|
||||
|
||||
prompt "the gitolite rc file needs to be edited by hand. The defaults
|
||||
are sensible, so if you wish, you can just exit the editor.
|
||||
|
||||
Otherwise, make any changes you wish and save it. Read the comments to
|
||||
understand what is what -- the rc file's documentation is inline.
|
||||
|
||||
Please remember this file will actually be copied to the server, and that
|
||||
all the paths etc. represent paths on the server!"
|
||||
|
||||
# lets try and get the file from there first
|
||||
if scp -P $port $user@$host:.gitolite.rc .
|
||||
then
|
||||
prompt "Oh hey... you already had a '.gitolite.rc' file on the server.
|
||||
Let's see if we can use that instead of the default one..."
|
||||
sort < .gitolite.rc | perl -ne 'print "$1\n" if /^(\$\w+) *=/' > glrc.old
|
||||
sort < conf/example.gitolite.rc | perl -ne 'print "$1\n" if /^(\$\w+) *=/' > glrc.new
|
||||
if diff -u glrc.old glrc.new
|
||||
then
|
||||
${VISUAL:-${EDITOR:-vi}} .gitolite.rc
|
||||
else
|
||||
prompt " looks like you're upgrading! I'm going to run your editor
|
||||
with *both* the old and the new files (in that order), so you can add
|
||||
in the lines pertaining to the variables shown with a '+' sign in the
|
||||
above diff. This is necessary; please dont skip this
|
||||
|
||||
[It's upto you to figure out how your editor handles 2 filename
|
||||
arguments, switch between them, copy lines, etc ;-)]"
|
||||
${VISUAL:-${EDITOR:-vi}} .gitolite.rc conf/example.gitolite.rc
|
||||
fi
|
||||
else
|
||||
cp conf/example.gitolite.rc .gitolite.rc
|
||||
${VISUAL:-${EDITOR:-vi}} .gitolite.rc
|
||||
fi
|
||||
|
||||
# copy the rc across
|
||||
scp -P $port .gitolite.rc $user@$host:
|
||||
|
||||
prompt "ignore any 'please edit this file' or 'run this command' type
|
||||
lines in the next set of command outputs coming up. They're only relevant
|
||||
for a manual install, not this one..."
|
||||
|
||||
# extract the GL_ADMINDIR and REPO_BASE locations
|
||||
GL_ADMINDIR=$(ssh -p $port $user@$host "perl -e 'do \".gitolite.rc\"; print \$GL_ADMINDIR'")
|
||||
REPO_BASE=$( ssh -p $port $user@$host "perl -e 'do \".gitolite.rc\"; print \$REPO_BASE'")
|
||||
|
||||
# MANUAL: still in the "gitolite-install" directory? Good. Run
|
||||
# "src/install.pl"
|
||||
|
||||
ssh -p $port $user@$host "cd gitolite-install; src/install.pl"
|
||||
|
||||
# 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
|
||||
|
||||
repo gitolite-admin
|
||||
RW+ = $admin_name
|
||||
|
||||
repo testing
|
||||
RW+ = @all
|
||||
|
||||
" > gitolite.conf
|
||||
|
||||
# send the config and the key to the remote
|
||||
scp -P $port gitolite.conf $user@$host:$GL_ADMINDIR/conf/
|
||||
|
||||
scp -P $port $HOME/.ssh/$admin_name.pub $user@$host:$GL_ADMINDIR/keydir
|
||||
|
||||
# MANUAL: cd to $GL_ADMINDIR and run "src/gl-compile-conf"
|
||||
|
||||
ssh -p $port $user@$host "cd $GL_ADMINDIR; src/gl-compile-conf"
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# hey lets go the whole hog on this; setup push-to-admin!
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
# 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 --allow-empty
|
||||
" | ssh -p $port $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 -p $port $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 ------------------------------------------------------------------------
|
||||
echo "Cool -- we're done. Now you can edit the config file (currently
|
||||
in ~/gitolite-admin/conf/gitolite.conf) to add more repos, users, etc.
|
||||
When done, 'git add' the changed files, 'git commit' and 'git push'.
|
||||
|
||||
Read the comments in conf/example.conf for information about the config
|
||||
file format -- like the rc file, this also has inline documentation.
|
||||
|
||||
Your URL for cloning any repo on this server will be
|
||||
|
||||
gitolite:reponame.git
|
||||
|
||||
However, any other users you set up will have to use
|
||||
|
||||
$user@$host:reponame.git
|
||||
|
||||
unless they also create similar settings in their '.ssh/config' file."
|
|
@ -24,13 +24,16 @@ use warnings;
|
|||
# ----------------------------------------------------------------------------
|
||||
|
||||
|
||||
our ($GL_LOGT, $GL_CONF_COMPILED, $REPO_BASE);
|
||||
our ($GL_LOGT, $GL_CONF_COMPILED, $REPO_BASE, $GIT_PATH);
|
||||
our %repos;
|
||||
|
||||
my $glrc = $ENV{HOME} . "/.gitolite.rc";
|
||||
die "parse $glrc failed: " . ($! or $@) unless do $glrc;
|
||||
die "parse $GL_CONF_COMPILED failed: " . ($! or $@) unless do $GL_CONF_COMPILED;
|
||||
|
||||
# add a custom path for git binaries, if specified
|
||||
$ENV{PATH} .= ":$GIT_PATH" if $GIT_PATH;
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# definitions specific to this program
|
||||
# ----------------------------------------------------------------------------
|
||||
|
|
|
@ -47,7 +47,7 @@ $Data::Dumper::Indent = 1;
|
|||
# common definitions
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
our ($GL_ADMINDIR, $GL_CONF, $GL_KEYDIR, $GL_CONF_COMPILED, $REPO_BASE, $REPO_UMASK, $PROJECTS_LIST);
|
||||
our ($GL_ADMINDIR, $GL_CONF, $GL_KEYDIR, $GL_CONF_COMPILED, $REPO_BASE, $REPO_UMASK, $PROJECTS_LIST, $GIT_PATH);
|
||||
|
||||
# now that this thing *may* be run via "push to admin", any errors have to
|
||||
# grab the admin's ATTENTION so he won't miss them among the other messages a
|
||||
|
@ -57,6 +57,9 @@ my $ATTN = "\n\t\t***** ERROR *****\n ";
|
|||
my $glrc = $ENV{HOME} . "/.gitolite.rc";
|
||||
die "$ATTN parse $glrc failed: " . ($! or $@) unless do $glrc;
|
||||
|
||||
# add a custom path for git binaries, if specified
|
||||
$ENV{PATH} .= ":$GIT_PATH" if $GIT_PATH;
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# definitions specific to this program
|
||||
# ----------------------------------------------------------------------------
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
use strict;
|
||||
use warnings;
|
||||
|
||||
our ($REPO_BASE, $GL_ADMINDIR, $GL_CONF);
|
||||
our ($REPO_BASE, $GL_ADMINDIR, $GL_CONF, $GIT_PATH);
|
||||
|
||||
# wrapper around mkdir; it's not an error if the directory exists, but it is
|
||||
# an error if it doesn't exist and we can't create it
|
||||
|
@ -33,6 +33,9 @@ unless (-f $glrc) {
|
|||
# ok now $glrc exists; read it to get the other paths
|
||||
die "parse $glrc failed: " . ($! or $@) unless do $glrc;
|
||||
|
||||
# add a custom path for git binaries, if specified
|
||||
$ENV{PATH} .= ":$GIT_PATH" if $GIT_PATH;
|
||||
|
||||
# mkdir $REPO_BASE, $GL_ADMINDIR if they don't already exist
|
||||
my $repo_base_abs = ( $REPO_BASE =~ m(^/) ? $REPO_BASE : "$ENV{HOME}/$REPO_BASE" );
|
||||
wrap_mkdir($repo_base_abs);
|
||||
|
@ -66,7 +69,10 @@ for my $repo (`find . -type d -name "*.git"`) {
|
|||
}
|
||||
|
||||
# oh and one of those repos is a bit more special and has an extra hook :)
|
||||
system("cp $GL_ADMINDIR/src/pta-hook.sh gitolite-admin.git/hooks/post-update");
|
||||
system("perl", "-i", "-p", "-e", "s(export GL_ADMINDIR=.*)(export GL_ADMINDIR=$GL_ADMINDIR)",
|
||||
if ( -d "gitolite-admin.git/hooks" ) {
|
||||
print STDERR "copying post-update hook to gitolite-admin repo...\n";
|
||||
system("cp -v $GL_ADMINDIR/src/pta-hook.sh gitolite-admin.git/hooks/post-update");
|
||||
system("perl", "-i", "-p", "-e", "s(export GL_ADMINDIR=.*)(export GL_ADMINDIR=$GL_ADMINDIR)",
|
||||
"gitolite-admin.git/hooks/post-update");
|
||||
chmod 0755, "gitolite-admin.git/hooks/post-update";
|
||||
chmod 0755, "gitolite-admin.git/hooks/post-update";
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue