Merge branch 'system-install'

This commit is contained in:
Sitaram Chamarty 2009-10-28 21:46:27 +05:30
commit 593ed765a7
7 changed files with 160 additions and 57 deletions

View file

@ -9,6 +9,9 @@ slightly more manual process. Both are explained here.
In this document:
* easy install
* typical example run
* advantages over the older install methods
* disadvantages
* manual install
* other notes
* next steps
@ -36,6 +39,17 @@ 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).
#### typical example run
A typical run for me is:
src/00-easy-install.sh -q git my.git.server sitaram
`-q` stands for "quiet" mode -- very minimal output, no verbose descriptions
of what it is going to do, and no pauses unless absolutely needed. However,
if you're doing this for the first time or you appreciate knowing what it is
actually doing, I suggest you skip the `-q`.
#### advantages over the older install methods
* all ssh problems reduced to **just one pre-requisite**: enable ssh pubkey

View file

@ -17,6 +17,14 @@ set -e
die() { echo "$@"; echo; echo "run $0 again without any arguments for help and tips"; exit 1; }
prompt() {
# receives two arguments. A short piece of text to be displayed, without
# pausing, in "quiet" mode, and a much longer one to be displayed, *with*
# a pause, in normal (verbose) mode
[[ $quiet == -q ]] && [[ -n $1 ]] && {
echo "$1"
return
}
shift
echo
echo
echo ------------------------------------------------------------------------
@ -26,7 +34,10 @@ prompt() {
}
usage() {
cat <<EOFU
Usage: $0 user host port admin_name
Usage: $0 [-q] user host port admin_name
- (optional) "-q" as first arg sets "quiet" mode: no verbose descriptions of
what is going on, no pauses unless absolutely necessary
- "user" is the username on the server where you will be installing gitolite
- "host" is that server's hostname (or IP address is also fine)
- "port" is optional
@ -35,9 +46,6 @@ Usage: $0 user host port admin_name
Example usage: $0 git my.git.server sitaram
Output:
- a proper gitolite admin repo in $HOME/gitolite-admin
Notes:
- "user" and "admin_name" must be simple names -- no special characters etc
please (only alphanumerics, dot, hyphen, underscore)
@ -55,11 +63,6 @@ Pre-requisites:
**DO NOT RUN THIS PROGRAM UNTIL THAT WORKS**
Errors:
- if you get a "pubkey [...filename...] exists" error, it is either leftover
from a previous, failed, run, or a genuine file you need. Decide which it
is, and remove it and retry, or use a different "admin_name", respectively.
EOFU
exit 1;
}
@ -78,6 +81,13 @@ EOFU
exit 1;
}
# are we in quiet mode?
quiet=
[[ "$1" == "-q" ]] && {
quiet=-q
shift
}
# 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
@ -120,7 +130,8 @@ ssh -p $port -o PasswordAuthentication=no $user@$host true ||
# line). For example, "ssh-keygen -t rsa ~/.ssh/sitaram"; this would create
# two files in ~/.ssh (sitaram and sitaram.pub)
prompt "the next command will create a new keypair for your gitolite access
prompt "setting up keypair..." \
"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
@ -138,7 +149,8 @@ prompt "the next command will create a new keypair for your gitolite access
if [[ -f $HOME/.ssh/$admin_name.pub ]]
then
prompt "Hmmm... pubkey $HOME/.ssh/$admin_name.pub exists; should I just re-use it?
prompt " ...reusing $HOME/.ssh/$admin_name.pub..." \
"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..."
@ -155,7 +167,8 @@ fi
if ssh-add -l &>/dev/null
then
prompt "you're running ssh-agent. We'll try and do an ssh-add of the
prompt " ...adding key to agent..." \
"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."
@ -184,7 +197,8 @@ host gitolite
if grep 'host *gitolite' $HOME/.ssh/config &>/dev/null
then
prompt "your \$HOME/.ssh/config already has settings for gitolite. I will
prompt "found gitolite para in ~/.ssh/config; assuming it is correct..." \
"your \$HOME/.ssh/config already has settings for gitolite. I will
assume they're correct, but if they're not, please edit that file, delete
that paragraph (that line and the following few lines), Ctrl-C, and rerun.
@ -193,7 +207,8 @@ then
$(cat ~/.ssh/.gl-stanza)"
else
prompt "creating settings for your gitolite access in $HOME/.ssh/config;
prompt "creating gitolite para in ~/.ssh/config..." \
"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)"
@ -212,7 +227,7 @@ rm $HOME/.ssh/.gl-stanza
# have to create the directory first.
ssh -p $port $user@$host mkdir -p gitolite-install
rsync -e "ssh -p $port" -a src conf doc $user@$host:gitolite-install/
rsync $quiet -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
@ -223,7 +238,8 @@ 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
prompt "the gitolite rc file needs to be edited by hand. The defaults
prompt "finding/creating gitolite rc..." \
"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
@ -233,19 +249,20 @@ prompt "the gitolite rc file needs to be edited by hand. The defaults
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 .
if scp -P $port $user@$host:.gitolite.rc . &>/dev/null
then
prompt "Oh hey... you already had a '.gitolite.rc' file on the server.
prompt " ...trying to reuse existing rc" \
"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 /^\s*(\$\w+) *=/' > glrc.old
sort < conf/example.gitolite.rc | perl -ne 'print "$1\n" if /^\s*(\$\w+) *=/' > glrc.new
if diff -u glrc.old glrc.new
then
${VISUAL:-${EDITOR:-vi}} .gitolite.rc
[[ $quiet == -q ]] || ${VISUAL:-${EDITOR:-vi}} .gitolite.rc
else
prompt " looks like you're upgrading, and there are some new rc
variables that this version is expecting that your old rc file doesn't
have.
prompt "" \
" looks like you're upgrading, and there are some new rc variables
that this version is expecting that your old rc file doesn't have.
I'm going to run your editor with two filenames. The first is the
example file from this gitolite version. It will have a block (code
@ -264,13 +281,14 @@ then
fi
else
cp conf/example.gitolite.rc .gitolite.rc
${VISUAL:-${EDITOR:-vi}} .gitolite.rc
[[ $quiet == -q ]] || ${VISUAL:-${EDITOR:-vi}} .gitolite.rc
fi
# copy the rc across
scp -P $port .gitolite.rc $user@$host:
scp $quiet -P $port .gitolite.rc $user@$host:
prompt "ignore any 'please edit this file' or 'run this command' type
prompt "installing/upgrading..." \
"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..."
@ -281,7 +299,7 @@ REPO_BASE=$( ssh -p $port $user@$host "perl -e 'do \".gitolite.rc\"; print \$RE
# MANUAL: still in the "gitolite-install" directory? Good. Run
# "src/install.pl"
ssh -p $port $user@$host "cd gitolite-install; src/install.pl"
ssh -p $port $user@$host "cd gitolite-install; src/install.pl $quiet"
# MANUAL: if you're upgrading, just go to your clone of the admin repo, make a
# dummy change, and push. (This assumes that you didn't change the
@ -294,7 +312,8 @@ ssh -p $port $user@$host "cd gitolite-install; src/install.pl"
upgrade=0
if ssh -p $port $user@$host cat $GL_ADMINDIR/keydir/$admin_name.pub &> /dev/null
then
prompt "this looks like an upgrade, based on the fact that a file called
prompt "upgrade done!" \
"this looks like an upgrade, based on the fact that a file called
$admin_name.pub already exists in $GL_ADMINDIR/keydir on the server.
Please go to your clone of the admin repo, make a dummy change (like maybe
@ -326,11 +345,11 @@ repo testing
" > gitolite.conf
# send the config and the key to the remote
scp -P $port gitolite.conf $user@$host:$GL_ADMINDIR/conf/
scp -P $port $HOME/.ssh/$admin_name.pub $user@$host:$GL_ADMINDIR/keydir
scp $quiet -P $port gitolite.conf $user@$host:$GL_ADMINDIR/conf/
scp $quiet -P $port $HOME/.ssh/$admin_name.pub $user@$host:$GL_ADMINDIR/keydir
# MANUAL: cd to $GL_ADMINDIR and run "src/gl-compile-conf"
ssh -p $port $user@$host "cd $GL_ADMINDIR; src/gl-compile-conf"
ssh -p $port $user@$host "cd $GL_ADMINDIR; src/gl-compile-conf $quiet"
# ----------------------------------------------------------------------
# hey lets go the whole hog on this; setup push-to-admin!
@ -356,15 +375,16 @@ GIT_WORK_TREE=$GL_ADMINDIR git commit -am start --allow-empty
# properly. The install program does this. So cd back to the
# "gitolite-install" directory and run "src/install.pl"
ssh -p $port $user@$host "cd gitolite-install; src/install.pl"
ssh -p $port $user@$host "cd gitolite-install; src/install.pl $quiet"
# 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", or
# pull once again if you already have a clone
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."
prompt "cloning gitolite-admin repo..." \
"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

45
src/gitolite.pm Normal file
View file

@ -0,0 +1,45 @@
# this file is commonly used using "require". It is not required to use "use"
# (because it doesn't live in a different package)
# warning: preceding para requires 4th attribute of a programmer after
# laziness, impatience, and hubris: sense of humour :-)
# WARNING
# -------
# the name of this file will change as soon as its function/feature set
# stabilises enough ;-)
# right now all it does is define a function that tells you where to find the
# rc file
# ----------------------------------------------------------------------------
# where is the rc file hiding?
# ----------------------------------------------------------------------------
sub where_is_rc
{
# till now, the rc file was in one fixed place: .gitolite.rc in $HOME of
# the user hosting the gitolite repos. This was fine, because gitolite is
# all about empowering non-root users :-)
# then we wanted to make a debian package out of it (thank you, Rhonda!)
# which means (a) it's going to be installed by root anyway and (b) any
# config files have to be in /etc/<something>
# the only way to resolve this in a backward compat way is to look for the
# $HOME one, and if you don't find it look for the /etc one
# this common routine does that, setting an env var for the first one it
# finds
return if $ENV{GL_RC};
for my $glrc ( $ENV{HOME} . "/.gitolite.rc", "/etc/gitolite/gitolite.rc" ) {
if (-f $glrc) {
$ENV{GL_RC} = $glrc;
return;
}
}
}
1;

View file

@ -27,8 +27,15 @@ use warnings;
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;
# the common setup module is in the same directory as this running program is
my $bindir = $0;
$bindir =~ s/\/[^\/]+$//;
require "$bindir/gitolite.pm";
# ask where the rc file is, get it, and "do" it
&where_is_rc();
die "parse $ENV{GL_RC} failed: " . ($! or $@) unless do $ENV{GL_RC};
# then "do" the compiled config file, whose name we now know
die "parse $GL_CONF_COMPILED failed: " . ($! or $@) unless do $GL_CONF_COMPILED;
# add a custom path for git binaries, if specified

View file

@ -47,6 +47,9 @@ $Data::Dumper::Indent = 1;
# common definitions
# ----------------------------------------------------------------------------
# setup quiet mode if asked; please do not use this when running manually
open STDOUT, ">", "/dev/null" if (@ARGV and shift eq '-q');
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
@ -54,8 +57,14 @@ our ($GL_ADMINDIR, $GL_CONF, $GL_KEYDIR, $GL_CONF_COMPILED, $REPO_BASE, $REPO_UM
# typical push generates
my $ATTN = "\n\t\t***** ERROR *****\n ";
my $glrc = $ENV{HOME} . "/.gitolite.rc";
die "$ATTN parse $glrc failed: " . ($! or $@) unless do $glrc;
# the common setup module is in the same directory as this running program is
my $bindir = $0;
$bindir =~ s/\/[^\/]+$//;
require "$bindir/gitolite.pm";
# ask where the rc file is, get it, and "do" it
&where_is_rc();
die "parse $ENV{GL_RC} failed: " . ($! or $@) unless do $ENV{GL_RC};
# add a custom path for git binaries, if specified
$ENV{PATH} .= ":$GIT_PATH" if $GIT_PATH;
@ -337,12 +346,12 @@ for my $repo (sort keys %repos) {
if ($repos{$repo}{'R'}{'daemon'}) {
unless (-f $export_ok) {
system("touch $export_ok");
print STDERR "daemon add $repo.git\n";
print "daemon add $repo.git\n";
}
} else {
if (-f $export_ok) {
unlink($export_ok);
print STDERR "daemon del $repo.git\n";
print "daemon del $repo.git\n";
}
}
}
@ -354,21 +363,21 @@ for my $repo (sort keys %repos) {
# not in the old list; add it to the new one
$projlist{"$repo.git"} = 1;
$projlist_changed = 1;
print STDERR "gitweb add $repo.git\n";
print "gitweb add $repo.git\n";
}
} else {
if ($projlist{"$repo.git"}) {
# delete it from new list
delete $projlist{"$repo.git"};
$projlist_changed = 1;
print STDERR "gitweb del $repo.git\n";
print "gitweb del $repo.git\n";
}
}
}
# has there been a change in the gitweb projects list?
if ($projlist_changed) {
print STDERR "updating gitweb project list $PROJECTS_LIST\n";
print "updating gitweb project list $PROJECTS_LIST\n";
my $projlist_fh = wrap_open( ">", $PROJECTS_LIST);
print $projlist_fh join("\n", sort keys %projlist), "\n" if %projlist;
close $projlist_fh;

View file

@ -5,33 +5,40 @@ use warnings;
our ($REPO_BASE, $GL_ADMINDIR, $GL_CONF, $GIT_PATH);
# setup quiet mode if asked; please do not use this when running manually
open STDOUT, ">", "/dev/null" if (@ARGV and shift eq '-q');
# 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
sub wrap_mkdir
{
my $dir = shift;
if ( -d $dir ) {
print STDERR "$dir already exists\n";
print "$dir already exists\n";
return;
}
mkdir($dir) or die "mkdir $dir failed: $!\n";
print STDERR "created $dir\n";
print "created $dir\n";
}
# the only path that is *fixed* (can't be changed without changing all 3
# programs) is ~/.gitolite.rc
# the common setup module is in the same directory as this running program is
my $bindir = $0;
$bindir =~ s/\/[^\/]+$//;
require "$bindir/gitolite.pm";
my $glrc = $ENV{HOME} . "/.gitolite.rc";
unless (-f $glrc) {
# ask where the rc file is, get it, and "do" it
&where_is_rc();
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");
print STDERR "created $glrc\n";
print STDERR "please edit it, change the paths if you wish to, and RERUN THIS SCRIPT\n";
print "created $glrc\n";
print "please edit it, change the paths if you wish to, and RERUN THIS SCRIPT\n";
exit;
}
# ok now $glrc exists; read it to get the other paths
die "parse $glrc failed: " . ($! or $@) unless do $glrc;
# ok now the rc file exists; read it to get the other paths
die "parse $ENV{GL_RC} failed: " . ($! or $@) unless do $ENV{GL_RC};
# add a custom path for git binaries, if specified
$ENV{PATH} .= ":$GIT_PATH" if $GIT_PATH;
@ -50,7 +57,7 @@ system("cp -R src doc $GL_ADMINDIR");
unless (-f $GL_CONF) {
system("cp conf/example.conf $GL_CONF");
print STDERR <<EOF;
print <<EOF;
created $GL_CONF
please edit it, then run these two commands:
cd $GL_ADMINDIR
@ -70,7 +77,7 @@ for my $repo (`find . -type d -name "*.git"`) {
# oh and one of those repos is a bit more special and has an extra hook :)
if ( -d "gitolite-admin.git/hooks" ) {
print STDERR "copying post-update hook to gitolite-admin repo...\n";
print "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");

View file

@ -28,8 +28,9 @@ use warnings;
our ($GL_CONF_COMPILED, $PERSONAL);
our %repos;
my $glrc = $ENV{HOME} . "/.gitolite.rc";
die "parse $glrc failed: " . ($! or $@) unless do $glrc;
# we should already have the GL_RC env var set when we enter this hook
die "parse $ENV{GL_RC} failed: " . ($! or $@) unless do $ENV{GL_RC};
# then "do" the compiled config file, whose name we now know
die "parse $GL_CONF_COMPILED failed: " . ($! or $@) unless do $GL_CONF_COMPILED;
# ----------------------------------------------------------------------------