Calling out to Nova

Whilst playing around with some ideas for an OpenStack management service I need to figure out how to call the Nova service to manage Flavors, i.e. create and delete Flavors as well as listing them. From looking around at existing code (e.g. from the Nova project on Github I can see two main approaches to solving this problem

  • RPC or using a HTTP client. The following are some notes on these approaches to help confirm my understanding and solicit feedback. Comments on any of the following and corrections to any inaccuracies will be greatly appreciated.

  • RPC
  • HTTP Client

Approach 1: RPC to Nova

OpenStack services talk to each other using RPC calls - the architecture is actually RPC over AMQP. As can be expected, there are both server and client components. Taking the nova code as an example - some important files/directories are:

1. General/Base classes

2. Client side code:

3. Server side code:

As far as I can see (and as should obviously be the case) - every method defined in 2 above has an equivalent method defined in 3 - i.e. the client rpc code invokes methods defined in the server rpc code. Though an obvious point this is important for what needs to be done to accomplish the goal of managing flavors via rpc.

One other interesting file is /nova/compute/

  • the code here has lots of examples of invoking the client-side rpc calls, eg:

    37 from nova.compute import rpcapi as compute_rpcapi … 1322 def _delete_instance(self, context, instance): 1323 def terminate(context, instance, bdms, reservations=None): 1324 self.compute_rpcapi.terminate_instance(context, instance, bdms, 1325 reservations=reservations) … 1586 def snapshot(self, context, instance, name, extra_properties=None, 1587 image_id=None): 1588 “"”Snapshot the given instance.””” … 1608 self.compute_rpcapi.snapshot_instance(context, instance=instance, 1609 image_id=image_meta[‘id’], image_type=’snapshot’) 1610 return image_meta

So, what needs to be done?

First I need to add the client side code to my service, and following observed convention add it in service_name/compute/ I also need to include the files from /nova/openstack/common/rpc/ - i.e. from #1 above. Besides the common configuration code that I will copy from the nova rpc_api (i.e. #2 above) this code will look something like:

190     def get_all_flavors(self, ctxt):
191         return, self.make_msg('get_all_flavors'))
193     def get_flavor(self, ctxt, flavor_id):
194         return, self.make_msg('get_flavor', flavor_id=flavor_id))
196     def create_flavor(self, ctxt, args={}):
197         return, self.make_msg())
199     def delete_flavor(self, ctxt, flavor_id):
200         return, self.make_msg('delete_flavor', flavor_id=flavor_id))

I haven’t yet figured out the parameters for ‘create_flavor’ above though that should be easy enough. Also, note that the rpc methods are ‘call’ rather than ‘cast’ as I am expecting a return - possible exception will be the delete_flavor method.

Right now, the server side rpc code has no methods relating to ‘flavors’ (note: method signatures in general refer to flavors as ‘instance_types’). So a big caveat with adopting the RPC approach is that I will have to submit the server side calls to manage ‘instance_types’ for inclusion in the nova/compute/ code in the Nova project. I am not sure why these calls aren’t there right now so I wonder if I will come up against resistance in trying to add them.

Approach 2: HTTP Client

Perhaps the most obvious (for me) example of inter-service communication in OpenStack is Nova<->Glance - i.e. the compute service exposing information about images from which compute instances can be created. I was surprised to find that Nova doesn’t use RPC to talk to the Image service Glance. Rather, it uses the python-glanceclient:

In nova/image/

30 import glanceclient
103 def _create_glance_client(context, host, port, use_ssl, version=1):
104     """Instantiate a new glanceclient.Client object."""

and in nova/compute/

47 from nova.image import glance
528     def _get_image(self, context, image_href):
529         if not image_href:
530             return None, {}
532         (image_service, image_id) = glance.get_remote_image_service(
533                 context, image_href)
534         image =, image_id)
535         return image_id, image

The good news is that there is already a python-novaclient that could in theory be used in a similar way to manage instance_types. My initial investigation lead me to believe that the the current Compute API only supports retrieving info about existing flavors but not creating or deleting them. However, a comment in the API spec lead me to the ‘Flavor Access’ Compute API extension that allows management of ‘private flavors’. So one caveat is that the ‘flavor access’ extension to Nova must be supported by Nova service I will be talking to, though I don’t expect this to be a blocker. I am guessing ‘private’ here means that these flavors are only available to the specific tenant that created them; I’m not yet sure how much of a problem this last point will be. To end on a positive note, it seems that the current python-novaclient already implements the ‘create’ and ‘delete’ methods for flavors.

blog comments powered by Disqus
RSS Feed Icon site.xml
RSS Feed Icon tripleo.xml