aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gitolite.pm32
-rwxr-xr-xsrc/gl-admin-push13
-rwxr-xr-xsrc/gl-compile-conf4
-rwxr-xr-xsrc/gl-conf-convert4
-rwxr-xr-xsrc/gl-dryrun8
-rwxr-xr-xsrc/gl-install102
-rwxr-xr-xsrc/gl-mirror-push1
-rwxr-xr-xsrc/gl-mirror-shell14
-rwxr-xr-xsrc/gl-setup81
-rwxr-xr-xsrc/gl-system-install209
-rwxr-xr-xsrc/gl-tool2
-rwxr-xr-xsrc/sshkeys-lint5
12 files changed, 279 insertions, 196 deletions
diff --git a/src/gitolite.pm b/src/gitolite.pm
index ca66107..37f3977 100644
--- a/src/gitolite.pm
+++ b/src/gitolite.pm
@@ -27,6 +27,7 @@ use Exporter 'import';
slurp
special_cmd
try_adc
+ wrap_mkdir
wrap_chdir
wrap_open
wrap_print
@@ -105,6 +106,17 @@ our %one_git_config; # ditto for %git_configs
# convenience subs
# ----------------------------------------------------------------------------
+sub wrap_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
+ my $dir = shift;
+ my $perm = shift; # optional
+ return if -d $dir;
+ mkdir($dir) or die "mkdir $dir failed: $!\n";
+ chmod $perm, $dir if $perm;
+}
+
sub wrap_chdir {
chdir($_[0]) or die "$ABRT chdir $_[0] failed: $! at ", (caller)[1], " line ", (caller)[2], "\n";
}
@@ -125,6 +137,19 @@ sub wrap_print {
chmod $oldmode, $file if $oldmode;
}
+sub wrap_system {
+ system(@_);
+
+ # straight from 'perldoc -f system' (sans the coredump part)
+ if ( $? == -1 ) {
+ print STDERR "failed to execute: $!\n";
+ } elsif ( $? & 127 ) {
+ printf STDERR "child died with signal %d\n", ( $? & 127 );
+ } else {
+ printf STDERR "child exited with value %d\n", $? >> 8;
+ }
+}
+
sub slurp {
local $/ = undef;
my $fh = wrap_open("<", $_[0]);
@@ -169,7 +194,9 @@ sub dos2unix {
sub log_it {
my ($ip, $logmsg);
- open my $log_fh, ">>", $ENV{GL_LOG} or die "open log failed: $!\n";
+ open my $log_fh, ">>", $ENV{GL_LOG} or die
+ "open log failed: $!\n" .
+ "attempting to log: " . ( $_[0] || '(nothing)' ) . "\n";
# first space sep field is client ip, per "man ssh"
($ip = $ENV{SSH_CONNECTION} || '(no-IP)') =~ s/ .*//;
# the first part of logmsg is the actual command used; it's either passed
@@ -467,6 +494,7 @@ sub setup_git_configs
next if $key =~ /^gitolite-options\./;
if ($value ne "") {
$value =~ s/^['"](.*)["']$/$1/;
+ $value =~ s/%GL_REPO/$repo/;
system("git", "config", $key, $value);
} else {
system("git", "config", "--unset-all", $key);
@@ -562,7 +590,7 @@ sub setup_gitweb_access
system("git config --remove-section gitweb 2>/dev/null");
}
- return ($desc or can_read($repo, 'gitweb'));
+ return (can_read($repo, 'gitweb') or $desc);
# this return value is used by the caller to write to projects.list
}
diff --git a/src/gl-admin-push b/src/gl-admin-push
index 3fd0214..cd71137 100755
--- a/src/gl-admin-push
+++ b/src/gl-admin-push
@@ -1,6 +1,15 @@
#!/bin/sh
die() { echo "$@" >&2; exit 1; }
+if [ "$1" = "-h" ]
+then
+ echo Usage:
+ echo " gl-admin-push [any options applicable to 'git push' command]"
+ echo
+ echo "Please see the 'gl-admin-push: ...' section in doc/tips-notes.mkd (Online at"
+ echo " http://sitaramc.github.com/gitolite/adminpush.html)"
+ exit 1
+fi
# ----------
@@ -9,7 +18,7 @@ die() { echo "$@" >&2; exit 1; }
GL_BINDIR=` perl -ne 'print($1), exit if /^command="(.+?)\/gl-(time|auth-command) /' < $HOME/.ssh/authorized_keys`
# GL_BINDIR still not known? we have a problem...
[ -z "$GL_BINDIR" ] && {
- cat <<EOF2
+ echo "
Unable to determine correct path for gitolite scripts from the authkeys file.
@@ -21,7 +30,7 @@ this command. For example (if you followed doc/http-backend.mkd precisely):
GL_BINDIR=/var/www/gitolite-home/bin $0 $@
-EOF2
+"
exit 1
}
diff --git a/src/gl-compile-conf b/src/gl-compile-conf
index 594d54c..4c296e6 100755
--- a/src/gl-compile-conf
+++ b/src/gl-compile-conf
@@ -175,9 +175,9 @@ sub parse_conf_line
@refs = qw(refs/.*) unless @refs;
# deprecation warning
map { print STDERR "WARNING: old syntax 'PATH/' found; please use new syntax 'NAME/'\n" if s(^PATH/)(NAME/) } @refs;
- # fully qualify refs that dont start with "refs/" or "NAME/";
+ # fully qualify refs that dont start with "refs/" or "NAME/" or "VREF/";
# prefix them with "refs/heads/"
- @refs = map { m(^(refs|NAME)/) or s(^)(refs/heads/); $_ } @refs;
+ @refs = map { m(^(refs|NAME|VREF)/) or s(^)(refs/heads/); $_ } @refs;
@refs = map { s(/USER/)(/\$gl_user/); $_ } @refs;
# expand the user list, unless it is just "@all"
diff --git a/src/gl-conf-convert b/src/gl-conf-convert
index 1faca4f..7b0bfee 100755
--- a/src/gl-conf-convert
+++ b/src/gl-conf-convert
@@ -9,6 +9,10 @@
use strict;
use warnings;
+if (not @ARGV and -t or $ARGV[0] eq '-h') {
+ print "Usage:\n gl-conf-convert < gitosis.conf > gitolite.conf\n(please the documentation for more)\n";
+ exit 1;
+}
my @comments = ();
my $groupname;
diff --git a/src/gl-dryrun b/src/gl-dryrun
index 2ebd198..5943433 100755
--- a/src/gl-dryrun
+++ b/src/gl-dryrun
@@ -11,7 +11,7 @@ cat <<EOFU
This is a quick hack. It is not "production quality". Resist the temptation
to turn this into an update.secondary hook and put it on the server. I WILL
NOT BE RESPONSIBLE FOR ANY PROBLEMS IF YOU DO THAT. (Even more so if you use
-'git checkout $3' *without* setting GIT_INDEX_FILE to something temporary, and
+'git checkout' *without* setting GIT_INDEX_FILE to something temporary, and
eventually realise that *deleted* files don't stay deleted...! And if you
didn't understand that, all the more reason not to do it).
@@ -35,6 +35,8 @@ EOFU
exit 1;
}
+[ "$1" = "-h" ] && usage
+
[ -n "$1" ] || die "need an admin username"
admin="$1"; shift
@@ -69,7 +71,7 @@ $GL_CONF_COMPILED="$GL_ADMINDIR/conf/gitolite.conf-compiled.pm";
$GL_WILDREPOS = 1;
$PROJECTS_LIST = $ENV{PWD} . "/projects.list";
$REPO_UMASK = 0077;
-$GL_BIG_CONFIG = 0;
+$GL_BIG_CONFIG = 1;
$GL_NO_DAEMON_NO_GITWEB = 1;
$GIT_PATH="";
$GL_GITCONFIG_KEYS = ".*";
@@ -86,7 +88,7 @@ EOF
# now compile it
echo compiling...
-$GL_BINDIR/gl-compile-conf
+$GL_BINDIR/gl-compile-conf || die "compile failed; aborting rest of run"
echo
echo "checking if $admin has push rights..."
diff --git a/src/gl-install b/src/gl-install
index de7aefd..ac9e84e 100755
--- a/src/gl-install
+++ b/src/gl-install
@@ -2,6 +2,8 @@
# INTERNAL COMMAND. NOT MEANT TO BE RUN BY THE USER DIRECTLY.
+# sets up REPO_BASE, GL_ADMINDIR. Symlinks hooks
+
use strict;
use warnings;
@@ -10,108 +12,52 @@ use warnings;
# ----------------------------------------------------------------------------
BEGIN {
- die "ENV GL_RC not set\n" unless $ENV{GL_RC};
+ die "ENV GL_RC not set\n" unless $ENV{GL_RC};
die "ENV GL_BINDIR not set\n" unless $ENV{GL_BINDIR};
}
use lib $ENV{GL_BINDIR};
+
use gitolite_rc;
+use gitolite_env;
use gitolite;
-# ----------------------------------------------------------------------------
-# start...
-# ----------------------------------------------------------------------------
-
-# 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;
- my $perm = shift; # optional
- if ( -d $dir ) {
- print "$dir already exists\n";
- return;
- }
- mkdir($dir) or die "mkdir $dir failed: $!\n";
- chmod $perm, $dir if $perm;
- print "created $dir\n";
-}
-
-unless ($ENV{GL_RC}) {
- # doesn't exist. Copy it across, tell user to edit it and come back
- my $glrc = $ENV{HOME} . "/.gitolite.rc";
- if ($GL_PACKAGE_CONF) {
- system("cp $GL_PACKAGE_CONF/example.gitolite.rc $glrc");
- } else {
- system("cp $ENV{GL_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;
-}
-
-# add a custom path for git binaries, if specified
-$ENV{PATH} .= ":$GIT_PATH" if $GIT_PATH;
-
-# set the umask before creating any files/directories
-umask($REPO_UMASK);
+setup_environment();
# mkdir $REPO_BASE, $GL_ADMINDIR if they don't already exist
wrap_mkdir($REPO_BASE);
-wrap_mkdir($GL_ADMINDIR, 0700);
+wrap_mkdir( $GL_ADMINDIR, 0700 );
+
# mkdir $GL_ADMINDIR's subdirs
-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", 0700);
+for my $dir (qw(conf keydir logs hooks hooks/common hooks/gitolite-admin)) {
+ wrap_mkdir( "$GL_ADMINDIR/$dir", 0700 );
}
-# "src" and "doc" will be overwritten on each install, but not conf
-if ($GL_PACKAGE_HOOKS) {
- system("cp -R -p $GL_PACKAGE_HOOKS $GL_ADMINDIR");
-} else {
- system("cp -R -p $ENV{GL_BINDIR}/../src $ENV{GL_BINDIR}/../doc $ENV{GL_BINDIR}/../hooks $GL_ADMINDIR");
- system("cp $ENV{GL_BINDIR}/../conf/VERSION $GL_ADMINDIR/conf");
-}
+# hooks must be propagated to all the repos in case they changed
-unless (-f $GL_CONF or $GL_PACKAGE_CONF) {
- print <<EOF;
- please do the following:
- 1. create and edit $GL_CONF to contain something like this:
- repo gitolite-admin
- RW+ = yourname
- 2. copy "yourname.pub" to $GL_ADMINDIR/keydir
- 3. run this command
- $GL_ADMINDIR/src/gl-compile-conf
-EOF
-}
+# See http://sitaramc.github.com/gitolite/hook_prop.html if you're not sure
+# what is happening here, especially the picture toward the end.
-# finally, hooks must be propagated to all the repos in case they changed
+# all repos, all hooks
chdir($REPO_BASE) or die "chdir $REPO_BASE failed: $!\n";
for my $repo (`find . -type d -name "*.git" -prune`) {
- chomp ($repo);
- # propagate our own, plus any local admin-defined, hooks
- ln_sf("$GL_ADMINDIR/hooks/common", "*", "$repo/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", "*", "$repo/hooks") if $GL_PACKAGE_HOOKS;
+ chomp($repo);
+ # propagate user hooks
+ ln_sf( "$GL_ADMINDIR/hooks/common", "*", "$repo/hooks" );
+ # propagate package hooks, overriding user hooks
+ ln_sf( "$GL_PACKAGE_HOOKS/common", "*", "$repo/hooks" );
chmod 0755, "$repo/hooks/update";
}
-# oh and one of those repos is a bit more special and has an extra hook :)
+# (special!) gitolite-admin repo, post-update hook, package hook only
if ( -d "gitolite-admin.git/hooks" ) {
- print "copying post-update hook to gitolite-admin repo...\n";
- unlink "gitolite-admin.git/hooks/post-update";
- symlink "$GL_ADMINDIR/hooks/gitolite-admin/post-update", "gitolite-admin.git/hooks/post-update"
- or die "could not symlink post-update hook\n";
- # ditto... (see previous block)
- ln_sf("$GL_PACKAGE_HOOKS/gitolite-admin", "post-update", "gitolite-admin.git/hooks") if $GL_PACKAGE_HOOKS;
+ ln_sf( "$GL_PACKAGE_HOOKS/gitolite-admin", "post-update", "gitolite-admin.git/hooks" );
chmod 0755, "gitolite-admin.git/hooks/post-update";
}
-# fixup program renames
+# deal with old program names...
+# not needed for RPM/DEB type systems since they take care of it themselves
+# but people upgrading might appreciate this; not sure how useful it is though
for my $oldname (qw(pta-hook.sh conf-convert.pl 00-easy-install.sh gl-easy-install 99-emergency-addkey.sh gl-emergency-addkey install.pl update-hook.pl hooks/update ga-post-update-hook VERSION)) {
unlink "$GL_ADMINDIR/src/$oldname";
unlink "$ENV{HOME}/gitolite-install/src/$oldname";
diff --git a/src/gl-mirror-push b/src/gl-mirror-push
index 70514cb..e7054e2 100755
--- a/src/gl-mirror-push
+++ b/src/gl-mirror-push
@@ -25,6 +25,7 @@ hn=`get_rc_val GL_HOSTNAME`
# get repo name then check if it's a local or slave (ie we're not the master)
[ -z "$1" ] && die fatal: missing reponame argument
repo=$1; shift
+repo=${repo%.git}
REPO_BASE=`get_rc_val REPO_BASE`
cd $REPO_BASE/$repo.git 2>/dev/null || die fatal: could not change directory to "$repo"
diff --git a/src/gl-mirror-shell b/src/gl-mirror-shell
index d2b6489..80534dc 100755
--- a/src/gl-mirror-shell
+++ b/src/gl-mirror-shell
@@ -39,6 +39,11 @@ die "fatal: GL_HOSTNAME not set in rc; mirroring disabled\n" unless $GL_HOSTNAME
# ----------------------------------------------------------------------------
+die "please read the gitolite mirroring documentation; this program is too
+critical for you to just run it based on a 'usage' message.\n" if not @ARGV or $ARGV[0] eq '-h';
+
+# ----------------------------------------------------------------------------
+
# deal with local invocations first
# on the "master", run from a shell, for one specific repo, with an optional
@@ -47,6 +52,7 @@ die "fatal: GL_HOSTNAME not set in rc; mirroring disabled\n" unless $GL_HOSTNAME
if ( ($ARGV[0] || '') eq 'request-push' and not $ENV{SSH_ORIGINAL_COMMAND} ) {
shift;
my $repo = shift or die "fatal: missing reponame\n";
+ $repo =~ s/\.git$//;
-d "$REPO_BASE/$repo.git" or die "fatal: no such repo?\n";
# this is the default argument if no slave list or key is supplied
@@ -77,8 +83,6 @@ if ( ($ARGV[0] || '') eq 'request-push' and not $ENV{SSH_ORIGINAL_COMMAND} ) {
exit 0;
}
-unless (@ARGV) { print STDERR "fatal: missing command\n"; exit 1; }
-
# ----------
# now the remote invocations; log it, then get the sender name
@@ -107,6 +111,7 @@ if ($soc eq 'info') {
if ($soc =~ /^git-receive-pack '(\S+)'$/) {
my $repo = $1;
+ $repo =~ s/\.git$//;
die "fatal: invalid characters in $repo\n" unless $repo =~ $REPONAME_PATT;
my $mm = mirror_mode($repo);
@@ -134,11 +139,12 @@ if ($soc =~ /^git-receive-pack '(\S+)'$/) {
if ($soc =~ /^request-push (\S+)$/) {
my $repo = $1;
+ $repo =~ s/\.git$//;
die "fatal: invalid characters in $repo\n" unless $repo =~ $REPONAME_PATT;
die "$ABRT fatal: $GL_HOSTNAME ==//==> $sender refused: not in slave list\n" unless mirror_listslaves($repo) =~ /(^|\s)$sender(\s|$)/;
print STDERR "$GL_HOSTNAME ==== ($repo) ===> $sender\n";
# just one sender, and we've checked that he is "on the list". Foreground...
- system("$ENV{GL_BINDIR}/gl-mirror-push", $repo, "-fg", $sender);
+ wrap_system("$ENV{GL_BINDIR}/gl-mirror-push", $repo, "-fg", $sender);
exit;
}
@@ -156,6 +162,8 @@ if ($soc =~ /^USER=(\S+) SOC=(git-receive-pack '(\S+)')$/) {
my $user = $1;
$ENV{SSH_ORIGINAL_COMMAND} = $2;
my $repo = $3;
+ $repo =~ s/\.git$//;
+ $repo =~ s(^/)();
die "fatal: invalid characters in $user\n" unless $user =~ $USERNAME_PATT;
die "fatal: invalid characters in $repo\n" unless $repo =~ $REPONAME_PATT;
die "$ABRT fatal: $GL_HOSTNAME <==//== $sender redirected push rejected\n" unless mirror_redirectOK($repo, $sender);
diff --git a/src/gl-setup b/src/gl-setup
index 7bf8881..1970d93 100755
--- a/src/gl-setup
+++ b/src/gl-setup
@@ -18,16 +18,42 @@ GL_PACKAGE_CONF=/tmp/share/gitolite/conf
# pubkey file if you happen to have lost all gitolite-access to the repos (but
# do have shell access via some other means)
+# ----------------------------------------------------------------------
+# local functions
+# ----------------------------------------------------------------------
+
die() { echo "$@" >&2; exit 1; }
get_rc_val() {
`dirname $0`/gl-query-rc $1
}
-TEMPDIR=`mktemp -d -t tmp.XXXXXXXXXX`
+# ----------------------------------------------------------------------
+# tempdir setup
+# ----------------------------------------------------------------------
+
+TEMPDIR=`perl -MFile::Temp -l -e 'print File::Temp::tempdir("tmp.XXXXXXXXXX", TMPDIR => 1);'`
export TEMPDIR
trap "/bin/rm -rf $TEMPDIR" 0
+# ----------------------------------------------------------------------
+# argument handling
+# ----------------------------------------------------------------------
+
+# save arguments for use in commit message later
+args="$*"
+
+if [ "$1" = "-h" ]
+then
+ echo Usage:
+ echo " gl-setup [-q] [-q] [YourName.pub] # ssh mode"
+ echo " gl-setup [-q] [-q] [YourName] # http mode"
+ echo
+ echo "Please see 'appendix d' in doc/install.mkd for more. (Online at"
+ echo " http://sitaramc.github.com/gitolite/install.html#gl-setup)"
+ exit 1
+fi
+
# quiet mode; only used to suppress popping up an editor on a new rc file
if [ "$1" = "-q" ]
then
@@ -35,6 +61,17 @@ then
quiet=1
fi
+# extra quiet mode (second '-q'); suppress the lint check at the end
+if [ "$1" = "-q" ]
+then
+ shift
+ nolint=1
+fi
+
+# ----------------------------------------------------------------------
+# get the admin_name and (usually) the pubkey file name
+# ----------------------------------------------------------------------
+
if [ -n "$GITOLITE_HTTP_HOME" ]
then
HOME=$GITOLITE_HTTP_HOME
@@ -51,6 +88,10 @@ else
fi
fi
+# ----------------------------------------------------------------------
+# report changes to rc file (for manual fixing) or setup a new rc file
+# ----------------------------------------------------------------------
+
export GL_RC
GL_RC=`get_rc_val GL_RC 2>/dev/null`
[ -z "$GL_RC" ] && GL_RC=$HOME/.gitolite.rc
@@ -62,7 +103,7 @@ then
}
print_rc_vars $GL_PACKAGE_CONF/example.gitolite.rc > $TEMPDIR/.newvars
print_rc_vars $GL_RC > $TEMPDIR/.oldvars
- comm -23 $TEMPDIR/.newvars $TEMPDIR/.oldvars > $TEMPDIR/.diffvars
+ grep -f $TEMPDIR/.oldvars -v $TEMPDIR/.newvars > $TEMPDIR/.diffvars
if [ -s $TEMPDIR/.diffvars ]
then
cp $GL_PACKAGE_CONF/example.gitolite.rc $HOME/.gitolite.rc.new
@@ -88,6 +129,10 @@ else
fi
fi
+# ----------------------------------------------------------------------
+# setup ~/.ssh
+# ----------------------------------------------------------------------
+
# setup ssh stuff. We break our normal rule that we will not fiddle with
# authkeys etc., because in this case it seems appropriate
(
@@ -98,6 +143,10 @@ fi
chmod go-w . .ssh .ssh/authorized_keys
)
+# ----------------------------------------------------------------------
+# setup gitolite's env vars
+# ----------------------------------------------------------------------
+
export GL_BINDIR
export REPO_BASE
export GL_ADMINDIR
@@ -105,42 +154,50 @@ GL_BINDIR=` get_rc_val GL_BINDIR `
REPO_BASE=` get_rc_val REPO_BASE `
GL_ADMINDIR=`get_rc_val GL_ADMINDIR`
-# now we get to gitolite itself
+# ----------------------------------------------------------------------
+# setup hooks, admindir, the admin repo
+# ----------------------------------------------------------------------
gl-install -q
[ -f $GL_ADMINDIR/conf/gitolite.conf ] || {
- cat <<EOF | cut -c9- > $GL_ADMINDIR/conf/gitolite.conf
+ echo "
repo gitolite-admin
RW+ = $admin_name
repo testing
RW+ = @all
-EOF
+ " | cut -c9- > $GL_ADMINDIR/conf/gitolite.conf
}
[ -n "$pubkey_file" ] && cp $pubkey_file $GL_ADMINDIR/keydir
touch $HOME/.ssh/authorized_keys
gl-compile-conf -q
-# setup push-to-admin
-[ -n "$pubkey_file" ] && (
+# setup the admin repo
+[ -n "$pubkey_file" ] || [ -n "$GITOLITE_HTTP_HOME" ] && (
cd $HOME; cd $REPO_BASE/gitolite-admin.git
GIT_WORK_TREE=$GL_ADMINDIR; export GIT_WORK_TREE
git add conf/gitolite.conf keydir
git config --get user.email >/dev/null || git config user.email $USER@`hostname`
git config --get user.name >/dev/null || git config user.name "$USER on `hostname`"
- git diff --cached --quiet 2>/dev/null || git commit -am start
+ git diff --cached --quiet 2>/dev/null || git commit -am "gl-setup $args"
)
# now that the admin repo is created, you have to set the hooks properly; best
# do it by running install again
gl-install -q
-# ----
+# ----------------------------------------------------------------------
+# lint check on ssh keys
+# ----------------------------------------------------------------------
+
+[ -z "$nolint" ] && {
+ # the never-ending quest to help with bloody ssh issues...
+ cd $GL_ADMINDIR/keydir
+ [ -n "$pubkey_file" ] && $GL_BINDIR/sshkeys-lint -q -a $admin_name < $HOME/.ssh/authorized_keys
+}
-# the never-ending quest to help with bloody ssh issues...
-cd $GL_ADMINDIR/keydir
-[ -n "$pubkey_file" ] && $GL_BINDIR/sshkeys-lint -q -a $admin_name < $HOME/.ssh/authorized_keys
+# ----------------------------------------------------------------------
exit 0
diff --git a/src/gl-system-install b/src/gl-system-install
index d7df7e4..b8b6377 100755
--- a/src/gl-system-install
+++ b/src/gl-system-install
@@ -1,117 +1,144 @@
-#!/bin/sh
+#!/usr/bin/perl
+use strict;
+use warnings;
+use English; # so I can say $EUID instead of $>
+use File::Path qw(mkpath);
-# install the gitolite software *system wide*. Not too robust, fancy, etc.,
-# but does have a usage message and catches simple problems.
+# install the gitolite software *system wide*.
-usage() { echo "
- Usage:
- $0 [shared-bin-dir shared-conf-dir shared-hooks-dir]
+# This program does for a manual install (root or non-root method) what
+# doc/packaging.mkd describes is needed to be done by a packager.
- Installs the gitolite software (just the software, not keys or repos)
- within \$HOME when invoked by a user, or system-wide when invoked by root.
+# Packagers can also use this program to do the same thing if they wish.
- Takes 0 or 3 absolute paths. The first one must be part of \$PATH.
+my ( $bin_dir, $conf_dir, $hooks_dir );
- Examples:
- # as root
- $0
+check_args();
+argv_or_defaults();
+check_dirs();
- # this defaults to:
- $0 /usr/local/bin /var/gitolite/conf /var/gitolite/hooks
+use FindBin;
+# we assume the standard gitolite source tree is here!
+chdir( $FindBin::Bin . "/.." ) or die "can't cd: $!\n";
- # as a normal user
- $0
+# notice the 'and' for failure after system() calls, because they return
+# "shell truth" not "perl truth"
- # this defaults to:
- $0 \$HOME/bin \$HOME/share/gitolite/conf \$HOME/share/gitolite/hooks
+# copy src
+system("cp src/* $bin_dir") and die "cp src/* to $bin_dir failed";
- [RPM packagers: you can supply a 4th argument to specify a 'buildroot'
- directory. DEB folks would call this a 'DESTDIR', I believe. In this
- usage the first 3 arguments are NOT optional]
-"
- exit 1;
-}
+# fixup GL_PACKAGE_CONF in gl-setup
+replace( "/tmp/share/gitolite/conf", $conf_dir, "$bin_dir/gl-setup" );
-die() { echo >&2; echo "$@" >&2; echo >&2; echo Run "$0 -h" for a detailed usage message. >&2; exit 1; }
-
-[ "$1" = "-h" ] && usage
+# record which version is being sent across; we assume it's HEAD
+record_version();
-validate_dir() {
- echo $1 | grep '^/' >/dev/null || die "$1 should be an absolute path"
- [ -d $1 ] || mkdir -p $1 || die "$1 does not exist and could not be created"
-}
+# copy conf
+system("cp -R conf/* $conf_dir") and die "cp conf/* to $conf_dir failed";
-# if we have a buildroot, set that up first
-buildroot=$4;
-[ -n "$buildroot" ] && validate_dir $buildroot
-[ -n "$buildroot" ] && buildroot=$buildroot/
-
-# either all 3 args must be supplied or none at all
-[ -n "$1" ] && [ -z "$3" ] && die "I need all 3 directories or none at all"
-# supply default values to args 1, 2, and 3 if not provided
-[ -z "$1" ] && {
- euid=`perl -e 'print $>'`
- if [ "$euid" = "0" ]
- then
- set /usr/local/bin /var/gitolite/conf /var/gitolite/hooks
- else
- set $HOME/bin $HOME/share/gitolite/conf $HOME/share/gitolite/hooks
- fi
- echo "using default values for EUID=$euid:" >&2
- echo "$@" >&2
-}
+# fixup GL_PACKAGE_CONF and GL_PACKAGE_HOOKS in the example rc
+replace( "/tmp/share/gitolite/conf", $conf_dir, "$conf_dir/example.gitolite.rc" );
+replace( "/tmp/share/gitolite/hooks", $hooks_dir, "$conf_dir/example.gitolite.rc" );
-gl_bin_dir=$1; validate_dir $buildroot$gl_bin_dir
-gl_conf_dir=$2; validate_dir $buildroot$gl_conf_dir
-gl_hooks_dir=$3; validate_dir $buildroot$gl_hooks_dir
+# copy hooks
+system("cp -R hooks/* $hooks_dir") and die "cp hooks/* to $hooks_dir failed";
-bindir=`echo $0 | perl -lpe 's/^/$ENV{PWD}\// unless /^\//; s/\/[^\/]+$//;'`
-cd $bindir/.. # we assume the standard gitolite source tree is here!
+# this is some extra gunk for people with crap setups
+path_advice();
-cp src/* $buildroot$gl_bin_dir || die "cp src/* to $buildroot$gl_bin_dir failed"
-perl -lpi -e "s(^GL_PACKAGE_CONF=.*)(GL_PACKAGE_CONF=$gl_conf_dir)" $buildroot$gl_bin_dir/gl-setup
+exit 0;
-# record which version is being sent across; we assume it's HEAD
-if git rev-parse --is-inside-work-tree >/dev/null 2>&1
-then
- git describe --tags --long --dirty=-dt 2>/dev/null > conf/VERSION || die "git describe failed -- your git is probably too old"
-else
- [ -f conf/VERSION ] || echo '(unknown)' > conf/VERSION
-fi
+# ----------------------------------------------------------------------
-cp -R conf/* $buildroot$gl_conf_dir || die "cp conf/* to $buildroot$gl_conf_dir failed"
-perl -lpi \
- -e "s(^#\s*\\\$GL_PACKAGE_CONF\s*=.*)(\\\$GL_PACKAGE_CONF = '$gl_conf_dir';)" \
- $buildroot$gl_conf_dir/example.gitolite.rc
-perl -lpi \
- -e "s(^#\s*\\\$GL_PACKAGE_HOOKS\s*=.*)(\\\$GL_PACKAGE_HOOKS = '$gl_hooks_dir';)" \
- $buildroot$gl_conf_dir/example.gitolite.rc
+sub check_args {
+ return unless @ARGV;
+ return if @ARGV == 3;
+ usage();
+}
-cp -R hooks/* $buildroot$gl_hooks_dir || die "cp hooks/* to $buildroot$gl_hooks_dir failed"
+sub argv_or_defaults {
+ ( $bin_dir, $conf_dir, $hooks_dir ) = @ARGV;
+ return if @ARGV;
+
+ unless (@ARGV) {
+ my $HOME = $ENV{HOME};
+ if ( $EUID eq "0" ) {
+ ( $bin_dir, $conf_dir, $hooks_dir ) = qw(/usr/local/bin /var/gitolite/conf /var/gitolite/hooks);
+ } else {
+ ( $bin_dir, $conf_dir, $hooks_dir ) = ( "$HOME/bin", "$HOME/share/gitolite/conf", "$HOME/share/gitolite/hooks" );
+ }
+ print STDERR "using default values for EUID=$EUID:\n";
+ print STDERR join( ", ", $bin_dir, $conf_dir, $hooks_dir ), "\n";
+ }
+}
-# ----
+sub check_dirs {
+ for my $dir ( $bin_dir, $conf_dir, $hooks_dir ) {
+ die "$dir should be an absolute path\n" unless $dir =~ m(^/);
+ mkpath($dir);
+ -d $dir or die "$dir does not exist and could not be created\n";
+ }
+}
-# check if $gl_bin_dir is in $PATH and advise the user if needed
-which=`which gl-setup 2>/dev/null`
+sub replace {
+ my ( $old, $new, $file ) = @_;
+ system("perl -lpi -e 's($old)($new)' $file");
+}
-path_advice="
-Since gl-setup MUST be run from the PATH (and not as src/gl-setup or such),
-you must fix this before running gl-setup. The simplest way is to add
+sub record_version {
+ # this is really much easier in plain shell :(
+ if ( system("git rev-parse --is-inside-work-tree >/dev/null 2>&1") ) {
+ # for system() calls, perl 'true/success' is shell 'false/fail', which
+ # means the command failed; we are not in a git work tree
+ -f "conf/VERSION" or system("echo '(unknown)' > conf/VERSION");
+ } else {
+ system("git describe --tags --long --dirty=-dt 2>/dev/null > conf/VERSION")
+ and die "git describe failed -- your git is probably too old";
+ }
+}
- PATH=$gl_bin_dir:\$PATH
+sub path_advice {
+ my $path_advice = "
+ Since gl-setup MUST be run from the PATH (and not as src/gl-setup or
+ such), you must fix this before running gl-setup. Just add
+
+ PATH=$bin_dir:\$PATH
+
+ to the end of your bashrc or similar file. You can even simply do that
+ manually each time you log in and want to run a gitolite command.\n";
+
+ for my $p ( split( ':', $ENV{PATH} ) ) {
+ return if $p eq $bin_dir; # all is well
+
+ if ( -x "$p/gl-setup" ) {
+ #<<<
+ die " ***** WARNING *****\n" .
+ " you have installed the sources into $bin_dir, but\n" .
+ " $p in your \$PATH *also* contains gl-setup.\n" .
+ " This is almost certainly going to confuse you or me later.\n" .
+ $path_advice;
+ #>>>
+ }
+ }
+
+ #<<<
+ die " ***** WARNING *****\n" .
+ " gl-setup is not in your \$PATH.\n" .
+ $path_advice;
+ #>>>
+}
-to the end of your bashrc or similar file. You can even simply run that
-command manually each time you log in and want to run a gitolite command."
+sub usage {
+ print "
+Usage:
+ gl-system-install [bin-dir conf-dir hooks-dir]
-[ -z "$which" ] && die " ***** WARNING *****
-gl-setup is not in your \$PATH.
-$path_advice"
+Requires all 3 arguments or none. All arguments supplied must be absolute
+paths. The following defaults are used if arguments are not supplied:
-which=`dirname $which`
-[ "$which" = "$gl_bin_dir" ] || die " ***** WARNING *****
-$which precedes $gl_bin_dir in your \$PATH,
-and it *also* contains gl-setup. This is almost certainly going to confuse
-you or me later.
-$path_advice"
+ as normal user: \$HOME/bin, \$HOME/share/gitolite/conf, \$HOME/share/gitolite/hooks
+ as root: /usr/local/bin, /var/gitolite/conf, /var/gitolite/hooks
+";
+ exit 1;
+}
-exit 0
diff --git a/src/gl-tool b/src/gl-tool
index 256a47a..d95a3bc 100755
--- a/src/gl-tool
+++ b/src/gl-tool
@@ -13,7 +13,7 @@ use gitolite_rc;
use gitolite;
sub usage { print <DATA>; exit 1; }
-usage() unless (@ARGV);
+usage() if (not @ARGV) or $ARGV[0] eq '-h';
my $cmd = shift;
my $pub = shift;
diff --git a/src/sshkeys-lint b/src/sshkeys-lint
index 96c027f..a18a306 100755
--- a/src/sshkeys-lint
+++ b/src/sshkeys-lint
@@ -8,7 +8,8 @@ use warnings;
use Getopt::Long;
my $admin = 0;
my $quiet = 0;
-GetOptions('admin|a=s' => \$admin, 'quiet|q' => \$quiet);
+my $help = 0;
+GetOptions('admin|a=s' => \$admin, 'quiet|q' => \$quiet, 'help|h' => $help);
use Data::Dumper;
$Data::Dumper::Deepcopy = 1;
@@ -31,7 +32,7 @@ sub msg {
print "sshkeys-lint: " . ( $warning ? "WARNING: " : "" ) . $_ for @_;
}
-@ARGV or not -t or usage();
+usage() if not @ARGV and -t or $help;
our @pubkeyfiles = @ARGV; @ARGV = ();
# ------------------------------------------------------------------------