gl-dont-panic replaced by more generic gl-admin-push

(sorry Douglas Adams; the "towel day" program is no more!)
This commit is contained in:
Sitaram Chamarty 2011-07-13 19:34:16 +05:30
parent df885e5989
commit 42df4c01a9
6 changed files with 95 additions and 130 deletions

View file

@ -19,6 +19,7 @@ In this document:
* <a href="#_personal_branches">"personal" branches</a>
* <a href="#_custom_hooks_and_custom_git_config">custom hooks and custom git config</a>
* <a href="#_bypassing_gitolite">bypassing gitolite</a>
* <a href="#_gl_admin_push_bypassing_gitolite_for_the_gitolite_admin_repo">gl-admin-push: bypassing gitolite for the gitolite-admin repo</a>
* <a href="#_disabling_write_access_to_take_backups">disabling write access to take backups</a>
* <a href="#_INconvenience_features">INconvenience features</a>
* <a href="#_deleting_a_repo">deleting a repo</a>
@ -326,11 +327,37 @@ to set that variable permanently, preferring this mode instead:
GL_BYPASS_UPDATE_HOOK=1 git push
**WARNING**: Do **NOT** try this with the special `gitolite-admin` repo. That
repo also runs a `post-update` hook which needs additional information which
is NOT available if you bypass gitolite. Mucking with that repo in this
manner is strongly discouraged, as in "are you feeling lucky today?". Use
`gl-dont-panic` if you need to do some server-side surgery for that repo.
<a name="_gl_admin_push_bypassing_gitolite_for_the_gitolite_admin_repo"></a>
##### gl-admin-push: bypassing gitolite for the gitolite-admin repo
The method described in the previous section (setting `GL_BYPASS_UPDATE_HOOK`)
will work for all the repos managed by gitolite, **except** for the special
`gitolite-admin` repo. For that you will need some extra magic, because there
is also a `post-update` hook that runs here, and this needs additional
information which is NOT available if you bypass gitolite.
Use the `gl-admin-push` program to make changes to the admin repo directly on
the server. Here's how:
* clone the repo to some safe location and cd to it:
cd /tmp
git clone ~/repositories/gitolite-admin.git
cd gitolite-admin
* make whatever changes you want to that clone and commit. You can add new
keys, change the conf file, or anything at all that needs fixing up. You
can even reset to an older commit (rewind) if that is the simplest way to
fix up some config problem that may have lost you your access.
* when done, instead of `git push <push arguments>`, use this program
instead, like so:
gl-admin-push <push arguments>
Note that this method will work for *any* repo, not just the special admin
repo.
<a name="_disabling_write_access_to_take_backups"></a>

View file

@ -131,7 +131,7 @@ gets this from `GL_BINDIR`.
#### OUTLIER!
* gl-dont-panic is an outlier. For some silly reason I have the notion that
* gl-admin-push is an outlier. For some silly reason I have the notion that
even if it runs from /tmp it should get the right values, so it is the
only one that interrogates `~/.ssh/authorized_keys` to get the actual
BINDIR in use!

View file

@ -31,7 +31,7 @@ In this document:
inherently less secure than pubkeys so not much point worrying about it.
* I have not tested any of the ancillary standalone programs (like
gl-dont-panic) in this mode. They're most likely going to crash and burn
gl-admin-push) in this mode. They're most likely going to crash and burn
because `$HOME` is not defined or in the wrong place; manually set
`HOME=$GITOLITE_HTTP_HOME` and hope for the best. Luckily most of them
have to do with sshkeys so this may not matter. YMMV.

View file

@ -250,9 +250,11 @@ first place, so the simplest way is to enable it from the server side only.
#### losing your admin key
If you lost the admin key, and need to re-establish ownership of the
gitolite-admin repository with a fresh key, take a look at the
`src/gl-dont-panic` program. You will need shell access to the server of
course. Run it without arguments to get instructions.
gitolite-admin repository with a fresh key, get a shell on the server and use
the program called `gl-admin-push` that comes with gitolite. See instructions
[here][gssp].
[gssp]: http://sitaramc.github.com/gitolite/doc/3-faq-tips-etc.html#_gl_server_side_push_bypassing_gitolite_for_the_gitolite_admin_repo
<a name="_simulating_ssh_copy_id"></a>
@ -431,14 +433,13 @@ invokes gitolite) is ignored.
To fix this, you have to use a different keypair for gitolite access. The
best way to do this is to create a new keypair, copy the pubkey to the server
as YourName.pub, then run `~/.gitolite/src/gl-dont-panic YourName.pub` on the
server. Remember to adjust your agent identities using ssh-add -D and ssh-add
if you're using ssh-agent, otherwise these new keys may not work.
as YourName.pub, then run `gl-setup YourName.pub` on the server. Remember to
adjust your agent identities using ssh-add -D and ssh-add if you're using
ssh-agent, otherwise these new keys may not work.
[In addition, for the 'from-client' install method, the admin may have used
the wrong URL syntax, having **utterly failed** to read/heed the message that
shows up at the end of running `gl-easy-install`. In this case the keys are
different, but the wrong one is being used.]
NOTE: If you installed using the 'from-client' install method, `gl-setup`
won't work. You will have to use the more generic method described
[here][gssp].
<a name="_appendix_3_ssh_client_may_not_be_offering_the_right_key"></a>

50
src/gl-admin-push Executable file
View file

