Contributing a patch to OpenStack

The other week, I found a bug in OpenStack Horizon that was preventing some text from being translated when a user switched locales. Since this was a bug and not a modification, I thought it'd be a good opportunity to try out submitting a patch to OpenStack.

The actual fix was dead simple. It involved changing one word:

ugettext

to

ugettext_lazy

across all files that included the original word.

The process for getting this fix committed was an interesting experience.

There's a detailed document on how to contribute to OpenStack on the organization'€™s website. All contributors must sign an agreement. This is the first time I've seen this in an open source project. If you work for an organization, it must also sign an agreement. Cybera had already done this, but since it was quite a long time ago, I was sure that the list of approved employees was outdated. So I filled out Schedule A.

OK, with that now out of the way, I can submit my patch, right? Not yet. Now I have to add myself to a wiki, join a group on Launchpad, and wait until my membership has been approved. Fortunately, Vish approved me within 24 hours. On the other hand, I wasted an entire day to overhead.

Okie dokie, I'm approved to submit patches. All patches should have a corresponding bug report for fixes or a blueprint for modifications. Understandable. I created a bug report.

Got my patch, got my bug report: how do I connect the two? Enter the Gerrit Workflow. This is designed to submit your patch to review.openstack.org where it can be reviewed, approved, and merged. Just looking at the front page of that site shows the amount of activity going on with the code-base. This level of activity kind of puts all of the overhead work into perspective.

Okay, so I clone the latest copy of Horizon, switch to the Folsom branch, make my changes, run the unit test suite (because I know dev's love that kind of stuff), and submit my patch. It appears on review.openstack.org and my ticket is automatically updated.

A Horizon team member lets me know that changes to the stable branch should come after the development branch has been updated. This makes sense to me from a development point of view, but I don't entirely agree with it.

As a systems administrator, I want to provide a stable environment. This means that any OpenStack environment I run needs to be one of the stable versions. Unless I have spare time to simply play around, I'll never run the development version, and therefore never run into any bugs in the development version. Any bug I find will be on the stable version. From working with other operators, I know this is how most production OpenStack environments are run.

It's unfortunate that the norm in OpenStack development is to concentrate almost entirely on the development version, and make the stable version almost an after-thought. Is it because the current development version will be the current stable version within six months? If this is the case, it does not mean that all OpenStack environments will automatically be upgraded to the new stable version.

Tangent aside, let's get back to my patch. I'm now on a mission to see this to the end. I decide to set up a small environment running the development version, make my changes, and test them out. It all looks good, so I submit a second patch. Again, review.openstack.org is updated, which subsequently updates the bug report.

A few hours later, I come back from a meeting and start poking around Horizon. I see an odd string of text. After 20 minutes of troubleshooting, I confirm the oddity is from my patch. Shoot. I quickly abort the patch at review.openstack.org and begin figuring out what happened.

Fortunately it was easy to decipher: I was simply too aggressive with changing all occurrences of the ugettext word. It only needed to be changed six times. Wash, rinse, repeat, and I have two new patches up at review.openstack.org.

A few hours later, an automated process called Jenkins runs some basic tests to see if my patch look safe. The patch for the development branch fails. Ugh. What now? The error report looked totally unrelated to my changes, so I google it. It turns out that Jenkins is having some personal issues and the fix is to just have him re-run the tests. I do so and the tests pass on the second round.

Soon after that someone approves the patch for the development branch. Each patch needs two approvals, so one down and one to go. The next day the Project Team Lead of Horizon approves the patch. Yay! Once a patch receives two approvals, Jenkins pops his head back in and runs some secondary tests. They fail again. Seriously? What now?

This time, the patch failed to merge into the main code. This could have happened if someone else had made a change while my patch was being reviewed, which would now cause my changes to conflict. I was changing a single word '€” did someone else already beat me to this?

I review the conflicts and see that for some bizarre reason, a file that I did not change was now being tagged as modified and is conflicting with the original file. Odd. I figure it's not worth putting the effort into researching entirely what happened, so I clean everything up and resubmit the patch.

Wash, rinse, repeat: Jenkins runs the first round of tests, two people approve the patch, and now for the big moment: Jenkins runs the second round of tests. It works! The patch is then automatically merged into the main code.

Now it looks like people are reviewing my patch for the stable version.

All in all, it took a total of four days to get a patch accepted. Fortunately, the majority of that time was due to initial overhead and beginner'€™s learning. Would I do it again? Sure, why not.