LegNeato! Christian Legnitto's blog about Mozilla, Apple, technology, and random stuff

29Jul/11Off

Announcing mediawiki-bugzilla, a MediaWiki extension to embed bug data

Do you use wiki pages to track things? Tired of copy and pasting bugzilla queries and bug information? Me too. I got fed up one day and decided to do something about it and the result is mediawiki-bugzilla.

What is mediawiki-bugzilla?

It is a server-side MediaWiki extension that provides read-only access to the Bugzilla REST API. It's basically a working proof of concept at this point but I will be beefing it up in the coming weeks.

Why did I write my own MediaWiki extension?

I deal with wiki pages, bugs, and triage daily. It seemed stupid to be copying data and sometimes I wanted to embed up-to-date bug information in various wiki pages. I looked for solutions and found the excellent Bugzilla Reports extension. Unfortunately, it didn't fit my needs:

  • Bugzilla Reports needs direct access to the Bugzilla database. Yikes! Not only would I not get that access that would mean we would have to security audit the whole thing. Also, it was unclear that the assorted groups and permissions could be preserved across queries
  • The specification/query language was homegrown. In addition to wiki markup one had to take time to learn how to tune and use a specification unique to Bugzilla Reports
  • I'm not the best PHP programmer in the world but the code seemed overly complex and was difficult to dive into

I actually hacked together a proof-of-concept backend to have Bugzilla Reports query the Bugzilla REST API instead of the database but it didn't work quite right and wasn't maintainable.

I wanted to make an extension that is painless to use, easy to develop, and has no possible way of exposing restricted bugs. I didn't want to create my own query specification / format, so I piggybacked off Gerv's excellent Bugzilla REST API. The extension is basically an easy way to make REST API calls from MediaWiki so the docs can be used for the extension as well.

How to use mediawiki-bugzilla

You essentially use this extension in this way:

<bugzilla>
(JSON REST API query key/value pairs)
</bugzilla>

For example, the following would be used to get all P1 bugs in the Bugzilla product:

<bugzilla>
{
"product": "Bugzilla",
"priority":"P1"
}
</bugzilla>

Notice that this is the same example used in the Bugzilla REST API documentation. Any query you can do via the API you should be able to embed in a wiki page using this extension.

I also stubbed out support for charting using the Google Charts API:

<bugzilla type="count" display="bar">
{
"product":      "Bugzilla",
"priority":     "P1",
"x_axis_field": "severity"
}
</bugzilla>

If you put both of the above examples into a wiki page you get something like this:

I know the tables aren't styled yet. I'm going to be using jquery UI + the datatable plugin, with a pref to fall back to standard HTML tables without javascript.

All this info (and more!) can be found in the README.

Next steps

The major thing I am going to add is caching of the queries every 5 minutes or so while allowing manual cache overriding. This should make it so 50 people loading a wiki page with 10 queries at the same time doesn't overwhelm Bugzilla.

After that I will beef up the charting and add some docs. Then we'll get this rolled out on wiki.mozilla.org!

As always, patches welcome. The code is very simple and it should be very easy to add new features as there aren't really any right now.

27Dec/10Off

Python library for Bugzilla’s REST API

I am now maintaining a python library (originally written by Jeff Balogh) for interacting with Bugzilla via the the REST API. You can get it from:

https://github.com/LegNeato/bztools

Check out the README for a simple example of how to use the library. You can also take a look at the scripts at http://hg.mozilla.org/users/clegnitto_mozilla.com/release_tools for some more advanced uses.

Some features:

  • Supports authentication (with credentials stored in the system keychain with a config file fallback)
  • Supports querying the API via agents with optional query options, so you can include/exclude what you need
  • Support for Bugs, Users, Attachments, Comments, Changes, Changesets, Flags, Keyword. Dependency support will be working shortly as well
  • Supports common set and equality operations for objects. For example, looping through a list of Bug objects:
    for bug in buglist:
      print bug
    

    Checking if a Bug object is in a list of Bugs:

    if bug in buglist:
      print "Found!"
    

    Adding sets of bugs together into one large set:

    all_bugs = buglist1 + buglist2 + buglist3
    

    Checking if two User objects are the same:

    if bug.assigned_to == bug.reporter:
      print "Assigned to the reporter!"

The library has really cleaned up my scripts and has been insanely useful. Thanks to Jeff for creating such a nice library and letting me take it over and improve it.