@ -0,0 +1,50 @@
#!/bin/sh
die() { echo "$@"; exit 1; } >&2
# ----------
# if GL_BINDIR was not passed in, find it
[ -z "$GL_BINDIR" ] &&
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
Unable to determine correct path for gitolite scripts from the authkeys file.
Perhaps you haven't installed gitolite yet?
Or perhaps this is an HTTP mode install? If so, please set the GL_BINDIR
environment variable to the full path of the gitolite scripts, then re-try
this command. For example (if you followed doc/http-backend.mkd precisely):
GL_BINDIR=/var/www/gitolite-home/bin $0 $@
EOF2
exit 1
}
# ----------
get_rc_val() {
$GL_BINDIR/gl-query-rc $1
}
# bypass the update hook
export GL_BYPASS_UPDATE_HOOK
GL_BYPASS_UPDATE_HOOK=1
# for normal repos, the GL_BYPASS_UPDATE_HOOK above suffices, and in fact you
# don't even need this program. But for the gitolite-admin repo, the
# post-update hook will also get called, which then needs these:
export GL_RC
export GL_BINDIR
export GL_ADMINDIR
GL_RC=$(get_rc_val GL_RC 2>/dev/null)
[ -z "$GL_RC" ] && die "hmm weird... GL_RC is undefined; ABORTING"
GL_BINDIR=$( get_rc_val GL_BINDIR )
GL_ADMINDIR=$(get_rc_val GL_ADMINDIR)
# and finally:
git push "$@"

View file

@ -1,113 +0,0 @@
#!/bin/sh
usage() {
cat <<EOF
First: DON'T PANIC
NOTE: This advice pertains to gitolite specific issues. If you don't
have ANY access to the server at all, it is OK to panic.
Step 1: prepare
- copy this program to your gitolite server
- if you lost your admin key, create a new keypair on your workstation
and copy the pub part of this new key also to the server
- rename it to whatever your gitolite admin username is, with a .pub
extension. (Example, I would call it "sitaram.pub")
Step 2: use one of the fixes below (on the server)
- (FIX #1: REWINDING BAD ADMIN COMMITS) if your last commit(s) to the
gitolite-admin repo pushed a very bad config and you want to rewind it
to a known good state, run this:
$0 rewind
(this doesn't actually rewind; it creates a new commit that has
the same state as the last good commit, which has the same effect)
- (FIX #2: PUSHING A NEW ADMIN KEY) if you lost your admin key, or you
had used the wrong key initially, then you get yourself a new keypair
and run this with the new pubkey:
$0 sitaram.pub # example using my name
Please note that this simply *replaces* the key for user "sitaram".
It does NOT add a new admin called "sitaram". In fact it does not
touch the config file (access rules) at all.
Step 3: completing the fix (on your workstation)
- do a 'git pull' on the gitolite admin clone or make a fresh clone
EOF
exit 1
}
if [ -z "$1" ]
then
usage
fi
# ------------------------------------------------------------------------
# arg check
die() { echo "$@"; exit 1; } >&2
cd $HOME # if he didn't *start* there, it's his bloody fault
[ -f "$1" ] || [ "$1" = "rewind" ] || die "need a valid file or 'rewind'"
if [ "$1" = "rewind" ]
then
:
else
bn1=`basename $1`;
admin_name=`basename $1 .pub`;
[ "$bn1" = "$admin_name" ] && die "filename needs to end in '.pub'"
fi
# ------------------------------------------------------------------------
# setup stuff. Note that for *this* program, we don't want to rely on $0
# telling us bindir; the user should be allowed to run it from anywhere and
# still have it work. Luckily, by the time you feel the need to run this
# program, authkeys is already populated, and anyway that's the only
# *reliable* place to get this info. However, when running in HTTP mode or
# Fedora mode, you have *no* keys in the authkeys file. In those cases you
# have to manually set GL_BINDIR externally before running this program
[ -z "$GL_BINDIR" ] &&
GL_BINDIR=$( perl -ne 'print($1), exit if /^command="(.+?)\/gl-(time|auth-command) /' < $HOME/.ssh/authorized_keys)
GL_RC=$( $GL_BINDIR/gl-query-rc GL_RC)
REPO_BASE=$( $GL_BINDIR/gl-query-rc REPO_BASE)
GL_ADMINDIR=$($GL_BINDIR/gl-query-rc GL_ADMINDIR)
export GL_RC
export REPO_BASE
export GL_BINDIR
export GL_ADMINDIR
TEMPDIR=$(mktemp -d -t tmp.XXXXXXXXXX)
export TEMPDIR
trap "/bin/rm -rf $TEMPDIR" 0
# ------------------------------------------------------------------------
# rewind the admin repo
if [ "$1" = "rewind" ]
then
git clone $REPO_BASE/gitolite-admin.git $TEMPDIR
cd $TEMPDIR
echo printing the last 9 commits to the config; echo
git log -9 --date=relative --format="%h %ar%x09%s" | perl -pe 'print "$.\t"'
echo; read -p 'please enter how many commits you want to rewind: ' n
good=`git rev-parse --short HEAD~$n`
git checkout -f $good .
git commit -m "emergency revert to $good"
GL_BYPASS_UPDATE_HOOK=1 git push
exit $?
fi
# ------------------------------------------------------------------------
# add/overwrite a key ($1)
git clone $REPO_BASE/gitolite-admin.git $TEMPDIR
cp $1 $TEMPDIR/keydir
cd $TEMPDIR
git add keydir
git commit -m "emergency add/update $admin_name key (from $1)"
GL_BYPASS_UPDATE_HOOK=1 git push
exit $?