some upgrade related fixups, plus a rule checking fixup
[gitolite-doc.git] / cookbook.mkd
blob61977fe79c8191e09aee8ce2d24ce81916ff8e35
1 <!-- options: toc -->
3 % gitolite cookbook
5 >   @@gray((a.k.a. "shut up with all the rambling and just tell me the bare
6 >   minimum I need to finish this!"))@@
8 include sidebar-toc
10 @@box-r(Note: This page has several [forward references][fr].  Skip it, or
11 maybe skim through it, on a first reading.  It's more of a "look at it when I
12 have a specific need" page anyway.)@@
14 Documentation is meant to be as complete as possible, which means it attempts
15 to cover all situations and scenarios.  That makes it harder to read.
17 However, if you make some assumptions, remove the rationale, justification,
18 exceptions and special cases, etc., and generally just say *what* is to be
19 done rather than explain *why*, many tasks can be described very easily.
21 Or, if the main documentation already does that, a cookbook may help you find
22 it faster, simply because it's organised differently.
24 Maybe this will help.  If you run into problems, please check the main
25 documentation before asking for help.
27 # administration {#cb-admin}
29 ## separating "key admin" from "repo admin"
31 In gitolite, the person who controls the keys is the most critical in terms of
32 security -- because he can always add his own key in your name :-)
34 .#d
36 .#! conf/vim-color
37     repo gitolite-admin
38         RW+ = key-manager repo-manager
40         RW+ VREF/NAME/                    = key-manager
41         -   VREF/NAME/keydir/             = @all
42         -   VREF/NAME/conf/gitolite.conf  = @all
44     include "actual.conf"
45 .end
47 .#d
49 Traditionally, the same person also administers repos and permissions.  But
50 sometimes you want to separate them.
52 To separate those roles, put the following in conf/gitolite.conf, and let the
53 repo-manager manage everything through "actual.conf":
55 .#t
57 # access {#cb-access}
59 ## looking up repo access from external tools
61 There are two supported interfaces for this, one in perl and one in shell.
62 Other languages should probably use the shell mode.  (The shell mode has a
63 very convenient "batch" mode if you need to check many repos at once).
65 **Perl interface**: A good intro to this, including a link to code, using
66 gitweb as an example can be found by looking for 'repo-specific authorisation
67 in gitweb' in the page on [allowing access to gitweb and
68 git-daemon][gitweb-daemon]. Some notes:
70   * be sure to read the comments in the code to learn exactly how to adapt it
71     to your needs
72   * in place of the `can_read` function in that code, you can of course use
73     `can_write`.  In fact, reading the comments in "Easy.pm" (look for it in
74     the source) shows you several other interesting tests you can make, like
75     `is_admin`, `in_group`, and `owns`.
77 **Shell interface**: If you want to do this from shell, it's even easier. The
78 same "Easy.pm" source contains comments that show shell equivalents for each
79 of the functions it exports, but here's a sample:
81     if gitolite access -q reponame username W
82     then
83         ...
85 You can even test for access to specific branches:
87     if gitolite access -q reponame username W master
88     then
89         ...
91 @@gray(If your gitolite is older than v3.6, you must use the full ref name;
92 just 'master' won't do.)@@
94 ## allowing access by other programs
96 Giving external tools (like apache) access to gitolite repositories involves
97 making sure that the unix owner/group and permissions settings allow this.
98 This is all described in the UMASK section in the page on the [rc file][rc],
99 because that's the only setting that gitolite controls; every thing else is
100 pure Unix.
102 # commands {#cb-commands}
104 ## adding your own commands
106 To add a command, say `foo`, do this:
108 1.  add this line in the rc file, within the `%RC` block, if it's not already
109     present, or uncomment it if it's already present and commented out:
111         LOCAL_CODE => "$ENV{HOME}/local",
113 2.  copy the program `foo` into `$HOME/local/commands`.  (Don't forget the
114     `chmod +x`!)
116 ## making commands available to remote users
118 Once you do the above, `foo` is available as `gitolite foo`.  To make it
119 available to remote users (as `ssh git@host foo`), add the line:
121     `foo`,
123 (including the comma at the end) to the ENABLE list in the rc file.
125 # hooks {#cb-hooks}
127 The main documentation for this feature starts [here][hooks].
129 ## adding your own update hooks
131 You have some update hooks (for example crlf checking) that you want to
132 include in gitolite.  Assuming the hook itself is tested and works as a normal
133 **git** update hook does (i.e., conforms to what `man githooks` says an update
134 hook should do), here's how to do this:
136 1.  add this line in the rc file, within the `%RC` block, if it's not already
137     present, or uncomment it if it's already present and commented out:
139         LOCAL_CODE => "$ENV{HOME}/local",
141 2.  copy your update hook to a subdirectory called VREF under this directory,
142     giving it a suitable name (let's say "crlf"):
144         # log on to server
145         cd $HOME
146         mkdir -p local/VREF
147         cp your-crlf-update-hook local/VREF/crlf
148         chmod +x local/VREF/crlf
150 3.  in your gitolite-admin clone, edit conf/gitolite.conf and
151     add lines like this:
153             -   VREF/crlf       =   @all
155     to each repo that should have that "update" hook.
157     Alternatively, you can simply add this at the end of the
158     gitolite.conf file:
159 .#! conf/vim-color
160         repo @all
161             -   VREF/crlf       =   @all
162 .end
164     Either way, add/commit/push the change to the gitolite-admin repo.
166 ## adding other (non-update) hooks
168 Say you want other hooks, like a post-receive hook.  Here's how:
170 1.  add this line in the rc file, within the `%RC` block, if it's not already
171     present, or uncomment it if it's already present and commented out:
173         LOCAL_CODE => "$ENV{HOME}/local",
175 2.  put your hooks into that directory, in a sub-sub-directory called
176     "hooks/common":
178         # log on to server
179         cd $HOME
180         mkdir -p local/hooks/common
181         cp your-post-receive-hook local/hooks/common/post-receive
182         chmod +x local/hooks/common/post-receive
184 3.  run `gitolite setup` to have the hooks propagate to existing repos (repos
185     created after this will get them anyway).
187 ## variation: maintain these hooks in the gitolite-admin repo
189 If you want to maintain these update hooks (VREFs) or non-update hooks
190 (post-update, pre-receive, post-receive) in the gitolite-admin repo, instead
191 of having to log on to the server and make changes, the procedure is almost
192 the same except for the following differences:
194 1.  add this line in the rc file, within the `%RC` block, if it's not already
195     present, or uncomment it if it's already present and commented out:
197         LOCAL_CODE => "$rc{GL_ADMIN_BASE}/local",
199     Notice "local" is *not* in \$HOME like in the previous examples!
201 2.  the hooks/scripts are to be added inside your gitolite-admin clone, not on
202     the server.  That is, whereever the above two sections say "cd \$HOME",
203     you should read it as "cd /path/to/your/gitolite-admin-clone".
205 3.  add/commit/push as usual.
207 For update hooks, you will of course need to add VREF rule lines to
208 appropriate repos in the conf file.  For non-update hooks, you **don't** need
209 to run 'gitolite setup' on the server; the push takes care of that.
211 ## @@gray((v3.6+))@@ variation: repo-specific hooks
213 Until now, the non-update hooks you specified apply to all repos.  Here's how
214 to apply them only to certain repos:
216 1.  add this line in the rc file, within the `%RC` block, if it's not already
217     present, or uncomment it if it's already present and commented out:
219         LOCAL_CODE => "$rc{GL_ADMIN_BASE}/local",
221 2.  uncomment the 'repo-specific-hooks' line in the rc file or add it to the
222     ENABLE list if it doesn't exist.
224     If your rc file does not have an ENABLE list, you need to add this to the
225     POST_COMPILE and the POST_CREATE lists.  Click [here][addtrig] for more on
226     all this.
228 3.  put your hooks into your gitolite-admin clone, as follows:
230         # on your workstation
231         cd /path/to/your/gitolite-admin-clone
232         mkdir -p local/hooks/repo-specific
234     Now add your hooks to that directory, but instead of using the git
235     "standard" names (pre-receive, post-receive, post-update), you use
236     descriptive names (e.g. "deploy", "RSS-post", etc).
238 4.  add them to the repos you want them to be active in, in your conf file.
239     For example:
241         repo foo
242             option hook.post-update     =   jenkins
243         repo bar @baz
244             option hook.post-update     =   deploy RSS-post
246 5.  add, commit, and push the admin repo.
248 # VREFs {#cb-vrefs}
250 ## adding your own VREFs
252 Adding VREFs is the same as adding the update hook, so please see the section
253 on "adding your own update hooks" above.
255 ## example VREFs
257 However, *writing* a proper VREF is not the same as writing a normal git
258 "update hook".  A proper VREF does more than just take 3 arguments, do
259 something, and exit with a non-zero exit code for failure.
261 A VREF is called with at least 4 more arguments after the 3 that git itself
262 defines for an update hook, plus usually at least one or two more.  It also
263 returns a lot more meaningful results via STDOUT.
265 Here are some examples.  I also advise you to keep a browser tab open to the
266 doc on [VREF arguments][vref-args] as you look at these.
268 ### example 1: restricting by day of week
270 Here's the conf extract to say "junior devs can only push on weekdays":
272 .#! conf/vim-color
273     repo foo
274         -   VREF/DAY/Sat    =   @junior-devs
275         -   VREF/DAY/Sun    =   @junior-devs
276 .end
278 The code for this VREF is ridiculously simple:
280 .#! conf/vim-color
281     #!/bin/bash
282     echo VREF/DAY/`date +%a`
283     # vim: set ft=sh
284 .end
286 On encountering the VREF rules (i.e., when a junior dev tries to access this
287 repo), gitolite calls the "DAY" VREF-maker.  The code within the VREF maker
288 simply echoes something like "VREF/DAY/Mon", where the last part is whatever
289 the actual day of the week happens to be.
291 This output is then treated as a virtual ref and matched against the rules.
292 On a Monday to Friday, nothing happens, because the VREFs generated do not
293 match any deny rules (or indeed any rules at all).  On weekends, they do
294 match, and the access is denied.
296 ### example 2: restricting by source IP address
298 This one restricts junior developers to access this repo only from a specific
299 network block.  The conf file here is slightly different.  We know that the
300 VREF-maker will return with *some* network address (as you'll see in the code
301 later), so we set it up so that the correct network block is allowed and
302 anything else is disallowed:
304 .#! conf/vim-color
305     repo foo
306         RW+ VREF/FROM/192.168.48.0/23   =   @junior-devs
307         -   VREF/FROM                   =   @junior-devs
308 .end
310 The code is not that complex.  We take the user's actual IP address (this is
311 available as the first word in `$SSH_CONNECTION` for ssh users, and for
312 smart-http users, gitolite fakes it and creates that variable!).  We then
313 treat the "23" in the VREF rule, which appears to the code as `$9`, as the
314 number of bits in the network address, then compute the network address for
315 the users IP with that number of bits.
317 This network address is then sent back.  (The `$9` is added back at the end,
318 but this is only to enable it to match the VREF rule).
320 .#! conf/vim-color
321     #!/bin/bash
323     # exit if no arguments were supplied to the VREF.  This covers the
324     # second VREF rule in the conf above
325     [ -n "$8" ] || exit 0
327     from=${SSH_CONNECTION%% *}
329     eval `ipcalc -n $from/$9`       # sets env var "NETWORK"
331     echo VREF/FROM/$NETWORK/$9
332     # vim: set ft=sh
333 .end
335 For a source IP of 192.168.49.97, this runs `ipcalc -n 192.168.49.97/23`,
336 which gives the network address 192.168.48.0.  The echo then just sends back
337 VREF/FROM/192.168.48.0/23.  This VREF matches the RW+ line.
339 But if the IP is, say, 192.168.45.67, running `ipcalc -n 192.168.45.67/23`
340 gives you 192.168.44.0.  The echo then send back VREF/FROM/192.18.44.0/23,
341 which won't match the RW+ line, but will match the next one and thus deny
342 access.
344 (One thing that may not be obvious in this specific example is that you have
345 to be careful when constructing the VREF rule.  For any VREF/FROM/A/B, the
346 result of running `ipcalc -n A/B` must be A, otherwise this won't work.  That
347 is, the bits of the network address after the network bits must be zero).
349 # wild repos
351 ## making exceptions for *specific* instances of a wild repo
353 Sometimes you want to specify rules or config for specific instances of a wild
354 repo, while still leaving it to be created by a user in the normal way.
356 This **will not** work:
358 .#! conf/vim-color
359     repo foo/..*
360         C                   =   blah blah
361         RW+                 =   CREATOR
362         RW                  =   WRITERS
363         R                   =   READERS
365     # this does NOT work
366     repo foo/special-1
367         RW+                 =   sitaram
368         option  foo.bar     =   baz
369 .end
371 The repo will be created as a **normal** (not wild) repo as soon as you push,
372 which means you can't run the [perms][] command on it to add people to the
373 READERS and WRITERS [roles][], or do other things that wild repos allow.
375 The mental nudge you need to deal with this is to think what you would do if
376 you had to write the same rule for more than one repo, say, any repo starting
377 with "foo/special-" followed by a number.  You'd use a pattern.  And a pattern
378 prevents an ordinary repo from being created.
380 So do this:
382 .#! conf/vim-color
383     # this will work
384     repo foo/special-[1]
385         RW+                 =   sitaram
386         option  foo.bar     =   baz
387 .end
389 Using a pattern for just one repo might sound like a kludge, but it's
390 perfectly valid and supported.
392 Note that you do NOT need a "C" rule in there, since the pattern is a subset
393 of the previous one (`foo/..*`), everything there applies to this repo also.
394 If you're not sure why that is, you may need to read up on [rule
395 accumulation][accum].
397 # moving stuff around {#cb-move}
399 ## moving a gitolite install from one machine to another
401 See [moving servers][moving].