23Nov/10Off

GitHub AMQP integration service hook live!

As of last night you can now send AMQP messages to a message broker (like the one running on pulse.mozilla.org) for GitHub pushes and commits!

Here's how to set it up...

First, go to the admin area of one of your repositories:

Next click on "Service Hooks" on the left hand side:

After that, select the AMQP service hook:

Configure the hook to point at your server and it's done!

Once configured, the next time you push there will be messages sent via AMQP to your server from GitHub. Currently, it sends one overall push message containing all changeset info in the push as well as individual changeset messages.

Mesages are sent for the push with the following routing key format:

"github.push.#{owner}.#{repo}.#{ref}"

where:

owner = payload['repository']['owner']['name']
repo  = payload['repository']['name']
ref   = payload['ref_name']

Messages are also sent for each commit in a push, with the following routing key format:

"github.commit.#{owner}.#{repo}.#{ref}.#{author}"

where:

author = commit['author']['email']
(other fields are the same as above)

The message data is sent in JSON format.

Here's an example commit message (dumped from Python):

{u'_meta': {u'exchange': u'org.mozilla.exchange.pulse.test',
 u'routing_key': u'github.commit.LegNeato.bztools.master.clegnitto@mozilla.com'},
 u'payload': {u'author': {u'email': u'clegnitto@mozilla.com',
 u'name': u'Christian Legnitto',
 u'username': u'LegNeato'},
 u'files': {u'added': [],
 u'modified': [u'README.rst'],
 u'removed': []},
 u'id': u'4d69ae955e6f877000ecfe17def333b32973070b',
 u'message': u'Change readme to point to my repo (and a test of AMQP GitHub service hook)',
 u'timestamp': u'2010-11-22T15:16:26-08:00',
 u'url': u'https://github.com/LegNeato/bztools/commit/4d69ae955e6f877000ecfe17def333b32973070b'}}

And here's an example push message (dumped from Python):

{u'_meta': {u'exchange': u'org.mozilla.exchange.pulse.test',
 u'routing_key': u'github.push.LegNeato.bztools.master'},
 u'payload': {u'after': u'0ccf64aa593e96a19529b9c9a3b1e0098c626108',
 u'before': u'9aa20993159d5e714103abc6741b43feb371fc34',
 u'commits': [{u'author': {u'email': u'clegnitto@mozilla.com',
 u'name': u'Christian Legnitto',
 u'username': u'LegNeato'},
 u'files': {u'added': [],
 u'modified': [u'bugzilla/models.py'],
 u'removed': []},
 u'id': u'80539c359d22ca35f61c34edb810bfc9c0bef6a8',
 u'message': u'Add support for keywords',
 u'timestamp': u'2010-11-17T16:14:37-08:00',
 u'url': u'https://github.com/LegNeato/bztools/commit/80539c359d22ca35f61c34edb810bfc9c0bef6a8'},
 {u'author': {u'email': u'clegnitto@mozilla.com',
 u'name': u'Christian Legnitto',
 u'username': u'LegNeato'},
 u'files': {u'added': [],
 u'modified': [u'README.rst'],
 u'removed': []},
 u'id': u'4d69ae955e6f877000ecfe17def333b32973070b',
 u'message': u'Change readme to point to my repo (and a test of AMQP GitHub service hook)',
 u'timestamp': u'2010-11-22T15:16:26-08:00',
 u'url': u'https://github.com/LegNeato/bztools/commit/4d69ae955e6f877000ecfe17def333b32973070b'},
 {u'author': {u'email': u'clegnitto@mozilla.com',
 u'name': u'Christian Legnitto',
 u'username': u'LegNeato'},
 u'files': {u'added': [],
 u'modified': [u'bugzilla/models.py'],
 u'removed': []},
 u'id': u'0ccf64aa593e96a19529b9c9a3b1e0098c626108',
 u'message': u'Add some string representations',
 u'timestamp': u'2010-11-22T18:19:32-08:00',
 u'url': u'https://github.com/LegNeato/bztools/commit/0ccf64aa593e96a19529b9c9a3b1e0098c626108'}],
 u'compare': u'https://github.com/LegNeato/bztools/compare/9aa2099...0ccf64a',
 u'forced': False,
 u'ref': u'refs/heads/master',
 u'ref_name': u'master',
 u'repository': {u'created_at': u'2010/11/15 14:45:56 -0800',
 u'description': u'Models and scripts to access the Bugzilla REST API.',
 u'fork': True,
 u'forks': 0,
 u'has_downloads': True,
 u'has_issues': False,
 u'has_wiki': True,
 u'homepage': u'',
 u'name': u'bztools',
 u'open_issues': 0,
 u'owner': {u'email': u'clegnitto@mozilla.com',
 u'name': u'LegNeato'},
 u'private': False,
 u'pushed_at': u'2010/11/22 19:17:25 -0800',
 u'url': u'https://github.com/LegNeato/bztools',
 u'watchers': 2}}}

