how did this H1 go missing?
[gitolite-doc.git] / docs / dev-notes.mkd
blobafe08435d0b5c4f094bd7c5651a682599698c28d
1 # writing your own "non-core" programs
3 ----
5 **This page is about *writing* hooks, commands, triggers, VREFS, and sugar
6 scripts.  *Installing* them, including "where and how", is described
7 [here][localcode]**.
9 [localcode]: non-core#for-your-non-core-programs
11 Note: the [non-core](non-core) page is the starting point for all information about
12 customising gitolite.
14 # environment variables and other inputs
16 In general, the following environment variables should always be available:
18     GL_BINDIR
19     GL_REPO_BASE
20     GL_ADMIN_BASE
22 `GL_BINDIR` is loosely equivalent to GIT\_EXEC\_PATH in git.  `GL_REPO_BASE`
23 is always `$HOME/repositories`, and `GL_ADMIN_BASE` is `$HOME/.gitolite`.
24 (You might ask why, if they're fixed values, do we need those variables.  Good
25 question... next!)
27 In addition, commands invoked by a remote client also have `GL_USER`, while
28 hooks have `GL_USER` as well as `GL_REPO` (which is the [logical
29 reponame][lrepo]).
31 [lrepo]: concepts#the-logical-repo-name
33 A special form of the [option](options) syntax can be used to set
34 [repo-specific environment variables][rsev].
36 [rsev]: dev-notes#appendix-1-repo-specific-environment-variables
38 Finally, note that triggers get a lot of relevant information from gitolite as
39 arguments; see [here](triggers) for details.
41 # APIs
43 ## the shell API
45 The following commands exist to help you write shell scripts that interact
46 easily with gitolite.  Each of them responds to `-h` so please run that for
47 more info.
49   * `gitolite access` to check access rights given repo, user, type of access
50     (R, W, ...) and refname (optional).  Example use: src/commands/desc.
52   * `gitolite creator` to get/check the creator of a repo.  Example use:
53     src/commands/desc.
55   * `gitolite git-config` to check gitolite options or git config variables
56     directly from gitolite's "compiled" output, (i.e., without looking at the
57     actual `repo.git/config` file or using the `git config` command).  Example
58     use: src/triggers/post-compile/update-gitweb-access-list.
60   * `gitolite query-rc` to check the value of an RC variable.  Example use:
61     src/commands/desc.
63 In addition, you can also look at the comments in src/lib/Gitolite/Easy.pm
64 (the perl API module) for ideas.
66 ## the perl API
68 ...is implemented by `Gitolite::Easy`; the comments in
69 src/lib/Gitolite/Easy.pm serve as documentation.
71 Note that some of the perl functions called by Easy.pm will change the current
72 directory to something else, without saving and restoring the directory.
73 Patches (to Easy.pm *only*) welcome.
75 # writing your own...
77 ## ...commands
79 Commands are standalone programs, in any language you like.  They simply
80 receive the arguments you append.  In addition, the env var `GL_USER` is
81 available if it is being run remotely.  src/commands/desc is the best example
82 at present.
84 ## ...hooks
86 ### anything but the update hook
88 If you want to add any hook other than the update hook, 'man githooks' is all
89 you need.
91 ### update hook
93 If you want to add additional `update` hook functionality, do this:
95   * Write and test your update hook separately from gitolite.
97   * Now add the code as a VREF (see [here][localcode] for details).  Let's say
98     you called it "foo".
100   * To call your new update hook to all accesses for all repos, add this to
101     the end of your conf file:
103     ```gitolite
104     repo @all
105         -       VREF/foo        =   @all
106     ```
108 As you probably guessed, you can make your additional update hooks more
109 selective, applying them only to some repos / users / combinations.
111 Note: a normal update hook expects 3 arguments (ref, old SHA, new SHA).  A
112 VREF will get those three, followed by at least 4 more.  Your VREF should just
113 ignore the extra args.
115 ## ...trigger programs
117 Trigger programs run at specific points in gitolite's execution, with specific
118 arguments being passed to them.  See the [triggers](triggers) page for details.
120 You can write programs that are both manually runnable as well as callable by
121 trigger events, especially if they don't *need* any arguments.
123 ## ..."sugar"
125 Syntactic sugar helpers are NOT complete, standalone, programs.  They must
126 include a perl sub called `sugar_script` that takes in a listref, and returns
127 a listref.  The listrefs point to a list that contains the entire conf file
128 (with all [include](conf#include-files) processing already done).  You create a new list with
129 contents modified as you like and return a ref to it.
131 There are a couple of examples in src/syntactic-sugar.
133 # appendix 1: repo-specific environment variables
135 A special form of the [option](options) syntax can be used to set
136 repo-specific environment variables that are visible to gitolite triggers and
137 any git hooks you may install.
139 For example, let's say you installed a post-update hook that initiates a CI
140 job.  By default, of course, this hook will be active for *all*
141 gitolite-managed repos.  However, you only want it to run for some specific
142 repos, say r1, r2, and r4.
144 To do that, first add this to the gitolite.conf:
146 ```gitolite
147 repo r1 r2 r4
148     option ENV.CI = 1
151 This creates an environment variable called `GL_OPTION_CI` with the value 1,
152 before any trigger or hook is invoked.
154 Note: option names *must* start with `ENV.`, followed by a seqence of
155 characters composed of alphas, numbers, and the underscore character.
157 Now the hook running the CI job can easily decide what to do:
159     # exit if $GL_OPTION_CI is not set
160     [ -z $GL_OPTION_CI ] && exit
162     ... rest of CI job code as before ...
164 Of course you can also do the opposite; i.e. decide that the listed repos
165 should *not* run the CI job but all other repos should:
167 ```gitolite
168 repo @all
169     option ENV.CI = 1
171 repo r1 r2 r4
172     option ENV.CI = ""
175 (The hook code remains the same as before.)
177 <font color="gray">Before this feature was added, you could still do this, by
178 using the `gitolite git-config` command inside the hook code to test for
179 options and configs set for the repo, like:
181     if gitolite git-config -q reponame gitolite-options.option-name
182     then
183         ...
185 The new method is much more convenient, as you can see.</font>
187 # appendix 2: log file format
189 Here's a brief description of gitolite's log file format.  All fields are tab
190 separated.
192 There are two kinds of lines in the log file:
194   * third field non-empty: actual log lines.  These are documented below.
196   * third field empty (i.e., two tabs after the second field): extra output to
197     help diagnose problems. These are NOT documented and may change without
198     notice.  They can be turned off completely by setting the RC variable
199     `LOG_EXTRA` to 0.
201 For all types of log lines, the first two fields are:
203   * field 1: local time, in `YYYY-MM-DD.HH:MM:SS` format
205   * field 2: transaction ID or "TID".  This is actually the PID of the
206     outermost command that was initiated (usually "gitolite-shell").  It helps
207     to keep log lines pertaining to one "run" together, even if several
208     sub-commands are spawned (like for example from triggers, or even the
209     update hook itself).
211 The third and later fields are all dependent on what type of log line it is.
213 The various log line formats are:
215   * **start**
217     This line denotes the beginning of a gitolite operation.
219       * field 3: 'ssh' or 'http'
221       * field 4: `ARGV=<comma-separated list of command line arguments>`
223         Usually this is just the gitolite username (the argument to
224         gitolite-shell, as supplied by the forced command in the authorized
225         keys file).  If you're [giving shell access][giving-shell] to some
226         users, this would be `-s,username`.  That's two command line arguments
227         ("-s" and the username), comma separated.
229       * field 5: `SOC=<original command from client>`
231         This is the command exactly as the git client sent it, or the user
232         typed it.  Typically this is one of these:
234             git-upload-pack 'reponame'
235             git-receive-pack 'reponame'
237         (including the single quotes, because that's what the client sent).
239         Gitolite commands are also recorded as is, so this could be something
240         like `info` or perhaps `perms -l reponame` etc.
242       * field 6: `FROM=<ip address>`
244   * **pre-git**
246     This log line appears when the first access check succeeds (i.e., before
247     git-upload-pack or git-receive-pack is called).
249       * field 3: 'pre\_git'
250       * field 4: reponame
251       * field 5: username
252       * field 6: 'R' or 'W'
253       * field 7: 'any'
254       * field 8: the refex that allowed access
256   * **update**
258     This log line appears when the second access check succeeds (i.e., when
259     the update hook decides to allow the push).
261       * field 3: 'update'
262       * field 4: reponame
263       * field 5: username
264       * field 6: 'W', '+', 'C', 'D', 'WM', '+M', 'CM', or 'DM'
265       * field 7: ref name (like 'refs/heads/master')
266       * field 8: old SHA
267       * field 9: new SHA
268       * field 10: the refex that allowed access
270     The values in field 6 reflect the possible [write types][write-types], but
271     note that there is a difference between what the log file contains and
272     what the gitolite.conf file contains (e.g., `+` versus `RW+`).  There's
273     another subtle difference for those who are not thinking clearly: the
274     `RW+` in the conf file is a permission, but it would show up as a `+` in
275     the log file only if an *actual* force push had happened, otherwise it
276     would be just `W`.
278     By the way, notice that fields 7 to 9 are exactly what git itself supplies
279     the update hook (see 'man githooks').
281     <font color="gray">There is a special version of this line that appears
282     when someone [bypasses][bypass] gitolite's access control to push directly
283     on the server.  The 'reponame' (field 4) is replaced by the full path of
284     the repo being pushed to, the username (field 5) is replaced by the Unix
285     userid in parentheses, and the operation code (field 6) is
286     'bypass'.</font>
288   * **create**
290     This log line appears when a wild repo was auto-created by a user.
292       * field 3: 'create'
293       * field 4: reponame
294       * field 5: username
295       * field 6: 'R' or 'W'
297     Field 6 is 'perms-c' if the wild repo is created using the perms command's
298     '-c' option.
300   * **end**
302     This indicates the end of the transaction.  Normally, you should not see
303     any more lines with the same TID after this line.
305       * field 3: 'END'
307   * **warnings** and **errors**
309     Typically seen when access is denied.
311       * field 3: 'warn' or 'die'
312       * field 4: message.  Parts of the message (like reponame, username, etc)
313         are not split out into fields, though.
315   * **cli**
317     This logs gitolite sub-commands run directly on the server, like `gitolite
318     setup` etc.
320       * field 3: 'cli'
321       * field 4: 'gitolite'
322       * field 5 to end: arguments supplied to gitolite command, one per field
324 [giving-shell]: sts#giving-shell-access-to-gitolite-users
325 [write-types]: conf-2#appendix-1-different-types-of-write-operations
326 [bypass]: emergencies#bypassing-gitolite
328 # appendix 3: sending log lines to syslog
330 Gitolite allows you to send log entries to syslog.  To do that, uncomment one
331 of the commented out values for LOG\_DEST in the rc file.  If your rc file
332 does not have any such lines, add one of the following lines just after the
333 LOG\_EXTRA line:
335     # use this to log only to syslog
336     LOG_DEST                        => 'syslog',
338     # use this to log to syslog and the normal gitolite log
339     LOG_DEST                        => 'syslog,normal',
341 Please note:
343 *   The first two fields described in the previous section (time, TID) are
344     different.  Syslog takes care of putting in the time, and the TID is
345     appended to the ident, so instead of just 'gitolite', you get
346     'gitolite[$GL_TID]'.
348     This means actual log lines will look something like this, since syslog
349     appends the actual PID to the ident as well:
351         Jun  3 09:26:11 sita-lt gitolite[14950][14950]: ssh ARGV=admin  SOC=git-receive-pack 'gitolite-admin'   FROM=::1
352         Jun  3 09:26:11 sita-lt gitolite[14950][14950]: pre_git gitolite-admin  admin   W   any refs/.*
353         Jun  3 09:26:11 sita-lt gitolite[14950][14991]: update  gitolite-admin  admin   W   refs/heads/master   [snip]
354         Jun  3 09:26:13 sita-lt gitolite[14950][14950]: END
356 *   Normal log messages use the 'info' priority, while LOG\_EXTRA messages
357     (see previous section) use the 'debug' priority.
359     It may be useful to send the debug output to a different output file.
360     Unlike in the normal gitolite logs, where there is an extra tab character
361     (or, an empty field, depending on how you look at it), the syslog lines do
362     not let you easily distinguish between the main log lines and the
363     LOG\_EXTRA lines.