From 9d2c9662a21044576d7ef4361d8bc22bc85deea9 Mon Sep 17 00:00:00 2001 From: Sitaram Chamarty Date: Sat, 10 Oct 2009 12:52:40 +0530 Subject: [PATCH 01/14] install: can't assume p-t-a is setup! make installing the p-u hook conditional to avoid ugly error --- src/install.pl | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/install.pl b/src/install.pl index 017854f..3e1f655 100755 --- a/src/install.pl +++ b/src/install.pl @@ -66,7 +66,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)", - "gitolite-admin.git/hooks/post-update"); -chmod 0755, "gitolite-admin.git/hooks/post-update"; +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"; +} From ccd8372bb30641cb63efbd5d2db495af92bcf266 Mon Sep 17 00:00:00 2001 From: Sitaram Chamarty Date: Sat, 10 Oct 2009 12:38:22 +0530 Subject: [PATCH 02/14] aa ha! easy install script! src/00-easy-install.sh does *everything* needed, and it's mostly self-documented --- README.mkd | 4 + doc/0-INSTALL.mkd | 52 ++++++++- src/00-easy-install.sh | 245 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 298 insertions(+), 3 deletions(-) create mode 100755 src/00-easy-install.sh diff --git a/README.mkd b/README.mkd index 5a59bd1..fe85675 100644 --- a/README.mkd +++ b/README.mkd @@ -3,6 +3,10 @@ > [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 diff --git a/doc/0-INSTALL.mkd b/doc/0-INSTALL.mkd index c54c7eb..d4f3b44 100644 --- a/doc/0-INSTALL.mkd +++ b/doc/0-INSTALL.mkd @@ -1,6 +1,52 @@ # installing gitolite -### pre-requisites +### 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 +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. 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... :) + +### 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. + +#### pre-requisites on the server If you managed to install git, you might already have what gitolite needs: @@ -13,7 +59,7 @@ 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 +#### 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 @@ -24,7 +70,7 @@ tar file of the branch you want. Please use the make command, not a plain make master.tar # or maybe "make rebel.tar" or "make pu.tar" -### quick install from tar file +#### 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 diff --git a/src/00-easy-install.sh b/src/00-easy-install.sh new file mode 100755 index 0000000..54cb5a0 --- /dev/null +++ b/src/00-easy-install.sh @@ -0,0 +1,245 @@ +#!/bin/bash + +# easy install for gitolite + +# this is the client side piece. This gets run *before* the server side piece + +# 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 "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 </dev/null || + die "cant find at least some files in gitolite sources/config; aborting" + +# do we have pubkey auth on the server +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 +[[ -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) + +[[ -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 + + 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." + +ssh-keygen -t rsa -f $HOME/.ssh/$admin_name || die "ssh-keygen failed for some reason..." + +if [[ -n $SSH_AGENT_PID ]] +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 + +# ok the gitolite key is done; create a stanza for it in ~/.ssh/config +echo " +host gitolite + hostname $host + user $user + 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), 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 +# ---------------------------------------------------------------------- + +# setup the gitolite sources and conf on the server +ssh $user@$host mkdir -p gitolite-install +rsync -a src conf doc $user@$host:gitolite-install/ + +# give the user an opportunity to change the rc +cp conf/example.gitolite.rc .gitolite.rc + # hey here it means "release candidate" ;-) + +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!" + +${VISUAL:-${EDITOR:-vi}} .gitolite.rc + +# copy the rc across +scp .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 $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 +ssh $user@$host "cd gitolite-install; src/install.pl" + +# setup the initial config file +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 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 +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 +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 + +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." + +cd $HOME +git clone gitolite:gitolite-admin.git + +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." From d0d9cbe3afebc490f230fb6fa9ea0420eb1fcd1a Mon Sep 17 00:00:00 2001 From: Sitaram Chamarty Date: Sun, 11 Oct 2009 05:51:19 +0530 Subject: [PATCH 03/14] easy install comment about clientside/serverside was wrong --- src/00-easy-install.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/00-easy-install.sh b/src/00-easy-install.sh index 54cb5a0..d19c1a5 100755 --- a/src/00-easy-install.sh +++ b/src/00-easy-install.sh @@ -2,7 +2,8 @@ # easy install for gitolite -# this is the client side piece. This gets run *before* the server side piece +# this runs on the client side, and itself takes care of all the server side +# work. You don't have to do anything on the server side directly # run without any arguments for "usage" info From d78bbe8c3eecc9b3592c1b1387b784571286e5f1 Mon Sep 17 00:00:00 2001 From: Sitaram Chamarty Date: Sun, 11 Oct 2009 08:31:59 +0530 Subject: [PATCH 04/14] 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 --- README.mkd | 104 ++++++++++++------------------- conf/example.gitolite.rc | 2 +- doc/0-INSTALL.mkd | 127 +++++++++----------------------------- doc/0-UPGRADE.mkd | 40 ++++++++++-- doc/1-migrate.mkd | 63 ++++++++----------- doc/2-admin.mkd | 55 +++-------------- doc/3-faq-tips-etc.mkd | 130 +++++++++++++++++++++++---------------- doc/4-push-to-admin.mkd | 5 ++ src/00-easy-install.sh | 99 +++++++++++++++++++++++++---- 9 files changed, 309 insertions(+), 316 deletions(-) diff --git a/README.mkd b/README.mkd index fe85675..7cbbaf3 100644 --- a/README.mkd +++ b/README.mkd @@ -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 diff --git a/conf/example.gitolite.rc b/conf/example.gitolite.rc index ea80bec..700fc0e 100644 --- a/conf/example.gitolite.rc +++ b/conf/example.gitolite.rc @@ -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 :-) # -------------------------------------- diff --git a/doc/0-INSTALL.mkd b/doc/0-INSTALL.mkd index d4f3b44..5ef38cf 100644 --- a/doc/0-INSTALL.mkd +++ b/doc/0-INSTALL.mkd @@ -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. diff --git a/doc/0-UPGRADE.mkd b/doc/0-UPGRADE.mkd index c106bc7..5e242f6 100644 --- a/doc/0-UPGRADE.mkd +++ b/doc/0-UPGRADE.mkd @@ -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 diff --git a/doc/1-migrate.mkd b/doc/1-migrate.mkd index fe0b4cf..fb0491f 100644 --- a/doc/1-migrate.mkd +++ b/doc/1-migrate.mkd @@ -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 diff --git a/doc/2-admin.mkd b/doc/2-admin.mkd index 8cd2216..133455a 100644 --- a/doc/2-admin.mkd +++ b/doc/2-admin.mkd @@ -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. diff --git a/doc/3-faq-tips-etc.mkd b/doc/3-faq-tips-etc.mkd index 66ab956..f24d30c 100644 --- a/doc/3-faq-tips-etc.mkd +++ b/doc/3-faq-tips-etc.mkd @@ -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//*`), 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. + diff --git a/doc/4-push-to-admin.mkd b/doc/4-push-to-admin.mkd index 48d1baa..8791480 100644 --- a/doc/4-push-to-admin.mkd +++ b/doc/4-push-to-admin.mkd @@ -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` diff --git a/src/00-easy-install.sh b/src/00-easy-install.sh index d19c1a5..2ca8bf1 100755 --- a/src/00-easy-install.sh +++ b/src/00-easy-install.sh @@ -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 ------------------------------------------------------------------------ From 0b81bfd6ec798adcd889d41087bdd1822f0f68d4 Mon Sep 17 00:00:00 2001 From: Sitaram Chamarty Date: Sun, 11 Oct 2009 14:08:14 +0530 Subject: [PATCH 05/14] easy install: allow ports other than 22 for ssh to server --- src/00-easy-install.sh | 55 ++++++++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 23 deletions(-) diff --git a/src/00-easy-install.sh b/src/00-easy-install.sh index 2ca8bf1..43e84a8 100755 --- a/src/00-easy-install.sh +++ b/src/00-easy-install.sh @@ -26,9 +26,10 @@ prompt() { } usage() { cat </dev/null || +ssh -p $port -o PasswordAuthentication=no $user@$host pwd >/dev/null || 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 @@ -152,14 +159,16 @@ fi # The lines to be included look like this: # host gitolite -# hostname server # user git +# hostname server +# port 22 # identityfile ~/.ssh/sitaram echo " host gitolite - hostname $host user $user + hostname $host + port $port identityfile ~/.ssh/$admin_name" > $HOME/.ssh/.gl-stanza if grep 'host *gitolite' $HOME/.ssh/config &>/dev/null @@ -191,8 +200,8 @@ rm $HOME/.ssh/.gl-stanza # 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/ +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 @@ -219,20 +228,20 @@ that all the paths etc. represent paths on the server!" ${VISUAL:-${EDITOR:-vi}} .gitolite.rc # copy the rc across -scp .gitolite.rc $user@$host: +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 $user@$host "perl -e 'do \".gitolite.rc\"; print \$GL_ADMINDIR'") -REPO_BASE=$( ssh $user@$host "perl -e 'do \".gitolite.rc\"; print \$REPO_BASE'") +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 $user@$host "cd gitolite-install; 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: @@ -252,13 +261,13 @@ repo testing " > gitolite.conf # send the config and the key to the remote -scp gitolite.conf $user@$host:$GL_ADMINDIR/conf/ +scp -P $port gitolite.conf $user@$host:$GL_ADMINDIR/conf/ -scp $HOME/.ssh/$admin_name.pub $user@$host:$GL_ADMINDIR/keydir +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 $user@$host "cd $GL_ADMINDIR; 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! @@ -278,13 +287,13 @@ ssh $user@$host "cd $GL_ADMINDIR; src/gl-compile-conf" 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 +" | 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 $user@$host "cd gitolite-install; 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, From 48e18e1d2d67baaa8169d6a4c29de923ea47e863 Mon Sep 17 00:00:00 2001 From: Sitaram Chamarty Date: Mon, 12 Oct 2009 09:53:30 +0530 Subject: [PATCH 06/14] easy install: some minor fixes - fix typo in introduction - detect if you're not running strictly as src/00-easy-install.sh --- src/00-easy-install.sh | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/src/00-easy-install.sh b/src/00-easy-install.sh index 43e84a8..7f21179 100755 --- a/src/00-easy-install.sh +++ b/src/00-easy-install.sh @@ -15,7 +15,7 @@ # command!) set -e -die() { echo "$@"; echo "run $0 again without any arguments for help and tips"; exit 1; } +die() { echo "$@"; echo; echo "run $0 again without any arguments for help and tips"; exit 1; } prompt() { echo echo @@ -47,7 +47,7 @@ Notes: Pre-requisites: - you must run this from the gitolite working tree top level directory. - This means you run this as "src/00-easy-install-clientside.sh" + 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 @@ -62,6 +62,23 @@ 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 @@ -78,13 +95,6 @@ port=22 [[ "$user" =~ [^a-zA-Z0-9._-] ]] && die "user '$user' invalid" [[ "$admin_name" =~ [^a-zA-Z0-9._-] ]] && die "admin_name '$admin_name' 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 - -# ---------------------------------------------------------------------- -# basic sanity checks -# ---------------------------------------------------------------------- - # MANUAL: make sure you're in the gitolite directory, at the top level. # The following files should all be visible: From 9e46920fe3544e6edb785595c3248e8d01f6ea5a Mon Sep 17 00:00:00 2001 From: Sitaram Chamarty Date: Mon, 12 Oct 2009 20:02:38 +0530 Subject: [PATCH 07/14] faq: explain one user many keys a bit better --- doc/3-faq-tips-etc.mkd | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/3-faq-tips-etc.mkd b/doc/3-faq-tips-etc.mkd index f24d30c..366c066 100644 --- a/doc/3-faq-tips-etc.mkd +++ b/doc/3-faq-tips-etc.mkd @@ -263,6 +263,11 @@ 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. From fc36050972ce406e28024709e2deb98d32296675 Mon Sep 17 00:00:00 2001 From: Sitaram Chamarty Date: Mon, 12 Oct 2009 20:39:34 +0530 Subject: [PATCH 08/14] easy install: one step toward idempotency... --- src/00-easy-install.sh | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/src/00-easy-install.sh b/src/00-easy-install.sh index 7f21179..aca409f 100755 --- a/src/00-easy-install.sh +++ b/src/00-easy-install.sh @@ -124,7 +124,6 @@ ssh -p $port -o PasswordAuthentication=no $user@$host pwd >/dev/null || # 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 The pubkey will be $HOME/.ssh/$admin_name.pub. You will have to @@ -141,7 +140,13 @@ prompt "the next command will create a new keypair for your gitolite access This makes using passphrases very convenient." -ssh-keygen -t rsa -f $HOME/.ssh/$admin_name || die "ssh-keygen failed for some reason..." +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 @@ -185,7 +190,7 @@ 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), and rerun. + 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: @@ -222,10 +227,6 @@ rsync -e "ssh -p $port" -a src conf doc $user@$host:gitolite-install/ # 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" ;-) - 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. @@ -235,6 +236,15 @@ 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. I'll use + that instead of the default one..." +else + cp conf/example.gitolite.rc .gitolite.rc +fi + ${VISUAL:-${EDITOR:-vi}} .gitolite.rc # copy the rc across @@ -296,7 +306,7 @@ ssh -p $port $user@$host "cd $GL_ADMINDIR; src/gl-compile-conf" 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 +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 From e0e9d389203730a0693fee9ff91b99bcec366982 Mon Sep 17 00:00:00 2001 From: Sitaram Chamarty Date: Mon, 12 Oct 2009 21:21:29 +0530 Subject: [PATCH 09/14] easy install: minor formatting stuff --- src/00-easy-install.sh | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/00-easy-install.sh b/src/00-easy-install.sh index aca409f..ee5d943 100755 --- a/src/00-easy-install.sh +++ b/src/00-easy-install.sh @@ -20,7 +20,7 @@ prompt() { echo echo echo ------------------------------------------------------------------------ - echo "$1" + echo " $1" echo read -p '...press enter to continue or Ctrl-C to bail out' } @@ -228,13 +228,13 @@ rsync -e "ssh -p $port" -a src conf doc $user@$host:gitolite-install/ # 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. + 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. + 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!" + 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 . @@ -251,8 +251,8 @@ ${VISUAL:-${EDITOR:-vi}} .gitolite.rc 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..." + 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'") @@ -316,8 +316,8 @@ GIT_WORK_TREE=$GL_ADMINDIR git commit -am start --allow-empty 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." + 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"! From d125488107485d274c522946291e1cb3a9e6e05f Mon Sep 17 00:00:00 2001 From: Sitaram Chamarty Date: Tue, 13 Oct 2009 10:02:58 +0530 Subject: [PATCH 10/14] doc/3 minor re-arrangement --- doc/3-faq-tips-etc.mkd | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/doc/3-faq-tips-etc.mkd b/doc/3-faq-tips-etc.mkd index 366c066..917590a 100644 --- a/doc/3-faq-tips-etc.mkd +++ b/doc/3-faq-tips-etc.mkd @@ -348,6 +348,26 @@ 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" @@ -398,23 +418,4 @@ 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. From 55ccb8291b36e7a03e3856d4c4c686815268c039 Mon Sep 17 00:00:00 2001 From: Sitaram Chamarty Date: Tue, 13 Oct 2009 08:44:59 +0530 Subject: [PATCH 11/14] easy install: change ssh-agent detection use ssh-add -l instead of $SSH_AGENT_PID to decide if agent is running --- src/00-easy-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/00-easy-install.sh b/src/00-easy-install.sh index ee5d943..fa148c7 100755 --- a/src/00-easy-install.sh +++ b/src/00-easy-install.sh @@ -157,7 +157,7 @@ fi # 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 ]] +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 From 030b3f29ef2f8f44d3a402e91315bc48c3461cb4 Mon Sep 17 00:00:00 2001 From: Sitaram Chamarty Date: Tue, 13 Oct 2009 09:55:58 +0530 Subject: [PATCH 12/14] easy install: minor improvement in detection of password-less auth --- src/00-easy-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/00-easy-install.sh b/src/00-easy-install.sh index fa148c7..c6201f1 100755 --- a/src/00-easy-install.sh +++ b/src/00-easy-install.sh @@ -110,7 +110,7 @@ ls src/gl-auth-command \ # is, running "ssh git@server" should log in straight away, without asking for # a password -ssh -p $port -o PasswordAuthentication=no $user@$host pwd >/dev/null || +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 From 59e15e62a1e95cb635f35991d9884aa7ef9db08d Mon Sep 17 00:00:00 2001 From: Sitaram Chamarty Date: Tue, 13 Oct 2009 10:02:45 +0530 Subject: [PATCH 13/14] support git installed outside default $PATH (also some minor fixes to doc/3) --- conf/example.gitolite.rc | 10 ++++++++++ doc/3-faq-tips-etc.mkd | 26 ++++++++++++++++++++++++-- src/00-easy-install.sh | 22 ++++++++++++++++++---- src/gl-auth-command | 5 ++++- src/gl-compile-conf | 5 ++++- src/install.pl | 5 ++++- 6 files changed, 64 insertions(+), 9 deletions(-) diff --git a/conf/example.gitolite.rc b/conf/example.gitolite.rc index 700fc0e..78df455 100644 --- a/conf/example.gitolite.rc +++ b/conf/example.gitolite.rc @@ -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; diff --git a/doc/3-faq-tips-etc.mkd b/doc/3-faq-tips-etc.mkd index 917590a..cda6ab0 100644 --- a/doc/3-faq-tips-etc.mkd +++ b/doc/3-faq-tips-etc.mkd @@ -14,6 +14,7 @@ In this document: * easier to specify gitweb/daemon access * better logging * one user, many keys + * support for git installed outside default PATH * who am I? * other cool things * "personal" branches @@ -226,7 +227,7 @@ bits and pieces. Here's an example, using short repo names for convenience: repo r2 # ...and so on... -### better logging +#### better logging 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 @@ -271,6 +272,27 @@ 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..receivepack` and `remote..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 @@ -292,7 +314,7 @@ In gitolite, it's simple: just ask nicely :-) ### other cool things -### "personal" branches +#### "personal" branches "personal" branches are great for corporate environments, where unauthenticated pull/clone is a no-no. Since a dev workstation cannot do diff --git a/src/00-easy-install.sh b/src/00-easy-install.sh index c6201f1..a9f5ecf 100755 --- a/src/00-easy-install.sh +++ b/src/00-easy-install.sh @@ -239,14 +239,28 @@ prompt "the gitolite rc file needs to be edited by hand. The defaults # 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. I'll use - that instead of the default one..." + 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 + 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 + else + ${VISUAL:-${EDITOR:-vi}} .gitolite.rc + fi else cp conf/example.gitolite.rc .gitolite.rc + ${VISUAL:-${EDITOR:-vi}} .gitolite.rc fi -${VISUAL:-${EDITOR:-vi}} .gitolite.rc - # copy the rc across scp -P $port .gitolite.rc $user@$host: diff --git a/src/gl-auth-command b/src/gl-auth-command index 62573d4..8201403 100755 --- a/src/gl-auth-command +++ b/src/gl-auth-command @@ -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 # ---------------------------------------------------------------------------- diff --git a/src/gl-compile-conf b/src/gl-compile-conf index ad50c4a..f51f97a 100755 --- a/src/gl-compile-conf +++ b/src/gl-compile-conf @@ -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 # ---------------------------------------------------------------------------- diff --git a/src/install.pl b/src/install.pl index 3e1f655..f6e4142 100755 --- a/src/install.pl +++ b/src/install.pl @@ -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); From b3cab456d5882aa3f88af4fa33d756a7c4bdb547 Mon Sep 17 00:00:00 2001 From: Sitaram Chamarty Date: Tue, 13 Oct 2009 10:16:23 +0530 Subject: [PATCH 14/14] easy-install: committed before testing? tsk tsk tsk! --- conf/example.gitolite.rc | 4 ++-- src/00-easy-install.sh | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/conf/example.gitolite.rc b/conf/example.gitolite.rc index 78df455..b3b3361 100644 --- a/conf/example.gitolite.rc +++ b/conf/example.gitolite.rc @@ -95,8 +95,8 @@ $PERSONAL=""; # works), leave this setting as is. Otherwise, choose one of the # alternatives, or write your own -$GIT_PATH="" -# $GIT_PATH="/opt/bin/" +$GIT_PATH=""; +# $GIT_PATH="/opt/bin/"; # -------------------------------------- # per perl rules, this should be the last line in such a file: diff --git a/src/00-easy-install.sh b/src/00-easy-install.sh index a9f5ecf..a9d8700 100755 --- a/src/00-easy-install.sh +++ b/src/00-easy-install.sh @@ -245,6 +245,8 @@ then 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 @@ -253,8 +255,6 @@ then [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 - else - ${VISUAL:-${EDITOR:-vi}} .gitolite.rc fi else cp conf/example.gitolite.rc .gitolite.rc