summaryrefslogtreecommitdiffstats
path: root/nova/api
diff options
context:
space:
mode:
authorNikola Dipanov <ndipanov@redhat.com>2012-11-07 18:56:35 +0100
committerNikola Dipanov <ndipanov@redhat.com>2012-12-03 19:38:19 +0100
commit1d00dfcfbb9bdeff358503fefefc7e6e7b4903eb (patch)
tree169e89e641e8f221b244f518549d93d1e8f9a1af /nova/api
parentac7737dc8b5122ff83beff2ae00eef7365fa032d (diff)
downloadnova-1d00dfcfbb9bdeff358503fefefc7e6e7b4903eb.tar.gz
nova-1d00dfcfbb9bdeff358503fefefc7e6e7b4903eb.tar.xz
nova-1d00dfcfbb9bdeff358503fefefc7e6e7b4903eb.zip
Boot from volume without image supplied
This patch allows for booting instances without supplying an image if there is block device mapping supplied. It makes changes to nova API and compute services to handle requests that do not have any image supplied. Also it makes rescue and rebuild work with instances started from volume. Finally the patch introduces tests to make sure the system acts as expected, and in the process fixes and refactors some old tests to make them test for cases this new functionality can introduce. This patch is intended to be a proof of concept and a first step towards a more cleaner interface for booting from volumes, outlined in https://etherpad.openstack.org/grizzly-boot-from-volumes. This patch also introduces a slight modification of the nova API so I am flagging it with DocImpact. The change is that if the os-volumes extension is used ImageRef does not need to be supplied to the create server API call provided there is block_device_mapping provided. Also note that this is the first step towards introducing a 'volume' parameter for starting instances which will replace the somewhat unintuitive block_device_mapping (they will still be used but not for the boot device). This patch is coupled with I5ba9b0f35a5084aa91eca260f46cac83b8b6591e that provides changes to the nova client. Implements: blueprint improve-boot-from-volume Fixes bug #1008622 Change-Id: I530760cfaa5eb0cae590c7383e0840c6b3f896b9
Diffstat (limited to 'nova/api')
-rw-r--r--nova/api/openstack/compute/servers.py23
-rw-r--r--nova/api/openstack/compute/views/servers.py25
2 files changed, 34 insertions, 14 deletions
diff --git a/nova/api/openstack/compute/servers.py b/nova/api/openstack/compute/servers.py
index 9c019f78f..68c5372c3 100644
--- a/nova/api/openstack/compute/servers.py
+++ b/nova/api/openstack/compute/servers.py
@@ -743,8 +743,7 @@ class Controller(wsgi.Controller):
self._validate_server_name(name)
name = name.strip()
- image_href = self._image_ref_from_req_data(body)
- image_href = self._image_uuid_from_href(image_href)
+ image_uuid = self._image_from_req_data(body)
personality = server_dict.get('personality')
config_drive = None
@@ -855,7 +854,7 @@ class Controller(wsgi.Controller):
(instances, resv_id) = self.compute_api.create(context,
inst_type,
- image_href,
+ image_uuid,
display_name=name,
display_description=name,
key_name=key_name,
@@ -1108,6 +1107,24 @@ class Controller(wsgi.Controller):
return image_uuid
+ def _image_from_req_data(self, data):
+ """
+ Get image data from the request or raise appropriate
+ exceptions
+
+ If no image is supplied - checks to see if there is
+ block devices set and proper extesions loaded.
+ """
+ image_ref = data['server'].get('imageRef')
+ bdm = data['server'].get('block_device_mapping')
+
+ if not image_ref and bdm and self.ext_mgr.is_loaded('os-volumes'):
+ return ''
+ else:
+ image_href = self._image_ref_from_req_data(data)
+ image_uuid = self._image_uuid_from_href(image_href)
+ return image_uuid
+
def _flavor_id_from_req_data(self, data):
try:
flavor_ref = data['server']['flavorRef']
diff --git a/nova/api/openstack/compute/views/servers.py b/nova/api/openstack/compute/views/servers.py
index b423b37d4..d281f6a61 100644
--- a/nova/api/openstack/compute/views/servers.py
+++ b/nova/api/openstack/compute/views/servers.py
@@ -164,17 +164,20 @@ class ViewBuilder(common.ViewBuilder):
def _get_image(self, request, instance):
image_ref = instance["image_ref"]
- image_id = str(common.get_id_from_href(image_ref))
- bookmark = self._image_builder._get_bookmark_link(request,
- image_id,
- "images")
- return {
- "id": image_id,
- "links": [{
- "rel": "bookmark",
- "href": bookmark,
- }],
- }
+ if image_ref:
+ image_id = str(common.get_id_from_href(image_ref))
+ bookmark = self._image_builder._get_bookmark_link(request,
+ image_id,
+ "images")
+ return {
+ "id": image_id,
+ "links": [{
+ "rel": "bookmark",
+ "href": bookmark,
+ }],
+ }
+ else:
+ return ""
def _get_flavor(self, request, instance):
instance_type = instance["instance_type"]