Monday, February 29, 2016

OpenStack adventures part 2


I'm doing good. My official internship task is done. =)

And in this post I'm going to describe how I made it.

The internship task

My patch for binary data support in Zaqar's websocket transport was finally merged recently! Yay.

The patch wasn't reviewed fast, because it was pretty big, especially on it's first revisions. But there was no way it could be splitted into smaller parts. Also it had relatively small priority for Zaqar team.

I remember, that when I was picking a task for my internship amongst the available ones on OpenStack's Intership ideas page, I was trying to pick the less scary task. The task "Implement support for binary data in the websocket transport on Zaqar" sounded less scary, because I was already familliar with websocket protocol. But still it was... scary. So I picked this one and, when I started working on it, I realized that the patch I need to write isn't hard at all and quickly made a working prototype just before the official start of internship period. :D

However, when I started to write the actual patch, I faced three obstacles.

The first obstacle

First one was lack of documentation for Zaqar project. I had to make sure my patch works correctly also in Zaqar's notifications. But I was unable to test notifications, they just weren't working in my Zaqar. I started to wonder, is this a bug in Zaqar. I was asking people, what can be wrong. Some time later my mentor Victoria shared her zaqar.conf, because notifications were working for her. And in her config I noticed this strange line in the [storage] section:

message_pipeline = zaqar.notification.notifier

That's it. It activates notifications functionality in Zaqar. But, for example, in my generated zaqar.conf there was only this:

# Pipeline to use for processing message operations. This pipeline
# will be consumed before calling the storage driver's controller
# methods. (list value)
#message_pipeline =

As you can see the description for message_pipeline parameter gives no hint at all about possible values and that it can be used for notifications.

So I added required value to the message_pipeline parameter to my zaqar.conf, and notifications started working like a charm.

Later, when I was writing new Configuration Reference for Zaqar, I added there information about how to activate notifications functionality and explained the idea of storage layer pipelines, so it might help other people. Because I care .
Though I would prefer to have description of possible values directly in configuration file's comments, my PTL said that describing them in Configuration Reference is enough.

The second obstacle

In Zaqar's repository there is a tiny websocket client for Zaqar written in JavaScript. It is called websocket.html and serves as example of possible client for Zaqar. I had to make sure my patch works correctly with authentication. The websocket.html has username and password fields, but each time I clicked on Login button, nothing happened. Except in JavaScript console, where I saw this:

XMLHttpRequest cannot load http://localhost:5000/v3/auth/tokens. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:63342' is therefore not allowed access.

I contacted the person who wrote websocket.html and he said that I have to enable CORS (Cross-origin resource sharing) in my Keystone (Identity service). After some time of searching information in the internet and experimenting, I configured Keystone to use CORS and expose X-Subject-Token header in it's responses. After this, authentication in websocket.html started to work and I was able to test it with my patch. Later I added error messages about CORS to websocket.html, so it would be much easier for the person trying websocket.html to know why authentication is not working and what should be done in Keystone's configuration to fix it. Also I'm going to add a small README near websocket.html with the instructions for configuring Keystone.

The third obstacle

Starting to write unit tests in Python was a bit hard for me, especially when I needed to "mock" some object, i.e. replace a real object by a stub for the purpose of unit testing. This was the hardest part during my learning of Python. But it's okay now. =)

Funny thing

My internship wasn't limited just to this tiny task. I already did much more than that to Zaqar project. And I feel really happy about my progress. Though just sometimes, when I don't have doubts about myself =).

In one of my next blog posts I will describe my whole internship period experience.


  1. How much python did you have to know before starting the project. I am still learning python.

  2. How much python did you have to know before starting the project. I am still learning python.