summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYoshiaki Tamura <yoshi@midokura.jp>2011-07-21 21:44:12 +0900
committerYoshiaki Tamura <yoshi@midokura.jp>2011-07-21 21:44:12 +0900
commit97503418bea47ca38d2181e5dc5fa710d6e15df3 (patch)
treeb3f8e1e73524aef00738496eff9cc687167630fd
parent6843421be9cdef1fc12d3480889bdcfd96821e1b (diff)
downloadnova-97503418bea47ca38d2181e5dc5fa710d6e15df3.tar.gz
nova-97503418bea47ca38d2181e5dc5fa710d6e15df3.tar.xz
nova-97503418bea47ca38d2181e5dc5fa710d6e15df3.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.
-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 e5e2c5b50..43e6a8cd9 100644
--- a/nova/api/openstack/contrib/volumes.py
+++ b/nova/api/openstack/contrib/volumes.py
@@ -21,10 +21,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")
@@ -296,6 +298,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"
@@ -329,4 +378,8 @@ class Volumes(extensions.ExtensionDescriptor):
collection_name='servers'))
resources.append(res)
+ res = extensions.ResourceExtension('os-volumes_boot',
+ BootFromVolumeController())
+ resources.append(res)
+
return resources