First step for reading OpenStack Nova source code

Yuki Nishiwaki
ukinau
Published in
4 min readJan 31, 2018

How many people do operators actually read source code for Nova when they need to operate OpenStack based cloud. Probably almost all people operating OpenStack have a experience looking over source code because OpenStack have a lot of extensions and the combination of extensions would be infinite and that infinite combination make operator often face some mysterious bugs. But I bet it’s not that easy even if everything is written in Python.
This is because of amount of source code and one of the characteristics of OpenStack which is “microservice” But actually it will be easier to read source code once you got overview of Nova source code structure.

So this article describe overview of Nova source code and make you feel comfortable to read Nova source code when you need.

nova-blabla

As you probably already know, nova have a lof of execution files which have name starting with “nova-” prefix. Are they composed of all different technology stack/different concept? Ahh not. Obviously nova repository defined kind of framework and all execution files have been composed with following that concept, which means once you got through one of the nova related execution file, you can read all nova code without pain.

Concept You have to know about Nova

CMD(nova/cmd/*)

This is the execution file the end-user will execute and that is created for each module. The contents inside this file is super simple and just create Service and execute it.

Service (nova/service.py)

This is the kind of framework for all nova related execution file. nova-compute, nova-scheduler and nova-conductor use same Service class. The module specific code would be defined in Manager and Service will choose proper manager by the name of execution file and load it. This Service achieve to behave module specific logic to call proper method of manager in proper timing. RPC server is also started by Service and manager will be endpoint of RPC Server.

Manager (nova/<module>/manager.py)

The module specific logic is written here. Service would call some method in proper timing like init_host when is loaded. So the developer have to implement all method being required by Service.
If you want to run RPC Server, Manager will be bound as a endpoint for RPC Server. So the developer need to implement internal API logic in Manager so that other module can call RPC.

DB (nova/db/sqlalchemy/api.py)

It’s just database access logic nothing more interesting than that

Objects (nova/objects/*)

This is very interesting thing to me. In OpenStack the accessor for database is not defined in model and instead of model that accessor is defined in object. Almost all database access would be done via object.
When try to access data on database via object, the developer can access data without taking care of how to access that data like via nova-conductor or directly accessing database.
Let me dive more how do nova achieve it. The class which is located in objects and represent data on database have “remotable” decorator for each accessor for data. By doing this, when that class have indirection_api variable indicating conductor rpc api client, automatically change the behaviour for database access so that just call conductor rpc call. If not, that module try to access database directly without asking nova-conductor.

https://github.com/openstack/oslo.versionedobjects/blob/master/oslo_versionedobjects/base.py#L168-L230

As you can see actual source code, Configuring conductor api client for object is usually done by cmd/<module>.py

API related (REST API, RPC API, API)

They can be divided into 3 parts.

  • Rest API Server (Rest API Client which is in other repository)
  • Software API Client
  • RPC API Client (RPC Server implementation is in Manager)

Sorting by how abstract API is from other method
Rest API > Software API > RPC API

So when you think something new module to use the feature other module provide, I recommend you to see API in the order of higher abstraction whether you can use it or not. Otherwise after you finished to implement with 5 RPC API calls, you could find very similer 1 Software API. We have to avoid such a situation.

Rest API Server (nova/api/openstack/*)

There is a bit confusion by many files having the name starting with api. But all code under this directory are for REST API server

Software API Client (nova/<module>/api.py)

I was wondering how should I call these type of logic, but here I decided to call that as Software API Client.
This is created for other module to call method of this API.
The communication over module would be done via RPC but RPC Server does not always provide the feature by good granularity sometimes too details for other module and the other reason to create Software API is to prevent other module from doing mis-operation like sometimes there is a situation for other module to call RPC API 2 just before call RPC API 3. Probably it’s more kind to other module to have a API calling RPC API in expected order than writing document. Probably these reason let the developer create such Software API.

RPC API Client (nova/<module>/rpcapi.py)

This is authentic RPC API Client. It’s basically prepared for each method of the endpoint for RPC Call(manager) and the method of RPC API Client do just preparing message queue and send message and wait for reply. There is no logic more than preparing transport.

Summary

I was reading through Nova Source Code without such a pre-information and I really wish could know above concept before start to read. So that’s why I wrote this article and hope this article help someone newbie for OpenStack.

Yuki Nishiwaki

--

--