nosync-quiet option added courtesy Robin Johnson (Gentoo project)
[gitolite-doc.git] / docs / cookbook.mkd
blobd890805eb8f2a2b18fec066a3f401f87a930de56
1 # gitolite cookbook
3 <center>(a.k.a. "stop all that rambling and just tell me what I need to do!")</center>
5 ----
7 Documentation is meant to be as complete as possible, which means it attempts
8 to cover all situations and scenarios.  That makes it harder to read.
10 However, if you make some assumptions, remove the rationale, justification,
11 exceptions and special cases, etc., and generally just say *what* is to be
12 done rather than explain *why*, many tasks can be described very easily.
14 Or, if the main documentation already does that, a cookbook may help you find
15 it faster, simply because it's organised differently.
17 Maybe this will help.  If you run into problems, please check the main
18 documentation before asking for help.
20 # administration
22 ## separating "key admin" from "repo admin"
24 In gitolite, the person who controls the keys is the most critical in terms of
25 security -- because he can always add his own key in your name :-)
27 Traditionally, the same person also administers repos and permissions.  But
28 sometimes you want to separate them.
30 To separate those roles, put the following in conf/gitolite.conf, and let the
31 repo-manager manage everything through "actual.conf":
33 ```gitolite
34 repo gitolite-admin
35     RW+ = key-manager repo-manager
37     RW+ VREF/NAME/                    = key-manager
38     -   VREF/NAME/keydir/             = @all
39     -   VREF/NAME/conf/gitolite.conf  = @all
41 include "actual.conf"
42 ```
44 # access
46 ## looking up repo access from external tools
48 There are two supported interfaces for this, one in perl and one in shell.
49 Other languages should probably use the shell mode.  (The shell mode has a
50 very convenient "batch" mode if you need to check many repos at once).
52 **Perl interface**: A good intro to this, including a link to code, using
53 gitweb as an example can be found by looking for 'repo-specific authorisation
54 in gitweb' in the page on [allowing access to gitweb and
55 git-daemon](gitweb-daemon). Some notes:
57   * be sure to read the comments in the code to learn exactly how to adapt it
58     to your needs
59   * in place of the `can_read` function in that code, you can of course use
60     `can_write`.  In fact, reading the comments in "Easy.pm" (look for it in
61     the source) shows you several other interesting tests you can make, like
62     `is_admin`, `in_group`, and `owns`.
64 **Shell interface**: If you want to do this from shell, it's even easier. The
65 same "Easy.pm" source contains comments that show shell equivalents for each
66 of the functions it exports, but here's a sample:
68     if gitolite access -q reponame username W
69     then
70         ...
72 You can even test for access to specific branches:
74     if gitolite access -q reponame username W master
75     then
76         ...
78 <span class="gray">If your gitolite is older than v3.6, you must use the full ref name;
79 just 'master' won't do.</span>
81 ## allowing access by other programs
83 Giving external tools (like apache) access to gitolite repositories involves
84 making sure that the unix owner/group and permissions settings allow this.
85 This is all described in the UMASK section in the page on the [rc file](rc),
86 because that's the only setting that gitolite controls; every thing else is
87 pure Unix.
89 # commands
91 ## adding your own commands
93 To add a command, say `foo`, do this:
95 1.  add this line in the rc file, within the `%RC` block, if it's not already
96     present, or uncomment it if it's already present and commented out:
98         LOCAL_CODE => "$ENV{HOME}/local",
100 2.  copy the program `foo` into `$HOME/local/commands`.  (Don't forget the
101     `chmod +x`!)
103 ## making commands available to remote users
105 Once you do the above, `foo` is available as `gitolite foo`.  To make it
106 available to remote users (as `ssh git@host foo`), add the line:
108     `foo`,
110 (including the comma at the end) to the ENABLE list in the rc file.
112 # hooks
114 Note: the main documentation for this feature starts [here][hooks].
116 [hooks]: non-core#hooks-and-gitolite
118 ## adding your own update hooks
120 You have some update hooks (for example crlf checking) that you want to
121 include in gitolite.  Assuming the hook itself is tested and works as a normal
122 **git** update hook does (i.e., conforms to what `man githooks` says an update
123 hook should do), here's how to do this:
125 1.  add this line in the rc file, within the `%RC` block, if it's not already
126     present, or uncomment it if it's already present and commented out:
128         LOCAL_CODE => "$ENV{HOME}/local",
130 2.  copy your update hook to a subdirectory called VREF under this directory,
131     giving it a suitable name (let's say "crlf"):
133         # log on to gitolite hosting user on the server, then:
134         cd $HOME
135         mkdir -p local/VREF
136         cp your-crlf-update-hook local/VREF/crlf
137         chmod +x local/VREF/crlf
139 3.  in your gitolite-admin clone, edit conf/gitolite.conf and
140     add lines like this:
142             -   VREF/crlf       =   @all
144     to each repo that should have that "update" hook.
146     Alternatively, you can simply add this at the end of the
147     gitolite.conf file:
149     ```gitolite
150     repo @all
151         -   VREF/crlf       =   @all
152     ```
154     Either way, add/commit/push the change to the gitolite-admin repo.
156 ## adding other (non-update) hooks
158 Say you want other hooks, like a post-receive hook.  Here's how:
160 1.  add this line in the rc file, within the `%RC` block, if it's not already
161     present, or uncomment it if it's already present and commented out:
163         LOCAL_CODE => "$ENV{HOME}/local",
165 2.  put your hooks into that directory, in a sub-sub-directory called
166     "hooks/common":
168         # log on to gitolite hosting user on the server, then:
169         cd $HOME
170         mkdir -p local/hooks/common
171         cp your-post-receive-hook local/hooks/common/post-receive
172         chmod +x local/hooks/common/post-receive
174 3.  run `gitolite setup` to have the hooks propagate to existing repos (repos
175     created after this will get them anyway).
177 ## variation: maintain these hooks in the gitolite-admin repo
179 !!! danger "Important security note:"
181     **If you enable this, anyone who can push changes to the admin repo will
182     effectively be able to run any arbitrary command on the server.**  See
183     [gitolite admin and shell access][privesc] for more background.
185 [privesc]: rc#security-note-gitolite-admin-and-shell-access
187 If you want to maintain these update hooks (VREFs) or non-update hooks
188 (post-update, pre-receive, post-receive) in the gitolite-admin repo, instead
189 of having to log on to the server and make changes, the procedure is almost
190 the same except for the following differences:
192 1.  add this line in the rc file, within the `%RC` block, if it's not already
193     present, or uncomment it if it's already present and commented out:
195         LOCAL_CODE => "$rc{GL_ADMIN_BASE}/local",
197     Notice "local" is *not* in `$HOME` like in the previous examples!
199 2.  the hooks/scripts are to be added inside your gitolite-admin clone, not on
200     the server.  That is, whereever the above two sections say `cd $HOME`,
201     you should read it as "cd /path/to/your/gitolite-admin-clone".
203     (The directory `local` will be within this clone of course, not in
204     `$HOME`.)
206 3.  add/commit/push as usual.
208 For update hooks, you will of course need to add VREF rule lines to
209 appropriate repos in the conf file.  For non-update hooks, you **don't** need
210 to run 'gitolite setup' on the server; the push takes care of that.
212 ## <span class="gray">(v3.6+)</span> variation: repo-specific hooks
214 Until now, the non-update hooks you specified apply to all repos.  Here's how
215 to apply them only to certain repos:
217 1.  add this line in the rc file, within the `%RC` block, if it's not already
218     present, or uncomment it if it's already present and commented out:
220         LOCAL_CODE => "$rc{GL_ADMIN_BASE}/local",
222 2.  uncomment the 'repo-specific-hooks' line in the rc file or add it to the
223     ENABLE list if it doesn't exist.
225     If your rc file does not have an ENABLE list, you need to add this to the
226     POST_COMPILE and the POST_CREATE lists.  Click [here][addtrig] for more on
227     all this.
229 3.  put your hooks into your gitolite-admin clone, as follows:
231         # on your workstation
232         cd /path/to/your/gitolite-admin-clone
233         mkdir -p local/hooks/repo-specific
235     Now add your hooks to that directory, but instead of using the git
236     "standard" names (pre-receive, post-receive, post-update), you use
237     descriptive names (e.g. "deploy", "RSS-post", etc).
239     **For pre-receive or pre-auto-gc you should not use more than one hook.
240     If you really need more than one, ask on the mailing list.**
243 4.  add them to the repos you want them to be active in, in your conf file.
244     For example:
246         repo foo
247             option hook.post-update     =   jenkins
248         repo bar @baz
249             option hook.post-update     =   deploy RSS-post
251 5.  add, commit, and push the admin repo.
253 [addtrig]: triggers#adding-your-own-scripts-to-a-trigger
254 [addtrigp]: triggers#adding-a-perl-module-as-a-trigger
256 # triggers
258 ## adding your own triggers
260 First, write your trigger code, using the documentation [here](triggers).
261 Note especially the sections "common arguments" and "trigger-specific
262 arguments".  Look in the shipped triggers for ideas.
264 !!! danger "Note:"
266     If your trigger is a perl module, as opposed to a standalone script or
267     executable, please see the section on [adding a perl module as a
268     trigger][addtrigp].
270 Let's say your trigger is called `foo`, and it will be a `PRE_GIT` trigger.
272 1.  add this line in the rc file, within the `%RC` block, if it's not already
273     present, or uncomment it if it's already present and commented out:
275         LOCAL_CODE => "$ENV{HOME}/local",
277 2.  copy the program `foo` into `$HOME/local/triggers`.  (Don't forget the
278     `chmod +x`!)
280 3.  edit `~/.gitolite.rc` again, and look for a `PRE_GIT` section.  If it
281     exists, add `'foo',` (note the trailing comma!) to it.  If it does not
282     exist, add this block just before the `ENABLE` section:
284         PRE_GIT =>
285         [
286             'foo'
287         ],
289     (again, note the trailing comma at the end of the block!)
291     After saving the file, test that this worked by running `gitolite query-rc PRE_GIT`;
292     your `foo` should be in the output list.  If it's not, back up
293     and double check your work.
295 That should be it.
297 # VREFs
299 ## adding your own VREFs
301 Adding VREFs is the same as adding the update hook, so please see the section
302 on "adding your own update hooks" above.
304 ## example VREFs
306 However, *writing* a proper VREF is not the same as writing a normal git
307 "update hook".  A proper VREF does more than just take 3 arguments, do
308 something, and exit with a non-zero exit code for failure.
310 A VREF is called with at least 4 more arguments after the 3 that git itself
311 defines for an update hook, plus usually at least one or two more.  It also
312 returns a lot more meaningful results via STDOUT.
314 Here are some examples.  I also advise you to keep a browser tab open to the
315 doc on [VREF arguments][vref-args] as you look at these.
317 !!! danger "Important:"
319     **VREFs only come into play for push operations.  When we say "access" in
320     this section, we mean only write access.**  If you want to restrict it
321     even for reads, you can do this in a `PRE_GIT` trigger; there's an example
322     in `contrib/triggers/IP-check` in the gitolite source tree that may be
323     useful as a template.
325 [vref-args]: vref#what-arguments-are-passed-to-the-vref-maker
327 ### example 1: restricting by day of week
329 Here's the conf extract to say "junior devs can only push on weekdays":
331 ```gitolite
332 repo foo
333     -   VREF/DAY/Sat    =   @junior-devs
334     -   VREF/DAY/Sun    =   @junior-devs
337 The code for this VREF is ridiculously simple:
339 ```sh
340 #!/bin/bash
341 echo VREF/DAY/`date +%a`
344 On encountering the VREF rules (i.e., when a junior dev tries to push to this
345 repo), gitolite calls the "DAY" VREF-maker.  The code within the VREF maker
346 simply echoes something like "VREF/DAY/Mon", where the last part is whatever
347 the actual day of the week happens to be.
349 This output is then treated as a virtual ref and matched against the rules.
350 On a Monday to Friday, nothing happens, because the VREFs generated do not
351 match any deny rules (or indeed any rules at all).  On weekends, they do
352 match, and the push is denied.
354 ### example 2: restricting by source IP address
356 This one restricts junior developers to push to this repo only from a specific
357 network block.  The conf file here is slightly different.  We know that the
358 VREF-maker will return with *some* network address (as you'll see in the code
359 later), so we set it up so that the correct network block is allowed and
360 anything else is disallowed:
362 ```gitolite
363 repo foo
364     RW+ VREF/FROM/192.168.48.0/23   =   @junior-devs
365     -   VREF/FROM                   =   @junior-devs
368 The code is not that complex.  We take the user's actual IP address (this is
369 available as the first word in `$SSH_CONNECTION` for ssh users, and for
370 smart-http users, gitolite fakes it and creates that variable!).  We then
371 treat the "23" in the VREF rule, which appears to the code as `$9`, as the
372 number of bits in the network address, then compute the network address for
373 the users IP with that number of bits.
375 This network address is then sent back.  (The `$9` is added back at the end,
376 but this is only to enable it to match the VREF rule).
378 ```sh
379 #!/bin/bash
381 # exit if no arguments were supplied to the VREF.  This covers the
382 # second VREF rule in the conf above
383 [ -n "$8" ] || exit 0
385 from=${SSH_CONNECTION%% *}
387 eval `ipcalc -n $from/$9`       # sets env var "NETWORK"
389 echo VREF/FROM/$NETWORK/$9
392 For a source IP of 192.168.49.97, this runs `ipcalc -n 192.168.49.97/23`,
393 which gives the network address 192.168.48.0.  The echo then just sends back
394 VREF/FROM/192.168.48.0/23.  This VREF matches the RW+ line.
396 But if the IP is, say, 192.168.45.67, running `ipcalc -n 192.168.45.67/23`
397 gives you 192.168.44.0.  The echo then send back VREF/FROM/192.18.44.0/23,
398 which won't match the RW+ line, but will match the next one and thus deny
399 the push.
401 (One thing that may not be obvious in this specific example is that you have
402 to be careful when constructing the VREF rule.  For any VREF/FROM/A/B, the
403 result of running `ipcalc -n A/B` must be A, otherwise this won't work.  That
404 is, the bits of the network address after the network bits must be zero).
406 # wild repos
408 ## making exceptions for *specific* instances of a wild repo
410 Sometimes you want to specify rules or config for specific instances of a wild
411 repo, while still leaving it to be created by a user in the normal way.
413 This **will not** work:
415 ```gitolite
416 repo foo/..*
417     C                   =   blah blah
418     RW+                 =   CREATOR
419     RW                  =   WRITERS
420     R                   =   READERS
422 # this does NOT work
423 repo foo/special-1
424     RW+                 =   sitaram
425     option  foo.bar     =   baz
428 The repo will be created as a **normal** (not wild) repo as soon as you push,
429 which means you can't run the [perms][] command on it to add people to the
430 READERS and WRITERS [roles][], or do other things that wild repos allow.
432 [perms]: user#setget-additional-permissions-for-repos-you-created
433 [roles]: wild#roles
435 The mental nudge you need to deal with this is to think what you would do if
436 you had to write the same rule for more than one repo, say, any repo starting
437 with "foo/special-" followed by a number.  You'd use a pattern.  And a pattern
438 prevents an ordinary repo from being created.
440 So do this:
442 ```gitolite
443 # this will work
444 repo foo/special-[1]
445     RW+                 =   sitaram
446     option  foo.bar     =   baz
449 Using a pattern for just one repo might sound like a kludge, but it's
450 perfectly valid and supported.
452 Note that you do NOT need a "C" rule in there, since the pattern is a subset
453 of the previous one (`foo/..*`), everything there applies to this repo also.
454 If you're not sure why that is, you may need to read up on [rule
455 accumulation][accum].
457 [accum]: conf#rule-accumulation
459 # moving stuff around
461 ## moving a gitolite install from one machine to another
463 [moving]: install#moving-servers
465 See [moving servers][moving].