Monday, May 19, 2014

OpenStack - OpenVSwitch Agent won't register

I hit the wall today when I tried to add an another compute node to my OpenStack. Everything seemed to install fine. However, the Openvswitch Agent did not register itself. Of course, I am using the Oracle Enterprise Linux which is not official supported yet by OpenStack and it made me uneasy. During the installation process, I hit a few problems of loading the wrong yum packages and I correct them manaully.

First I checked out neutron-openvswitch-agent.log on the compute node. There is no trace and error. I checked out the neutron-server.log, no trace and error neither.  I understand that the registration mechanism is by sending a report_status message from the agent to neutron controller.

I used rabbitmqctl to check for the existence of the queue and it did. It really buffled me. So I compared the message in the neutron-server.log.  With the surprise, the clock on the new compute node was not set correctly and the '_context_timestamp' is off in the debug messager.

2014-05-19 15:13:33.923 21639 DEBUG neutron.db.agents_db [req-915d3718-8489-4bd1-905f-3a02959b2746 None] Message with invalid timestamp received report_state /opt/stack/neutron/neutron/db/agents_db.py:214

So the time is the problem.  I adjusted the clock. Magically, the agent is registered. I hope there is much more clear message to idenify the problem.

Friday, May 9, 2014

Adding your own configuration to OpenStack Neutron using oslo.config

If you are doing OpenStack development,  eventually you will want to add your own configuration in OpenStack for you own plugin/mechanism driver. The steps required is pretty simple.

Let say my plugin/mechanism driver need to talk to a web service running to perform some operation and I do not want to hard code the web service configuration.

OpenStack uses oslo.config to do the configuration parsing. 

First, you need to tell oslo.config what configuration options are needed.

Here is the sample code fragment to create my configuration parameter list. 

ml2_my_opts = [
    cfg.StrOpt('hostname', default=None,
               help=_("The hostname of the my service")),
    cfg.IntOpt('port', default=8443,
               help=_("The port number of my service")),
    cfg.StrOpt('username', default=None,
               help=_("The username of my service")),
    cfg.StrOpt('password', default=None,
               help=_("The password of my service"))]

I specify the hostname, port, username and password. I set the port default value as 8443.

Then I register it by doing the following.

cfg.CONF.register_opts(my_service_opts, "my_service")

"my_service" is optional. If specified, it is the namespace I am going to use. 

To retrieve the configuration,

hostname = cfg.CONF.my_service_opts.hostname
port = cfg.CONF.my_service_opts.port
username = cfg.CONF.my_service_opts.username
password = cfg.CONF.my_service_opts.password

Now the coding is done. 

Let put the parameters on the configuration file. The configuration file is specified by the --config-file in the argument of python. For example, 

stack    17357  0.1  0.0 284908 52156 pts/9    S+   08:57   0:05 python /usr/bin/neutron-server --config-file /etc/neutron/neutron.conf --config-file /etc/neutron/plugins/ml2/ml2_conf.ini

For the neutron-server, two configuration files are specified. One is /etc/neutron/neutron.conf and the other is /etc/neutron/plugins/ml2/ml2_conf.ini.

For the above example, I will put the following configuration in one of the configuration file listed above.

[my_service]
hostname=my_host
port=8443
username=guest
password=guest

With oslo.config, adding your own additional configuration is extremely simple.