summaryrefslogtreecommitdiffstats
path: root/nova/api
diff options
context:
space:
mode:
authorYoshiaki Tamura <yoshi@midokura.jp>2011-07-26 17:10:31 +0000
committerTarmac <>2011-07-26 17:10:31 +0000
commitb1e72bbe231d29ddf62fb2942ab055b5c92f1a0a (patch)
tree4b149cd1d50536a510db8c12cb81ba61abd53350 /nova/api
parent48a6bf42b3af5323d35f9a31bd4233712165b276 (diff)
parent97503418bea47ca38d2181e5dc5fa710d6e15df3 (diff)
downloadnova-b1e72bbe231d29ddf62fb2942ab055b5c92f1a0a.tar.gz
nova-b1e72bbe231d29ddf62fb2942ab055b5c92f1a0a.tar.xz
nova-b1e72bbe231d29ddf62fb2942ab055b5c92f1a0a.zip
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.
Diffstat (limited to 'nova/api')
-rw-r--r--nova/api/openstack/contrib/volumes.py53
1 files changed, 53 insertions, 0 deletions
diff --git a/nova/api/openstack/contrib/volumes.py b/nova/api/openstack/contrib/volumes.py
index 827e36097..867fe301e 100644
--- a/nova/api/openstack/contrib/volumes.py
+++ b/nova/api/openstack/contrib/volumes.py
@@ -22,10 +22,12 @@ from nova import compute
from nova import exception
from nova import flags
from nova import log as logging
+from nova import quota
from nova import volume
from nova.api.openstack import common
from nova.api.openstack import extensions
from nova.api.openstack import faults
+from nova.api.openstack import servers
LOG = logging.getLogger("nova.api.volumes")
@@ -297,6 +299,53 @@ class VolumeAttachmentController(object):
return {'volumeAttachments': res}
+class BootFromVolumeController(servers.ControllerV11):
+ """The boot from volume API controller for the Openstack API."""
+
+ def _create_instance(self, context, instance_type, image_href, **kwargs):
+ try:
+ return self.compute_api.create(context, instance_type,
+ image_href, **kwargs)
+ except quota.QuotaError as error:
+ self.helper._handle_quota_error(error)
+ except exception.ImageNotFound as error:
+ msg = _("Can not find requested image")
+ raise faults.Fault(exc.HTTPBadRequest(explanation=msg))
+
+ def create(self, req, body):
+ """ Creates a new server for a given user """
+ extra_values = None
+ try:
+
+ def get_kwargs(context, instance_type, image_href, **kwargs):
+ kwargs['context'] = context
+ kwargs['instance_type'] = instance_type
+ kwargs['image_href'] = image_href
+ return kwargs
+
+ extra_values, kwargs = self.helper.create_instance(req, body,
+ get_kwargs)
+
+ block_device_mapping = body['server'].get('block_device_mapping')
+ kwargs['block_device_mapping'] = block_device_mapping
+
+ instances = self._create_instance(**kwargs)
+ except faults.Fault, f:
+ return f
+
+ # We can only return 1 instance via the API, if we happen to
+ # build more than one... instances is a list, so we'll just
+ # use the first one..
+ inst = instances[0]
+ for key in ['instance_type', 'image_ref']:
+ inst[key] = extra_values[key]
+
+ builder = self._get_view_builder(req)
+ server = builder.build(inst, is_detail=True)
+ server['server']['adminPass'] = extra_values['password']
+ return server
+
+
class Volumes(extensions.ExtensionDescriptor):
def get_name(self):
return "Volumes"
@@ -330,4 +379,8 @@ class Volumes(extensions.ExtensionDescriptor):
collection_name='servers'))
resources.append(res)
+ res = extensions.ResourceExtension('os-volumes_boot',
+ BootFromVolumeController())
+ resources.append(res)
+
return resources