diff --git a/Makefile b/Makefile index 730fa72..7780900 100644 --- a/Makefile +++ b/Makefile @@ -7,10 +7,10 @@ # Note: I'm not sure if that "-r" is a GNU tar extension... .GITOLITE-VERSION: - @touch .GITOLITE-VERSION + @touch conf/VERSION %.tar: .GITOLITE-VERSION - git describe --all --long $* > .GITOLITE-VERSION + git describe --tags --long $* > conf/VERSION git archive $* > $@ - tar -r -f $@ .GITOLITE-VERSION - rm .GITOLITE-VERSION + tar -r -f $@ conf/VERSION + rm conf/VERSION diff --git a/doc/0-INSTALL.mkd b/doc/0-INSTALL.mkd index 88ba053..bb22bb6 100644 --- a/doc/0-INSTALL.mkd +++ b/doc/0-INSTALL.mkd @@ -2,31 +2,58 @@ [Update 2009-11-18: easy install now works from msysgit also!] +Gitolite is somewhat unusual as far as "server" software goes -- every userid +on the system is a potential "gitolite host" and can install his own version +if he chooses to. + This document tells you how to install gitolite. After the install is done, you may want to see the [admin document][admin] for adding users, repos, etc. [admin]: http://github.com/sitaramc/gitolite/blob/pu/doc/2-admin.mkd -There's an easy install script that requires bash (**strongly** recommended), -but if you have no bash or you're on one of the legacy Unixes there's a -slightly more manual process. Both are explained here. - In this document: - * easy install + * install methods + * user install * typical example run * advantages over the older install methods * disadvantages - * manual install - * upgrades - * other notes + * upgrades + * other notes + * system install / user setup * next steps - * appendix A: server and client requirements + * appendix A: server and client requirements for user install + * server + * install workstation + * admin workstation(s) * appendix B: uninstalling gitolite + * appendix C: NOTE TO PACKAGE MAINTAINERS ---- -### easy install +### install methods + +There are 2 ways to install gitolite: The **user-install** mode was the +traditional way, and is used when *any* of the following is true: + + * you don't have root on your "server" (some types of hosting setups, many + corporate paranoia setups ;-) + * your server distro does not have gitolite in its package repositories + * your server distro's package repositories have an old version of gitolite + * you want to stay current with the latest gitolite versions + * your server is not Linux (maybe AIX, or Solaris, etc.) + +The "user install" section describes this method. + +The **system-install followed by user-setup** mode is used when you (or +someone who has root) has installed an RPM or DEB of gitolite and you intend +to use that version. + +The "system install / user setup" section describes this method. + +---- + +### user install There is an easy install script that makes installing very easy for the common case. **This script will setup everything on the server, but you have to run @@ -44,6 +71,7 @@ Assumptions/pre-requisites: `ssh-copy-id` in that file for instructions * you have a clone or an archive of gitolite somewhere on your workstation * if you don't have one, just run `git clone git://github.com/sitaramc/gitolite` + * your workstation has bash (even msysgit bash will do) Once you have all this, just `cd` to that clone and run `src/gl-easy-install` and follow the prompts! (Running it without any arguments shows you usage @@ -76,13 +104,7 @@ actually doing, I suggest you skip the `-q`. * need a recent bash -### manual install - -If you don't have bash, it's not very complicated to do it manually. Just -open the file `src/gl-easy-install` in a nice, syntax coloring, text -editor, and follow the instructions marked "MANUAL" :-) - -### upgrades +#### upgrades Upgrading gitolite is easy. @@ -98,7 +120,7 @@ way. I decided that it is not possible to **safely** let an upgrade do something meaningful with them -- fiddling with existing config files (as opposed to merely creating one which did not exist) is best left to a human. -### other notes +#### other notes * if you run `src/gl-easy-install` without the `-q` option, you will be given a chance to edit `~/.gitolite.rc`. You can change any options (such @@ -106,6 +128,36 @@ opposed to merely creating one which did not exist) is best left to a human. *don't* have to know perl to do so, it's fairly easy to guess in this limited case. +### system install / user setup + +In this mode a system administrator installs gitolite using the server's +distro package mechanism (yum install, apt-get install, etc). + +Once this is done, you as a user must run a command like this (unlike in the +"user install" mode, this is done directly on the server): + + gl-setup yourname.pub + +where yourname.pub is a copy of a public key from your workstation. The first +time you run this, it will create a "gitolite-admin" repo and populate it with +the right configuration for whoever has the corresponding private key to +clone and push it. In other words, that person is the administrator for this +particular gitolite instance. + +If your system administrator upgrades gitolite itself, things will usually +just work without any change; you should not have to do anything special. +However, some new features may require additional settings in your +`~/.gitolite.rc` file. + +Finally, in the rare case that you managed to lose your keys to the admin repo +and want to supply a new pubkey, you can use this command to replace any such +key. Could be useful in an emergency -- just get your new "yourname.pub" to +the server and run the same command as above. + +**IMPORTANT**: there are two variables in the `~/.gitolite.rc` file: +`$GL_PACKAGE_CONF` and `$GL_PACKAGE_HOOKS`. If you remove or change either of +them, expect trouble :-) + ### next steps The last message produced by the easy install script should tell you how to @@ -114,7 +166,7 @@ document. -### appendix A: server and client requirements +### appendix A: server and client requirements for user install There are 3 machines *potentially* involved in installing and administering gitolite. @@ -171,7 +223,7 @@ allow you to push to the gitolite-admin repo. -### uninstalling gitolite +### appendix B: uninstalling gitolite Sometimes you might find gitolite is overkill -- you have only one user (yourself) pushing maybe. Or maybe gitolite is just not enough -- you want a @@ -217,3 +269,43 @@ following (assuming `$REPO_BASE` in the rc file was left at its default of before the actual path used, in order for the remote to still work. This is because you'll now be accessing it through plain ssh, which means you have to give it the full path. + +### appendix C: NOTE TO PACKAGE MAINTAINERS + +Here's how you'd package gitolite. In the following description, location "X" +can be, say, `/usr/share/gitolite/conf` or some such, and similarly location +"Y" can be perhaps `/usr/share/gitolite/hooks`. It's upto your distro +policies where they are. + +These are the content changes needed (no trailing slashes in the location +values please): + + * `gl-setup` should have the following line: + + GL_PACKAGE_CONF="X" + + * `example.gitolite.rc` should have the following lines: + + $GL_PACKAGE_CONF="X"; + $GL_PACKAGE_HOOKS="Y"; + +This is where the files should be installed: + + * everything in "src" goes somewhere on the PATH + * everything in "conf" goes to location "X" + * everything in "hooks" goes to location "Y" + +You might also want to delete the `gl-easy-install` script, since that is +meant for a totally different mode of installation and probably would *not* +work if a user tried to run it :-) + +On the initial install, you could also choose to setup a userid called +"gitolite", and run "gl-setup" as that user; however I do not know how you +would come up with the initial pubkey that is needed. Anyway, the point is +that the "gitolite" user is no more special than any other in terms of hosting +gitolite. Any user can host it by just running "gl-setup". + +When you upgrade, just overwrite all the files; it'll all just work. In fact, +other than the initial "gl-setup" run, the only time a gitolite hosting user +has to actually do anything is to edit their own `~/.gitolite.rc` file if they +want to enable or disable specific features. diff --git a/src/hooks/update b/hooks/common/update similarity index 100% rename from src/hooks/update rename to hooks/common/update diff --git a/src/ga-post-update-hook b/hooks/gitolite-admin/post-update similarity index 100% rename from src/ga-post-update-hook rename to hooks/gitolite-admin/post-update diff --git a/src/gitolite.pm b/src/gitolite.pm index b87e45b..46d537c 100644 --- a/src/gitolite.pm +++ b/src/gitolite.pm @@ -34,7 +34,7 @@ our $USERNAME_PATT=qr(^\@?[0-9a-zA-Z][0-9a-zA-Z._\@+-]*$); # very simple patter our $REPOPATT_PATT=qr(^\@?[0-9a-zA-Z][\\^.$|()[\]*+?{}0-9a-zA-Z._\@/-]*$); # these come from the RC file -our ($REPO_UMASK, $GL_WILDREPOS); +our ($REPO_UMASK, $GL_WILDREPOS, $GL_PACKAGE_CONF, $GL_PACKAGE_HOOKS); our %repos; # ---------------------------------------------------------------------------- @@ -148,6 +148,9 @@ sub new_repo } # propagate our own, plus any local admin-defined, hooks ln_sf($hooks_dir, "*", "hooks"); + # in case of package install, GL_ADMINDIR is no longer the top cop; + # override with the package hooks + ln_sf("$GL_PACKAGE_HOOKS/common", "*", "hooks") if $GL_PACKAGE_HOOKS; chmod 0755, "hooks/update"; } @@ -282,7 +285,7 @@ sub report_basic # send back some useful info if no command was given print "hello $user, the gitolite version here is "; - system("cat", "$GL_ADMINDIR/src/VERSION"); + system("cat", ($GL_PACKAGE_CONF || "$GL_ADMINDIR/conf") . "/VERSION"); print "\ryou have the following permissions:\n\r"; for my $r (sort keys %repos) { my $perm .= ( $repos{$r}{C}{'@all'} ? ' @' : ( $repos{$r}{C}{$user} ? ' C' : ' ' ) ); diff --git a/src/gl-auth-command b/src/gl-auth-command index db16113..443bd8f 100755 --- a/src/gl-auth-command +++ b/src/gl-auth-command @@ -32,6 +32,7 @@ our %repos; # the common setup module is in the same directory as this running program is my $bindir = $0; $bindir =~ s/\/[^\/]+$//; +$bindir = "$ENV{PWD}/$bindir" unless $bindir =~ /^\//; require "$bindir/gitolite.pm"; # ask where the rc file is, get it, and "do" it @@ -177,7 +178,7 @@ if ( -d "$repo_base_abs/$repo.git" ) { # auto-vivify new repo if you have C access (and wildrepos is on) if ( $GL_WILDREPOS and $repos{$repo}{C}{$user} || $repos{$repo}{C}{'@all'} ) { wrap_chdir("$repo_base_abs"); - new_repo($repo, "$GL_ADMINDIR/src/hooks", $user); + new_repo($repo, "$GL_ADMINDIR/hooks/common", $user); wrap_chdir($ENV{HOME}); } } diff --git a/src/gl-compile-conf b/src/gl-compile-conf index 842a30a..bd2780f 100755 --- a/src/gl-compile-conf +++ b/src/gl-compile-conf @@ -68,6 +68,7 @@ our ($REPONAME_PATT, $REPOPATT_PATT, $USERNAME_PATT, $AUTH_COMMAND, $AUTH_OPTION # the common setup module is in the same directory as this running program is my $bindir = $0; $bindir =~ s/\/[^\/]+$//; +$bindir = "$ENV{PWD}/$bindir" unless $bindir =~ /^\//; require "$bindir/gitolite.pm"; # ask where the rc file is, get it, and "do" it @@ -395,7 +396,7 @@ for my $repo (sort keys %repos) { next if $repo =~ m(^EXTCMD/); # these are not real repos unless (-d "$repo.git") { print STDERR "creating $repo...\n"; - new_repo($repo, "$GL_ADMINDIR/src/hooks"); + new_repo($repo, "$GL_ADMINDIR/hooks/common"); # new_repo would have chdir'd us away; come back wrap_chdir("$repo_base_abs"); } diff --git a/src/gl-easy-install b/src/gl-easy-install index 35c31e2..989f3a6 100755 --- a/src/gl-easy-install +++ b/src/gl-easy-install @@ -169,12 +169,12 @@ basic_sanity() { # MANUAL: make sure you're in the gitolite directory, at the top level. # The following files should all be visible: - ls src/ga-post-update-hook \ + ls hooks/gitolite-admin/post-update \ + hooks/common/update \ src/gitolite.pm \ src/gl-install \ src/gl-auth-command \ src/gl-compile-conf \ - src/hooks/update \ conf/example.conf \ conf/example.gitolite.rc >/dev/null || die "cant find at least some files in gitolite sources/config; aborting" @@ -196,12 +196,12 @@ version_info() { # MANUAL: if needed, make a note of the version you are upgrading from, and to # record which version is being sent across; we assume it's HEAD - git describe --tags --long HEAD 2>/dev/null > src/VERSION || echo '(unknown)' > src/VERSION + git describe --tags --long HEAD 2>/dev/null > conf/VERSION || echo '(unknown)' > conf/VERSION # what was the old version there? export upgrade_details="you are upgrading \ - $(ssh -p $port $user@$host cat gitolite-install/src/VERSION 2>/dev/null || echo '(or installing first-time)' ) \ - to $(cat src/VERSION)" + $(ssh -p $port $user@$host cat gitolite-install/conf/VERSION 2>/dev/null || echo '(or installing first-time)' ) \ + to $(cat conf/VERSION)" prompt "$upgrade_details" "$v_upgrade_details" } @@ -282,8 +282,7 @@ copy_gl() { # have to create the directory first. ssh -p $port $user@$host mkdir -p gitolite-install - scp $quiet -P $port -r src conf doc $user@$host:gitolite-install/ - rm -f src/VERSION + scp $quiet -P $port -r src conf doc hooks $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 diff --git a/src/gl-install b/src/gl-install index 9159ed5..b163439 100755 --- a/src/gl-install +++ b/src/gl-install @@ -3,7 +3,7 @@ use strict; use warnings; -our ($REPO_BASE, $GL_ADMINDIR, $GL_CONF, $GIT_PATH); +our ($REPO_BASE, $GL_ADMINDIR, $GL_CONF, $GIT_PATH, $GL_PACKAGE_CONF, $GL_PACKAGE_HOOKS); # setup quiet mode if asked; please do not use this when running manually open STDOUT, ">", "/dev/null" if (@ARGV and shift eq '-q'); @@ -31,7 +31,11 @@ require "$bindir/gitolite.pm"; unless ($ENV{GL_RC}) { # doesn't exist. Copy it across, tell user to edit it and come back my $glrc = $ENV{HOME} . "/.gitolite.rc"; - system("cp conf/example.gitolite.rc $glrc"); + if ($GL_PACKAGE_CONF) { + system("cp $GL_PACKAGE_CONF/example.gitolite.rc $glrc"); + } else { + system("cp $bindir/../conf/example.gitolite.rc $glrc"); + } print "created $glrc\n"; print "please edit it, change the paths if you wish to, and RERUN THIS SCRIPT\n"; exit; @@ -48,21 +52,28 @@ my $repo_base_abs = ( $REPO_BASE =~ m(^/) ? $REPO_BASE : "$ENV{HOME}/$REPO_BASE" wrap_mkdir($repo_base_abs); wrap_mkdir($GL_ADMINDIR); # mkdir $GL_ADMINDIR's subdirs -for my $dir qw(conf doc keydir logs src) { +for my $dir qw(conf doc keydir logs src hooks hooks/common hooks/gitolite-admin) { + # some of them will stay empty; too lazy to fix right now ;-) wrap_mkdir("$GL_ADMINDIR/$dir"); } # "src" and "doc" will be overwritten on each install, but not conf -system("cp -R src doc $GL_ADMINDIR"); +if ($GL_PACKAGE_HOOKS) { + system("cp -R $GL_PACKAGE_HOOKS $GL_ADMINDIR"); +} else { + system("cp -R $bindir/../src $bindir/../doc $bindir/../hooks $GL_ADMINDIR"); + system("cp $bindir/../conf/VERSION $GL_ADMINDIR/conf"); +} -unless (-f $GL_CONF) { - system("cp conf/example.conf $GL_CONF"); +unless (-f $GL_CONF or $GL_PACKAGE_CONF) { print < .newvars + perl -ne 's/^\s+//; s/[\s=].*//; print if /^\$/;' < ~/.gitolite.rc | sort > .oldvars + comm -23 .newvars .oldvars > .diffvars + if [[ -s .diffvars ]] + then + cp $GL_PACKAGE_CONF/example.gitolite.rc ~/.gitolite.rc.new + echo new version of the rc file saved in ~/.gitolite.rc.new + echo + echo please update ~/.gitolite.rc manually if you need features + echo controlled by any of the following variables: + echo ---- + sed -e 's/^/ /' < .diffvars + echo ---- + fi + rm -f .newvars .oldvars .diffvars +else + [[ -n $pubkey_file ]] || die "looks like first run -- I need a pubkey file" + cp $GL_PACKAGE_CONF/example.gitolite.rc ~/.gitolite.rc +fi + +gl-install -q + +GL_ADMINDIR=$(cd;perl -e 'do ".gitolite.rc"; print $GL_ADMINDIR') +REPO_BASE=$( cd;perl -e 'do ".gitolite.rc"; print $REPO_BASE' ) + +[[ -f $GL_ADMINDIR/conf/gitolite.conf ]] || { + cat < $GL_ADMINDIR/conf/gitolite.conf + repo gitolite-admin + RW+ = $admin_name + + repo testing + RW+ = @all +EOF +} +[[ -n $pubkey_file ]] && cp $pubkey_file $GL_ADMINDIR/keydir + +touch $HOME/.ssh/authorized_keys +gl-compile-conf -q + +# setup push-to-admin +od=$PWD +cd; cd $REPO_BASE/gitolite-admin.git +GIT_WORK_TREE=$GL_ADMINDIR git add conf/gitolite.conf keydir +GIT_WORK_TREE=$GL_ADMINDIR git diff --cached --quiet || GIT_WORK_TREE=$GL_ADMINDIR git commit -am start +cd $od + +# now that the admin repo is created, you have to set the hooks properly; best +# do it by running install again +gl-install -q