Web Status

Jinja Web Templates

Buildbot uses Jinja2 to render its web interface. The authoritative source for this templating engine is its own documentation, of course, but a few notes are in order for those who are making only minor modifications.

Whitespace

Jinja directives are enclosed in {% .. %}, and sometimes also have dashes. These dashes strip whitespace in the output. For example:

{% for entry in entries %}
  <li>{{ entry }}</li>
{% endfor %}

will produce output with too much whitespace:

<li>pigs</li>


<li>cows</li>

But adding the dashes will collapse that whitespace completely:

{% for entry in entries -%}
  <li>{{ entry }}</li>
{%- endfor %}

yields

<li>pigs</li><li>cows</li>

Web Authorization Framework

Whenever any part of the web framework wants to perform some action on the buildmaster, it should check the user's authorization first.

Always check authorization twice: once to decide whether to show the option to the user (link, button, form, whatever); and once before actually performing the action.

To check whether to display the option, you'll usually want to pass an authz object to the Jinja template in your HtmlResource subclass:

def content(self, req, cxt):
    # ...
    cxt['authz'] = self.getAuthz(req)
    template = ...
    return template.render(**cxt)

and then determine whether to advertise the action in the template:

{{ if authz.advertiseAction('myNewTrick') }}
  <form action="{{ myNewTrick_url }}"> ...
{{ endif }}

Actions can optionally require authentication, so use needAuthForm to determine whether to require a 'username' and 'passwd' field in the generated form. These fields are usually generated by authFormIfNeeded:

{{ authFormIfNeeded(authz, 'myNewTrick') }}

Once the POST request comes in, it's time to check authorization again. This usually looks something like

res = yield self.getAuthz(req).actionAllowed('myNewTrick', req, someExtraArg)
if not res:
    defer.returnValue(Redirect(path_to_authfail(req)))
    return

The someExtraArg is optional (it's handled with *args, so you can have several if you want), and is given to the user's authorization function. For example, a build-related action should pass the build status, so that the user's authorization function could ensure that devs can only operate on their own builds.

Note that actionAllowed returns a Deferred instance, so you must wait for the Deferred and yield the Redirect instead of returning it.

The available actions are described in WebStatus.