Merge lp:~tamura-yoshiaki/nova/boot-from-volume-os-api into lp:~hudson-openstack/nova/trunk

Proposed by Yoshiaki Tamura
Status: Merged
Approved by: Josh Kearney
Approved revision: 1245
Merged at revision: 1325
Proposed branch: lp:~tamura-yoshiaki/nova/boot-from-volume-os-api
Merge into: lp:~hudson-openstack/nova/trunk
Diff against target: 79 lines (+53/-0)
1 file modified
nova/api/openstack/contrib/ (+53/-0)
To merge this branch: bzr merge lp:~tamura-yoshiaki/nova/boot-from-volume-os-api
Reviewer Review Type Date Requested Status
Josh Kearney (community) Approve
Devin Carlen (community) Approve
Matt Dietz (community) Needs Fixing
Brian Waldon (community) Needs Information
Review via email:

Commit message

Add OpenStack API support for block_device_mapping.

This patch enables boot from volume feature already implemented in EC2
API, as an OpenStack API extension.

To post a comment you must log in.
Revision history for this message
Brian Waldon (bcwaldon) wrote :

I'm pretty sure this should be added as an API extension, I'm just not sure what the best way is.

review: Needs Information
Revision history for this message
Yoshiaki Tamura (tamura-yoshiaki) wrote :

> I'm pretty sure this should be added as an API extension, I'm just not sure
> what the best way is.

Yes, I think it's a fair point.
My opinion would be not to make things too complicated, but if there is better way that Nova has been doing for similar cases, I would be happy to know it.

Revision history for this message
Brian Waldon (bcwaldon) wrote :

Could this live in the existing volumes extension?

Revision history for this message
Matt Dietz (cerberus) wrote :

Agree with Brian: This should exist in an extension instead

review: Needs Fixing
Revision history for this message
Brian Waldon (bcwaldon) wrote :

This can actually live in the OSAPI like you have it here, you just need to create an (essentially empty) extension to document it. We really just need the ExtensionDescriptor.

Revision history for this message
Yoshiaki Tamura (tamura-yoshiaki) wrote :

Sorry for my slow response again. Added a controller in volumes extension. Please let me know if this approach is acceptable.

Revision history for this message
Devin Carlen (devcamcar) wrote :

This approach is looking good...

review: Approve
Revision history for this message
Josh Kearney (jk0) wrote :

Looks good.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'nova/api/openstack/contrib/'
--- nova/api/openstack/contrib/ 2011-07-20 17:52:22 +0000
+++ nova/api/openstack/contrib/ 2011-07-21 12:48:36 +0000
@@ -22,10 +22,12 @@
22from nova import exception22from nova import exception
23from nova import flags23from nova import flags
24from nova import log as logging24from nova import log as logging
25from nova import quota
25from nova import volume26from nova import volume
26from nova.api.openstack import common27from nova.api.openstack import common
27from nova.api.openstack import extensions28from nova.api.openstack import extensions
28from nova.api.openstack import faults29from nova.api.openstack import faults
30from nova.api.openstack import servers
31LOG = logging.getLogger("nova.api.volumes")33LOG = logging.getLogger("nova.api.volumes")
@@ -297,6 +299,53 @@
297 return {'volumeAttachments': res}299 return {'volumeAttachments': res}
302class BootFromVolumeController(servers.ControllerV11):
303 """The boot from volume API controller for the Openstack API."""
305 def _create_instance(self, context, instance_type, image_href, **kwargs):
306 try:
307 return self.compute_api.create(context, instance_type,
308 image_href, **kwargs)
309 except quota.QuotaError as error:
310 self.helper._handle_quota_error(error)
311 except exception.ImageNotFound as error:
312 msg = _("Can not find requested image")
313 raise faults.Fault(exc.HTTPBadRequest(explanation=msg))
315 def create(self, req, body):
316 """ Creates a new server for a given user """
317 extra_values = None
318 try:
320 def get_kwargs(context, instance_type, image_href, **kwargs):
321 kwargs['context'] = context
322 kwargs['instance_type'] = instance_type
323 kwargs['image_href'] = image_href
324 return kwargs
326 extra_values, kwargs = self.helper.create_instance(req, body,
327 get_kwargs)
329 block_device_mapping = body['server'].get('block_device_mapping')
330 kwargs['block_device_mapping'] = block_device_mapping
332 instances = self._create_instance(**kwargs)
333 except faults.Fault, f:
334 return f
336 # We can only return 1 instance via the API, if we happen to
337 # build more than one... instances is a list, so we'll just
338 # use the first one..
339 inst = instances[0]
340 for key in ['instance_type', 'image_ref']:
341 inst[key] = extra_values[key]
343 builder = self._get_view_builder(req)
344 server =, is_detail=True)
345 server['server']['adminPass'] = extra_values['password']
346 return server
300class Volumes(extensions.ExtensionDescriptor):349class Volumes(extensions.ExtensionDescriptor):
301 def get_name(self):350 def get_name(self):
302 return "Volumes"351 return "Volumes"
@@ -330,4 +379,8 @@
330 collection_name='servers'))379 collection_name='servers'))
331 resources.append(res)380 resources.append(res)
382 res = extensions.ResourceExtension('os-volumes_boot',
383 BootFromVolumeController())
384 resources.append(res)
333 return resources386 return resources