misc
[gitolite-doc.git] / dev-notes.mkd
bloba511ed9c6590f17c5810168c9b8db6e1af4de907
1 <!-- options: toc -->
3 % writing your own "non-core" programs
5 include sidebar-toc
7 Gitolite has a huge bunch of existing features that gradually need to be moved
8 over.  Plus you may want to write your own programs to interact with it.
10 **This page is about *writing* hooks, commands, triggers, VREFS, and sugar
11 scripts.  *Installing* them, including "where and how", is described
12 [here][localcode]**.
14 Note: the [non-core][] page is the starting point for all information about
15 customising gitolite.
17 # environment variables and other inputs
19 In general, the following environment variables should always be available:
21     GL_BINDIR
22     GL_REPO_BASE
23     GL_ADMIN_BASE
25 `GL_BINDIR` is loosely equivalent to GIT\_EXEC\_PATH in git.  `GL_REPO_BASE`
26 is always \$HOME/repositories, and `GL_ADMIN_BASE` is \$HOME/.gitolite.  (You
27 might ask why, if they're fixed values, do we need those variables.  Good
28 question... next!)
30 In addition, commands invoked by a remote client also have `GL_USER`, while
31 hooks have `GL_USER` as well as `GL_REPO`.
33 A special form of the [option][options] syntax can be used to set
34 [repo-specific environment variables][rsev].
36 Finally, note that triggers get a lot of relevant information from gitolite as
37 arguments; see [here][triggers] for details.
39 # APIs
41 ## the shell API
43 The following commands exist to help you write shell scripts that interact
44 easily with gitolite.  Each of them responds to `-h` so please run that for
45 more info.
47   * `gitolite access` to check access rights given repo, user, type of access
48     (R, W, ...) and refname (optional).  Example use: src/commands/desc.
50   * `gitolite creator` to get/check the creator of a repo.  Example use:
51     src/commands/desc.
53   * `gitolite git-config` to check gitolite options or git config variables
54     directly from gitolite's "compiled" output, (i.e., without looking at the
55     actual `repo.git/config` file or using the `git config` command).  Example
56     use: src/triggers/post-compile/update-gitweb-access-list.
58   * `gitolite query-rc` to check the value of an RC variable.  Example use:
59     src/commands/desc.
61 In addition, you can also look at the comments in src/lib/Gitolite/Easy.pm
62 (the perl API module) for ideas.
64 ## the perl API
66 ...is implemented by Gitolite::Easy; the comments in src/lib/Gitolite/Easy.pm
67 serve as documentation.
69 Note that some of the perl functions called by Easy.pm will change the current
70 directory to something else, without saving and restoring the directory.
71 Patches (to Easy.pm *only*) welcome.
73 # writing your own...
75 ## ...commands
77 Commands are standalone programs, in any language you like.  They simply
78 receive the arguments you append.  In addition, the env var `GL_USER` is
79 available if it is being run remotely.  src/commands/desc is the best example
80 at present.
82 ## ...hooks
84 ### anything but the update hook
86 If you want to add any hook other than the update hook, 'man githooks' is all
87 you need.
89 ### update hook
91 If you want to add additional `update` hook functionality, do this:
93   * Write and test your update hook separately from gitolite.
95   * Now add the code as a VREF (see [here][localcode] for details).  Let's say
96     you called it "foo".
98     NOTE: if you don't care about all the extra stuff that VREFs give you over
99     a normal update hook, you don't have to read that page at all; just put
100     the code in the right place and go to the next step.
102   * To call your new update hook to all accesses for all repos, add this to
103     the end of your conf file:
104 .#! conf/vim-color
105         repo @all
106             -       VREF/foo        =   @all
107 .end
109 As you probably guessed, you can make your additional update hooks more
110 selective, applying them only to some repos / users / combinations.
112 Note: a normal update hook expects 3 arguments (ref, old SHA, new SHA).  A
113 VREF will get those three, followed by at least 4 more.  Your VREF should just
114 ignore the extra args.
116 ## ...trigger programs
118 Trigger programs run at specific points in gitolite's execution, with specific
119 arguments being passed to them.  See the [triggers][] page for details.
121 You can write programs that are both manually runnable as well as callable by
122 trigger events, especially if they don't *need* any arguments.
124 ## ..."sugar"
126 Syntactic sugar helpers are NOT complete, standalone, programs.  They must
127 include a perl sub called `sugar_script` that takes in a listref, and returns
128 a listref.  The listrefs point to a list that contains the entire conf file
129 (with all [include][] processing already done).  You create a new list with
130 contents modified as you like and return a ref to it.
132 There are a couple of examples in src/syntactic-sugar.
134 # appendix 1: repo-specific environment variables {#rsev}
136 A special form of the [option][options] syntax can be used to set
137 repo-specific environment variables that are visible to gitolite triggers and
138 any git hooks you may install.
140 For example, let's say you installed a post-update hook that initiates a CI
141 job.  By default, of course, this hook will be active for *all*
142 gitolite-managed repos.  However, you only want it to run for some specific
143 repos, say r1, r2, and r4.
145 To do that, first add this to the gitolite.conf:
147 .#! conf/vim-color
148     repo r1 r2 r4
149         option ENV.CI = 1
150 .end
152 This creates an environment variable called `GL_OPTION_CI` with the value 1,
153 before any trigger or hook is invoked.
155 Note: option names *must* start with `ENV.`, followed by a seqence of
156 characters composed of alphas, numbers, and the underscore character.
158 Now the hook running the CI job can easily decide what to do:
160     # exit if $GL_OPTION_CI is not set
161     [ -z $GL_OPTION_CI ] && exit
163     ... rest of CI job code as before ...
165 Of course you can also do the opposite; i.e. decide that the listed repos
166 should *not* run the CI job but all other repos should:
168 .#! conf/vim-color
169     repo @all
170         option ENV.CI = 1
172     repo r1 r2 r4
173         option ENV.CI = ""
174 .end
176 (The hook code remains the same as before.)
178 <font color="gray">Before this feature was added, you could still do this, by
179 using the `gitolite git-config` command inside the hook code to test for
180 options and configs set for the repo, like:
182     if gitolite git-config -q reponame gitolite-options.option-name
183     then
184         ...
186 The new method is much more convenient, as you can see.</font>
188 # appendix 2: log file format {#lff}
190 Here's a brief description of gitolite's log file format.  All fields are tab
191 separated.
193 There are two kinds of lines in the log file:
195   * third field non-empty: actual log lines.  These are documented below.
197   * third field empty (i.e., two tabs after the second field): extra output to
198     help diagnose problems. These are NOT documented and may change without
199     notice.  They can be turned off completely by setting the RC variable
200     `LOG_EXTRA` to 0.
202 For all types of log lines, the first two fields are:
204   * field 1: local time, in YYYY-MM-DD.HH:MM:SS format
206   * field 2: transaction ID or "TID".  This is actually the PID of the
207     outermost command that was initiated (usually "gitolite-shell").  It helps
208     to keep log lines pertaining to one "run" together, even if several
209     sub-commands are spawned (like for example from triggers, or even the
210     update hook itself).
212 The third and later fields are all dependent on what type of log line it is.
214 The various log line formats are:
216   * **start**
218     This line denotes the beginning of a gitolite operation.
220       * field 3: 'ssh' or 'http'
222       * field 4: `ARGV=<comma-separated list of command line arguments>`
224         Usually this is just the gitolite username (the argument to
225         gitolite-shell, as supplied by the forced command in the authorized
226         keys file).  If you're [giving shell access][giving-shell] to some
227         users, this would be "-s,username".  That's two command line arguments
228         ("-s" and the username), comma separated.
230       * field 5: `SOC=<original command from client>`
232         This is the command exactly as the git client sent it, or the user
233         typed it.  Typically this is one of these:
235             git-upload-pack 'reponame'
236             git-receive-pack 'reponame'
238         (including the single quotes, because that's what the client sent).
240         Gitolite commands are also recorded as is, so this could be something
241         like `info` or perhaps `perms -l reponame` etc.
243       * field 6: `FROM=<ip address>`
245   * **pre-git**
247     This log line appears when the first access check succeeds (i.e., before
248     git-upload-pack or git-receive-pack is called).
250       * field 3: 'pre\_git'
251       * field 4: reponame
252       * field 5: username
253       * field 6: 'R' or 'W'
254       * field 7: 'any'
255       * field 8: the refex that allowed access
257   * **update**
259     This log line appears when the second access check succeeds (i.e., when
260     the update hook decides to allow the push).
262       * field 3: 'update'
263       * field 4: reponame
264       * field 5: username
265       * field 6: 'W', '+', 'C', 'D', 'WM', '+M', 'CM', or 'DM'
266       * field 7: ref name (like 'refs/heads/master')
267       * field 8: old SHA
268       * field 9: new SHA
269       * field 10: the refex that allowed access
271     The values in field 6 reflect the possible [write types][write-types], but
272     note that there is a difference between what the log file contains and
273     what the gitolite.conf file contains (e.g., `+` versus `RW+`).  There's
274     another subtle difference for those who are not thinking clearly: the
275     `RW+` in the conf file is a permission, but it would show up as a `+` in
276     the log file only if an *actual* force push had happened, otherwise it
277     would be just `W`.
279     By the way, notice that fields 7 to 9 are exactly what git itself supplies
280     the update hook (see 'man githooks').
282     <font color="gray">There is a special version of this line that appears
283     when someone [bypasses][bypass] gitolite's access control to push directly
284     on the server.  The 'reponame' (field 4) is replaced by the full path of
285     the repo being pushed to, the username (field 5) is replaced by the Unix
286     userid in parentheses, and the operation code (field 6) is
287     'bypass'.</font>
289   * **create**
291     This log line appears when a wild repo was auto-created by a user.
293       * field 3: 'create'
294       * field 4: reponame
295       * field 5: username
296       * field 6: 'R' or 'W'
298     Field 6 is 'perms-c' if the wild repo is created using the perms command's
299     '-c' option.
301   * **end**
303     This indicates the end of the transaction.  Normally, you should not see
304     any more lines with the same TID after this line.
306       * field 3: 'END'
308   * **warnings** and **errors**
310     Typically seen when access is denied.
312       * field 3: 'warn' or 'die'
313       * field 4: message.  Parts of the message (like reponame, username, etc)
314         are not split out into fields, though.
316   * **cli**
318     This logs gitolite sub-commands run directly on the server, like `gitolite
319     setup` etc.
321       * field 3: 'cli'
322       * field 4: 'gitolite'
323       * field 5 to end: arguments supplied to gitolite command, one per field
325 # appendix 3: @@gray((v3.6.1+))@@ syslog
327 Gitolite allows you to send log entries to syslog.  To do that, uncomment one
328 of the commented out values for LOG\_DEST in the rc file.  If your rc file
329 does not have any such lines, add one of the following lines just after the
330 LOG\_EXTRA line:
332     # use this to log only to syslog
333     LOG_DEST                        => 'syslog',
335     # use this to log to syslog and the normal gitolite log
336     LOG_DEST                        => 'syslog,normal',
338 Please note:
340 *   The first two fields described in the previous section (time, TID) are
341     different.  Syslog takes care of putting in the time, and the TID is
342     appended to the ident, so instead of just 'gitolite', you get
343     'gitolite[$GL_TID]'.
345     This means actual log lines will look something like this, since syslog
346     appends the actual PID to the ident as well:
348         Jun  3 09:26:11 sita-lt gitolite[14950][14950]: ssh ARGV=admin  SOC=git-receive-pack 'gitolite-admin'   FROM=::1
349         Jun  3 09:26:11 sita-lt gitolite[14950][14950]: pre_git gitolite-admin  admin   W   any refs/.*
350         Jun  3 09:26:11 sita-lt gitolite[14950][14991]: update  gitolite-admin  admin   W   refs/heads/master   [snip]
351         Jun  3 09:26:13 sita-lt gitolite[14950][14950]: END
353 *   Normal log messages use the 'info' priority, while LOG\_EXTRA messages
354     (see previous section) use the 'debug' priority.
356     It may be useful to send the debug output to a different output file.
357     Unlike in the normal gitolite logs, where there is an extra tab character
358     (or, an empty field, depending on how you look at it), the syslog lines do
359     not let you easily distinguish between the main log lines and the
360     LOG\_EXTRA lines.