Skip to content

Commit

Permalink
Adds deserialization for block_device_mapping
Browse files Browse the repository at this point in the history
The os-volumes extension adds the ability to boot from a volume
or snapshot by including block_device_mapping in the server create
request. This patch adds code to the xml deserializer so
block_device_mapping can be specified via xml as well.

Fixes bug 1052695

Change-Id: I3e586abb32976df98d70c29b6a021fd01c4c186b
  • Loading branch information
vishvananda committed Sep 19, 2012
1 parent ebb2814 commit f30387d
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 0 deletions.
31 changes: 31 additions & 0 deletions nova/api/openstack/compute/servers.py
Expand Up @@ -193,6 +193,12 @@ def _extract_server(self, node):
if security_groups is not None:
server["security_groups"] = security_groups

# NOTE(vish): this is not namespaced in json, so leave it without a
# namespace for now
block_device_mapping = self._extract_block_device_mapping(server_node)
if block_device_mapping is not None:
server["block_device_mapping"] = block_device_mapping

# NOTE(vish): Support this incorrect version because it was in the code
# base for a while and we don't want to accidentally break
# anyone that might be using it.
Expand All @@ -206,6 +212,31 @@ def _extract_server(self, node):

return server

def _extract_block_device_mapping(self, server_node):
"""Marshal the block_device_mapping node of a parsed request"""
node = self.find_first_child_named(server_node, "block_device_mapping")
if node:
block_device_mapping = []
for child in self.extract_elements(node):
if child.nodeName != "mapping":
continue
mapping = {}
attributes = ["volume_id", "snapshot_id", "device_name",
"virtual_name", "volume_size"]
for attr in attributes:
value = child.getAttribute(attr)
if value:
mapping[attr] = value
attributes = ["delete_on_termination", "no_device"]
for attr in attributes:
value = child.getAttribute(attr)
if value:
mapping[attr] = utils.bool_from_str(value)
block_device_mapping.append(mapping)
return block_device_mapping
else:
return None

def _extract_scheduler_hints(self, server_node):
"""Marshal the scheduler hints attribute of a parsed request"""
node = self.find_first_child_named(server_node,
Expand Down
40 changes: 40 additions & 0 deletions nova/tests/api/openstack/compute/test_servers.py
Expand Up @@ -3333,6 +3333,46 @@ def test_request_with_scheduler_hints(self):
}}
self.assertEquals(request['body'], expected)

def test_request_with_block_device_mapping(self):
serial_request = """
<server xmlns="http://docs.openstack.org/compute/api/v2"
name="new-server-test" imageRef="1" flavorRef="1">
<block_device_mapping>
<mapping volume_id="7329b667-50c7-46a6-b913-cb2a09dfeee0"
device_name="/dev/vda" virtual_name="root"
delete_on_termination="False" />
<mapping snapshot_id="f31efb24-34d2-43e1-8b44-316052956a39"
device_name="/dev/vdb" virtual_name="ephemeral0"
delete_on_termination="False" />
<mapping device_name="/dev/vdc" no_device="True" />
</block_device_mapping>
</server>"""
request = self.deserializer.deserialize(serial_request)
expected = {"server": {
"name": "new-server-test",
"imageRef": "1",
"flavorRef": "1",
"block_device_mapping": [
{
"volume_id": "7329b667-50c7-46a6-b913-cb2a09dfeee0",
"device_name": "/dev/vda",
"virtual_name": "root",
"delete_on_termination": False,
},
{
"snapshot_id": "f31efb24-34d2-43e1-8b44-316052956a39",
"device_name": "/dev/vdb",
"virtual_name": "ephemeral0",
"delete_on_termination": False,
},
{
"device_name": "/dev/vdc",
"no_device": True,
},
]
}}
self.assertEquals(request['body'], expected)


class TestAddressesXMLSerialization(test.TestCase):

Expand Down

0 comments on commit f30387d

Please sign in to comment.