GL_BINDIR2 becomes LOCAL_CODE, allows hook propagation also...
plus a bunch of doc changes
This commit is contained in:
parent
3c0f177481
commit
4373c5c74c
107
doc/cust.mkd
107
doc/cust.mkd
|
@ -5,7 +5,9 @@ not considered "core". This keeps the core simpler, and allows you to enhance
|
|||
gitolite for your own purposes without too much fuss. (As an extreme example,
|
||||
even mirroring is not in core now!)
|
||||
|
||||
(Also, please see the [developer notes][dev-notes] page).
|
||||
This document will tell you about the types of non-core programs, and
|
||||
how/where to install your own. (Actually *writing* the code is described in
|
||||
the [developer notes][dev-notes] page).
|
||||
|
||||
----
|
||||
|
||||
|
@ -13,13 +15,13 @@ even mirroring is not in core now!)
|
|||
|
||||
----
|
||||
|
||||
## types of non-core programs
|
||||
## introduction
|
||||
|
||||
There are 5 basic types of non-core programs.
|
||||
|
||||
* *Commands* can be run from the shell command line. Among those, the ones
|
||||
listed in the COMMANDS hash of the rc file can also be run remotely.
|
||||
* *Hooks* are standard git hooks; see below.
|
||||
* *Hooks* are standard git hooks.
|
||||
* *Sugar scripts* change the conf language for your convenience. The word
|
||||
sugar comes from "syntactic sugar".
|
||||
* *Triggers* are to gitolite what hooks are to git. I just chose a
|
||||
|
@ -29,9 +31,76 @@ There are 5 basic types of non-core programs.
|
|||
[Here][non-core] is a list of non-core programs shipped with gitolite, with
|
||||
some description of each.
|
||||
|
||||
## #commands gitolite "commands"
|
||||
## locations
|
||||
|
||||
Gitolite comes with several commands that users can run. Remote users run the
|
||||
### default/primary location of non-core programs
|
||||
|
||||
Regardless of how you installed gitolite, `gitolite query-rc GL_BINDIR` will
|
||||
tell you where the programs reside. Within that directory, the locations of
|
||||
non-core programs are:
|
||||
|
||||
* `commands` for commands.
|
||||
* `syntactic-sugar` for sugar scripts.
|
||||
* `triggers` and `lib/Gitolite/Triggers` for triggers ([this][triggers] will
|
||||
explain the difference).
|
||||
* `VREF` for [VREFs][vref].
|
||||
|
||||
### #localcode alternate location -- the `LOCAL_CODE` rc variable
|
||||
|
||||
If you want to add new non-core programs to your installation, or override the
|
||||
shipped non-core programs with your own versions, it's easy enough to simply
|
||||
copy your programs to the appropriate directory above, but then they'd get
|
||||
wiped out on the next upgrade.
|
||||
|
||||
A simple, "git-ish", method is to maintain a "local" branch in your clone of
|
||||
the gitolite source repo and make your changes there. Maintain them using
|
||||
rebase or merge when you 'git pull' gitolite itself, then use the rebased or
|
||||
merged "local" as the source for your gitolite upgrades. Works very nicely,
|
||||
and uses nothing but your git knowledge.
|
||||
|
||||
Sadly, it doesn't work for people installing from RPMs/DEBs; their "primary
|
||||
location" has already been setup, so any site-local customisations have to be
|
||||
done elsewhere.
|
||||
|
||||
This is where `LOCAL_CODE` comes in. If you define the `LOCAL_CODE` rc
|
||||
variable, then its value (**please use a FULL path**) describes a location
|
||||
where you can have any or all of these subdirectories:
|
||||
|
||||
* `commands`
|
||||
* `hooks/common`
|
||||
* `syntactic-sugar`
|
||||
* `triggers` and `lib/Gitolite/Triggers`
|
||||
* `VREF`
|
||||
|
||||
You might have noticed there's a new `hooks/common` directory here so you can
|
||||
add hooks also using this mechanism. Unlike the rest of the directories,
|
||||
adding new hooks to `hooks/common` requires that you follow up with `gitolite
|
||||
setup`, or at least `gitolite setup --hooks-only`.
|
||||
|
||||
### #pushcode managing custom code via the gitolite-admin repo
|
||||
|
||||
The location given in `LOCAL_CODE` could be anywhere on disk.
|
||||
|
||||
However, if you point it to someplace inside `$GL_ADMIN_BASE` (i.e.,
|
||||
`$HOME/.gitolite`), then you can version those programs using the
|
||||
gitolite-admin repo.
|
||||
|
||||
I suggest using a directory called "local-code" within the gitolite-admin repo
|
||||
that contains as much of the above directory structure you need. If you do
|
||||
that, then this is what you'd have in the rc file:
|
||||
|
||||
LOCAL_CODE => "$ENV{HOME}/.gitolite/local-code",
|
||||
|
||||
When you do this, gitolite takes care of everything automatically, including
|
||||
running `gitolite setup --hooks-only` when you change any hooks and push.
|
||||
**However, if you do this, anyone who can push changes to the admin repo will
|
||||
effectively be able to run any arbitrary command on the server.**
|
||||
|
||||
## types of non-core programs
|
||||
|
||||
### #commands gitolite "commands"
|
||||
|
||||
Gitolite comes with several commands that users can run. Remote users run
|
||||
commands by saying:
|
||||
|
||||
ssh git@host command-name [args...]
|
||||
|
@ -46,23 +115,25 @@ checking for the presence of env var `GL_USER`.
|
|||
You can get a **list of available commands** by using the `help` command.
|
||||
Naturally, a remote user will see a much smaller list than the server user.
|
||||
|
||||
You add commands to the "allowed from remote" list by adding its name (or
|
||||
uncommenting it if it's already added but commented out) to the COMMANDS hash
|
||||
in the [rc][] file.
|
||||
You allow a command to be run from remote clients by adding its name to (or
|
||||
uncommenting it if it's already added but commented out) the COMMANDS hash in
|
||||
the [rc][] file.
|
||||
|
||||
If you write your own commands, put them in src/commands.
|
||||
### #hooks hooks and gitolite
|
||||
|
||||
## #hooks hooks and gitolite
|
||||
You can install any hooks except these:
|
||||
|
||||
Gitolite uses the `update` hook for all repos. In addition, it uses the
|
||||
`post-update` hook for the gitolite-admin repo.
|
||||
* (all repos) gitolite reserves the `update` hook. See the "update hook"
|
||||
section in [dev-notes][] if you want additional update hook functionality.
|
||||
|
||||
If you want to add your own hook, it's easy as long as it's not the 'update'
|
||||
hook. Just add it to `$HOME/.gitolite/hooks/common` and run `gitolite setup`.
|
||||
* (gitolite-admin repo only) gitolite reserves the `post-update` hook.
|
||||
|
||||
The rest is between you and 'man githooks' :-)
|
||||
How/where to install them is described in detail in the "locations" section
|
||||
above, especially [this][localcode] and [this][pushcode]. The summary is that
|
||||
you put them in the "hooks/common" sub-directory within the directory whose
|
||||
name is given in the `LOCAL_CODE` rc variable.
|
||||
|
||||
## #sugar syntactic sugar
|
||||
### #sugar syntactic sugar
|
||||
|
||||
Sugar scripts help you change the perceived syntax of the conf language. The
|
||||
base syntax of the language is very simple, so sugar scripts take something
|
||||
|
@ -74,10 +145,10 @@ lines), while the parser in the core gitolite engine does not change.
|
|||
If you want to write your own sugar scripts, please read the "your own sugar"
|
||||
section in [dev-notes][] first then email me.
|
||||
|
||||
## triggers
|
||||
### triggers
|
||||
|
||||
Triggers have their own [document][triggers].
|
||||
|
||||
## VREFs
|
||||
### VREFs
|
||||
|
||||
VREFs also have their own [document][vref].
|
||||
|
|
|
@ -7,8 +7,9 @@
|
|||
Gitolite has a huge bunch of existing features that gradually need to moved
|
||||
over. Plus you may want to write your own programs to interact with it.
|
||||
|
||||
Here are some random notes on developing hooks, commands, triggers, and sugar
|
||||
scripts.
|
||||
**This document is about *writing* hooks, commands, triggers, VREFS, and sugar
|
||||
scripts. *Installing* them, including "where and how", is described
|
||||
[here][localcode]**.
|
||||
|
||||
## environment variables and other inputs
|
||||
|
||||
|
@ -56,14 +57,19 @@ serve as documentation.
|
|||
|
||||
## writing your own...
|
||||
|
||||
### ...commands
|
||||
|
||||
Commands are standalone programs, in any language you like. They simply
|
||||
receive the arguments you append. In addition, the env var `GL_USER` is
|
||||
available if it is being run remotely. src/commands/desc is the best example
|
||||
at present.
|
||||
|
||||
### ...hooks
|
||||
|
||||
#### anything but the update hook
|
||||
|
||||
If you want to add your own hook, it's easy as long as it's not the 'update'
|
||||
hook. Just add it to `$HOME/.gitolite/hooks/common` and run `gitolite setup`.
|
||||
|
||||
The rest is between you and 'man githooks' :-)
|
||||
If you want to add any hook other than the update hook, 'man githooks' is all
|
||||
you need.
|
||||
|
||||
#### update hook
|
||||
|
||||
|
@ -71,7 +77,8 @@ If you want to add additional `update` hook functionality, do this:
|
|||
|
||||
* Write and test your update hook separately from gitolite.
|
||||
|
||||
* Now add the code to src/VREF. Let's say it is called "foo".
|
||||
* Now add the code as a VREF (see [here][localcode] for details). Let's say
|
||||
you called it "foo".
|
||||
|
||||
* To call your new update hook to all accesses for all repos, add this to
|
||||
the end of your conf file:
|
||||
|
@ -79,24 +86,13 @@ If you want to add additional `update` hook functionality, do this:
|
|||
repo @all
|
||||
- VREF/foo = @all
|
||||
|
||||
As you probably guessed, you can now make your additional update hooks more
|
||||
As you probably guessed, you can make your additional update hooks more
|
||||
selective, applying them only to some repos / users / combinations.
|
||||
|
||||
Note: a normal update hook expects 3 arguments (ref, old SHA, new SHA). A
|
||||
VREF will get those three, followed by at least 4 more. Your VREF should just
|
||||
ignore the extra args.
|
||||
|
||||
### ...commands
|
||||
|
||||
You can add your own commands. You can run them on the server (example,
|
||||
`gitolite access`). Then you can enable certain commands to be allowed to run
|
||||
by a remote user by adding them to the "COMMANDS" hash of the [rc][] file.
|
||||
|
||||
Commands are standalone programs, in any language you like. They simply
|
||||
receive the arguments you append. In addition, the env var `GL_USER` is
|
||||
available if it is being run remotely. src/commands/desc is the best example
|
||||
at present.
|
||||
|
||||
### ...trigger programs
|
||||
|
||||
Trigger programs run at specific points in gitolite's execution, with specific
|
||||
|
|
|
@ -101,7 +101,7 @@
|
|||
* the [subconf][] command
|
||||
* ([link][partial-copy]: faking selective READ control)
|
||||
* using pubkeys obtained [from elsewhere][keysonly]
|
||||
* [updating hooks][pushhook] via the admin repo
|
||||
* ([link][pushcode]: updating code via the admin repo)
|
||||
|
||||
## interfacing with [external][] tools
|
||||
|
||||
|
|
23
doc/rc.mkd
23
doc/rc.mkd
|
@ -98,24 +98,7 @@ information.
|
|||
|
||||
DEFAULT_ROLE_PERMS => "READERS \@all\nWRITERS \@senior_devs",
|
||||
|
||||
* `GL_BINDIR2`, string
|
||||
* `LOCAL_CODE`, string
|
||||
|
||||
This is useful when you install gitolite system-wide, but want to add or
|
||||
override commands, VREFs, triggers, etc., by putting them somewhere in the
|
||||
hosting user's home directory (i.e., without requiring root privileges).
|
||||
|
||||
Add a new variable `GL_BINDIR2` to the the rc file. Example:
|
||||
|
||||
GL_BINDIR2 => "$ENV{HOME}/gitolite/src2",
|
||||
|
||||
In that directory, create as much of the following directory structure as
|
||||
you need to add your programs:
|
||||
|
||||
.
|
||||
|-- commands
|
||||
|-- lib
|
||||
| `-- Gitolite
|
||||
| `-- Triggers
|
||||
|-- syntactic-sugar
|
||||
|-- triggers
|
||||
`-- VREF
|
||||
This is described in more detail [here][localcode]. Please be aware
|
||||
**this must be a FULL path**, not a relative path.
|
||||
|
|
|
@ -68,41 +68,3 @@ Then write a script that
|
|||
|
||||
Run this from cron or however you want.
|
||||
|
||||
## #pushhook updating hooks via the admin repo
|
||||
|
||||
Gitolite by default maintains the distinction between someone who can push to
|
||||
the admin repo and someone who has shell access to the server. As a result,
|
||||
you cannot change any hooks merely by pushing the admin repo.
|
||||
|
||||
But some people don't care about this and want to do it anyway. Besides,
|
||||
there *is* one advantage: your hooks can also be versioned now.
|
||||
|
||||
So here's how to add/change hooks when you push the gitolite-admin repo:
|
||||
|
||||
1. Put all common hooks in a new directory called 'common-hooks'.
|
||||
|
||||
2. Create a trigger program called 'propagate-hooks' in 'src/triggers' that
|
||||
contains this:
|
||||
|
||||
#!/bin/sh
|
||||
|
||||
cd $GL_ADMIN_BASE
|
||||
cp -a common-hooks/* hooks/common
|
||||
|
||||
gitolite setup --hooks-only
|
||||
|
||||
3. Add this to the `POST_COMPILE` trigger list in the rc file.
|
||||
|
||||
And that should be it, pretty much.
|
||||
|
||||
If you have lots of repos this is inefficient -- because the hook fixup will
|
||||
run on *any* change to the admin repo, even if the change has nothing to do
|
||||
with hooks.
|
||||
|
||||
If you're concerned about this, put the script in 'src/commands' instead of
|
||||
'src/triggers'. (You might want to add some access control; see other
|
||||
commands for inspiration, but it's not really needed in this case).
|
||||
|
||||
Then, whenever any hooks have changed, the admin can run
|
||||
|
||||
ssh git@host propagate-hooks
|
||||
|
|
|
@ -323,14 +323,13 @@ sub store_common {
|
|||
$hook_reset++;
|
||||
}
|
||||
|
||||
# propagate user hooks
|
||||
# propagate user-defined (custom) hooks to all repos
|
||||
ln_sf( "$rc{LOCAL_CODE}/hooks/common", "*", "$repo.git/hooks" ) if $rc{LOCAL_CODE};
|
||||
|
||||
# override/propagate gitolite defined hooks for all repos
|
||||
ln_sf( "$rc{GL_ADMIN_BASE}/hooks/common", "*", "$repo.git/hooks" );
|
||||
|
||||
# propagate admin hook
|
||||
# override/propagate gitolite defined hooks for the admin repo
|
||||
ln_sf( "$rc{GL_ADMIN_BASE}/hooks/gitolite-admin", "*", "$repo.git/hooks" ) if $repo eq 'gitolite-admin';
|
||||
|
||||
# g2 diff: no "site-wide" hooks (the stuff in between gitolite hooks
|
||||
# and user hooks) anymore. I don't think anyone used them anyway...
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,11 +25,20 @@ sub post_update {
|
|||
tsh_try("git ls-tree --name-only master");
|
||||
_die "no files/dirs called 'hooks' or 'logs' are allowed" if tsh_text() =~ /^(hooks|logs)$/m;
|
||||
|
||||
my $hooks_changed = 0;
|
||||
{
|
||||
local $ENV{GIT_WORK_TREE} = $rc{GL_ADMIN_BASE};
|
||||
|
||||
tsh_try("git diff --name-only master");
|
||||
$hooks_changed++ if tsh_text() =~ m(/hooks/common/);
|
||||
# the leading slash ensure that this hooks/common directory is below
|
||||
# some top level directory, not *at* the top. That's LOCAL_CODE, and
|
||||
# it's actual name could be anything but it doesn't matter to us.
|
||||
|
||||
tsh_try("git checkout -f --quiet master");
|
||||
}
|
||||
_system("gitolite compile");
|
||||
_system("gitolite setup --hooks-only") if $hooks_changed;
|
||||
_system("gitolite trigger POST_COMPILE");
|
||||
|
||||
exit 0;
|
||||
|
|
|
@ -87,7 +87,7 @@ do $ENV{G3T_RC} if exists $ENV{G3T_RC} and -r $ENV{G3T_RC};
|
|||
# setup some perl/rc/env vars
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
unshift @INC, "$rc{GL_BINDIR2}/lib" if $rc{GL_BINDIR2};
|
||||
unshift @INC, "$rc{LOCAL_CODE}/lib" if $rc{LOCAL_CODE};
|
||||
|
||||
$ENV{PATH} = "$ENV{GL_BINDIR}:$ENV{PATH}";
|
||||
|
||||
|
@ -232,13 +232,13 @@ sub trigger {
|
|||
}
|
||||
|
||||
sub _which {
|
||||
# looks for a file in GL_BINDIR2 or GL_BINDIR. Returns whichever exists
|
||||
# (GL_BINDIR2 preferred if defined) or 0 if not found.
|
||||
# looks for a file in LOCAL_CODE or GL_BINDIR. Returns whichever exists
|
||||
# (LOCAL_CODE preferred if defined) or 0 if not found.
|
||||
my $file = shift;
|
||||
my $mode = shift; # could be 'x' or 'r'
|
||||
|
||||
my @files = ("$rc{GL_BINDIR}/$file");
|
||||
unshift @files, ("$rc{GL_BINDIR2}/$file") if $rc{GL_BINDIR2};
|
||||
unshift @files, ("$rc{LOCAL_CODE}/$file") if $rc{LOCAL_CODE};
|
||||
|
||||
for my $f ( @files ) {
|
||||
return $f if -x $f;
|
||||
|
|
Loading…
Reference in a new issue