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
1=== modified file 'nova/api/openstack/contrib/'
2--- nova/api/openstack/contrib/ 2011-07-20 17:52:22 +0000
3+++ nova/api/openstack/contrib/ 2011-07-21 12:48:36 +0000
4@@ -22,10 +22,12 @@
5 from nova import exception
6 from nova import flags
7 from nova import log as logging
8+from nova import quota
9 from nova import volume
10 from nova.api.openstack import common
11 from nova.api.openstack import extensions
12 from nova.api.openstack import faults
13+from nova.api.openstack import servers
16 LOG = logging.getLogger("nova.api.volumes")
17@@ -297,6 +299,53 @@
18 return {'volumeAttachments': res}
21+class BootFromVolumeController(servers.ControllerV11):
22+ """The boot from volume API controller for the Openstack API."""
24+ def _create_instance(self, context, instance_type, image_href, **kwargs):
25+ try:
26+ return self.compute_api.create(context, instance_type,
27+ image_href, **kwargs)
28+ except quota.QuotaError as error:
29+ self.helper._handle_quota_error(error)
30+ except exception.ImageNotFound as error:
31+ msg = _("Can not find requested image")
32+ raise faults.Fault(exc.HTTPBadRequest(explanation=msg))
34+ def create(self, req, body):
35+ """ Creates a new server for a given user """
36+ extra_values = None
37+ try:
39+ def get_kwargs(context, instance_type, image_href, **kwargs):
40+ kwargs['context'] = context
41+ kwargs['instance_type'] = instance_type
42+ kwargs['image_href'] = image_href
43+ return kwargs
45+ extra_values, kwargs = self.helper.create_instance(req, body,
46+ get_kwargs)
48+ block_device_mapping = body['server'].get('block_device_mapping')
49+ kwargs['block_device_mapping'] = block_device_mapping
51+ instances = self._create_instance(**kwargs)
52+ except faults.Fault, f:
53+ return f
55+ # We can only return 1 instance via the API, if we happen to
56+ # build more than one... instances is a list, so we'll just
57+ # use the first one..
58+ inst = instances[0]
59+ for key in ['instance_type', 'image_ref']:
60+ inst[key] = extra_values[key]
62+ builder = self._get_view_builder(req)
63+ server =, is_detail=True)
64+ server['server']['adminPass'] = extra_values['password']
65+ return server
68 class Volumes(extensions.ExtensionDescriptor):
69 def get_name(self):
70 return "Volumes"
71@@ -330,4 +379,8 @@
72 collection_name='servers'))
73 resources.append(res)
75+ res = extensions.ResourceExtension('os-volumes_boot',
76+ BootFromVolumeController())
77+ resources.append(res)
79 return resources