Now that this service exists Pulse can get messages about Mozilla checkins for projects hosted on GitHub, making Pulse the one-stop shop for real-time Mozilla data...once the Bugzilla extension, MediaWiki extension, and Mercurial extension are put into production of course.

10Sep/10Off

bugzilla-amqp is now buzgilla-push, supports the STOMP protocol

The Bugzilla server-side extension I released previously has been renamed to bugzilla-push. It can now be found at http://github.com/LegNeato/bugzilla-push. The main impetus for the name change was that it now supports STOMP in addition to AMQP. It seemed silly to keep "amqp" in the name when it supports multiple protocols.

The reason for adding STOMP support is to keep my message broker options open. While RabbitMQ is pretty nice, it may not meet the needs for pulse.mozilla.org once it gets out of prototype mode. All open source brokers (HornetQ, Apache ActiveMQ & Qpid, Redhat MRG, etc) have pledged to support AMQP eventually, but many have not implemented it. Most have implemented STOMP though, as the protocol is both stable and simple. The extension now gives the Bugzilla administrator the option of choosing which protocol to use based on their requirements.

Notable changes since I last blogged:

  1. Pluggable backends with optional CPAN dependencies. If you don't want to use AMQP, you don't need to have those dependencies installed
  2. Added simple support for message security. This was a major hurdle for getting bugzilla-push rolled out on bugzilla.mozilla.org. I intend to beef it up more in the coming weeks as well
  3. Fixed a bug where false values were being sent as "0" in the JSON messages instead of JSON's false
  4. Fixed support for using vhosts that are not "/" (the AMQP default)

Planned in the next week:

  1. Supporting YAML for message encoding
  2. Supporting Python's pickle for message encoding
  3. Get the extension rolled out on landfill.bugzilla.org
  4. Test, test, test
  5. Ask for security review from Mozilla's web security team
20Aug/10Off

Push notifications for Bugzilla!

I've had some downtime between Firefox releases and chose to work on a pet project on-and-off for the past week. I'm announcing it today as bugzilla-amqp.

What is bugzilla-amqp?

A server-side Bugzilla extension that sends messages to a message broker via AMQP whenever a Bugzilla object (bug, keyword, component, etc) is created or modified.

Why?

It enables push notifications for interesting events in Bugzilla! This is a big deal. Tools no longer have to poll the various APIs when dealing with bug data...instead they can sit back and get notified! Want to know when you are CC'd? Easy! Want to know when a new bug is written? No problem! Take a look at the quick demo video (webm, theora...warning, large!)

Because it talks AMQP, tools interested in the Bugzilla messages/events can be written in just about any language you want for any platform you want.

The impetus for writing this extension came from the desire to integrate Mozilla Pulse (running RabbitMQ) with bugzilla.mozilla.org, having push messages end-to-end.

Sounds awesome! I want this on bugzilla.mozilla.org now!

It won't be rolled out on bmo for a bit yet. All these need to happen:

  1. There are some features that need to be added first (like, uh, security)
  2. After that, because there is a fair amount of code (as far as Bugzilla extensions go), it will likely need to go through a security review
  3. Performance testing needs to happen so that it doesn't bring down bmo inadvertently
  4. The server running Mozilla Pulse needs to get beefier and the traffic expectations with IT have to be revisited (I promised them it was a prototype after all...)

I have filed bug 589322 to track putting the extension into production on bmo.

Ok, still sounds awesome...where do I get the code?

I've put it at http://github.com/LegNeato/bugzilla-amqp. Let me know if you use it and/or find any issues and feel free to fork away!

Are you some hardcore Bugzilla hacker?

Nope, I'm a Firefox release manager :-) . The Bugzilla extension system is pretty easy...I highly suggest you take a look if you ever wished Bugzilla did something differently or wanted a feature added.