From 8d43c3fba1a5e07703cae6f7b631d0787c4f41bb Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Tue, 18 Sep 2012 12:02:50 -0700 Subject: [PATCH] Makes scheduler hints and disk config xml correct The scheduler hints and disk config extensions were not using proper prefixes when deserializing xml. This patch modifes them to deserialize properly. It leaves the old deserialization in place as well so anyone using the broken implementation will continue to work. It also updates the api samples to use the new format. Note that the proper fix required changing the alias for the scheduler hints extension, since the alias is used for xml, so the samples had to be moved. Finally it fixes an issue with deserialization, allowing it to support multiple hints with the same name. Part of bug 1050997 Change-Id: I9969582d65d44de25388f07b6d2013fb7d093fb2 --- .../scheduler-hints-post-req.json | 0 .../OS-SCH-HNT/scheduler-hints-post-req.xml | 12 +++++ .../scheduler-hints-post-resp.json | 0 .../scheduler-hints-post-resp.xml | 0 .../all_extensions/extensions-get-resp.json | 18 +++---- .../all_extensions/extensions-get-resp.xml | 8 ++-- .../scheduler-hints-post-req.xml | 10 ---- .../compute/contrib/scheduler_hints.py | 14 +++--- nova/api/openstack/compute/servers.py | 25 ++++++++-- .../api/openstack/compute/test_servers.py | 47 ++++++++++++++++++- .../scheduler-hints-post-req.json.tpl | 0 .../scheduler-hints-post-req.xml.tpl | 12 +++++ .../scheduler-hints-post-resp.json.tpl | 0 .../scheduler-hints-post-resp.xml.tpl | 0 .../extensions-get-resp.json.tpl | 16 +++---- .../extensions-get-resp.xml.tpl | 6 +-- .../scheduler-hints-post-req.xml.tpl | 10 ---- 17 files changed, 121 insertions(+), 57 deletions(-) rename doc/api_samples/{os-scheduler-hints => OS-SCH-HNT}/scheduler-hints-post-req.json (100%) create mode 100644 doc/api_samples/OS-SCH-HNT/scheduler-hints-post-req.xml rename doc/api_samples/{os-scheduler-hints => OS-SCH-HNT}/scheduler-hints-post-resp.json (100%) rename doc/api_samples/{os-scheduler-hints => OS-SCH-HNT}/scheduler-hints-post-resp.xml (100%) delete mode 100644 doc/api_samples/os-scheduler-hints/scheduler-hints-post-req.xml rename nova/tests/integrated/api_samples/{os-scheduler-hints => OS-SCH-HNT}/scheduler-hints-post-req.json.tpl (100%) create mode 100644 nova/tests/integrated/api_samples/OS-SCH-HNT/scheduler-hints-post-req.xml.tpl rename nova/tests/integrated/api_samples/{os-scheduler-hints => OS-SCH-HNT}/scheduler-hints-post-resp.json.tpl (100%) rename nova/tests/integrated/api_samples/{os-scheduler-hints => OS-SCH-HNT}/scheduler-hints-post-resp.xml.tpl (100%) delete mode 100644 nova/tests/integrated/api_samples/os-scheduler-hints/scheduler-hints-post-req.xml.tpl diff --git a/doc/api_samples/os-scheduler-hints/scheduler-hints-post-req.json b/doc/api_samples/OS-SCH-HNT/scheduler-hints-post-req.json similarity index 100% rename from doc/api_samples/os-scheduler-hints/scheduler-hints-post-req.json rename to doc/api_samples/OS-SCH-HNT/scheduler-hints-post-req.json diff --git a/doc/api_samples/OS-SCH-HNT/scheduler-hints-post-req.xml b/doc/api_samples/OS-SCH-HNT/scheduler-hints-post-req.xml new file mode 100644 index 000000000000..66843fae330d --- /dev/null +++ b/doc/api_samples/OS-SCH-HNT/scheduler-hints-post-req.xml @@ -0,0 +1,12 @@ + + + xen + eb999657-dd6b-464e-8713-95c532ac3b18 + + diff --git a/doc/api_samples/os-scheduler-hints/scheduler-hints-post-resp.json b/doc/api_samples/OS-SCH-HNT/scheduler-hints-post-resp.json similarity index 100% rename from doc/api_samples/os-scheduler-hints/scheduler-hints-post-resp.json rename to doc/api_samples/OS-SCH-HNT/scheduler-hints-post-resp.json diff --git a/doc/api_samples/os-scheduler-hints/scheduler-hints-post-resp.xml b/doc/api_samples/OS-SCH-HNT/scheduler-hints-post-resp.xml similarity index 100% rename from doc/api_samples/os-scheduler-hints/scheduler-hints-post-resp.xml rename to doc/api_samples/OS-SCH-HNT/scheduler-hints-post-resp.xml diff --git a/doc/api_samples/all_extensions/extensions-get-resp.json b/doc/api_samples/all_extensions/extensions-get-resp.json index 22eb1e207f67..e459340d5765 100644 --- a/doc/api_samples/all_extensions/extensions-get-resp.json +++ b/doc/api_samples/all_extensions/extensions-get-resp.json @@ -48,6 +48,14 @@ "namespace": "http://docs.openstack.org/compute/ext/flavor_extra_data/api/v1.1", "updated": "2011-09-14T00:00:00+00:00" }, + { + "alias": "OS-SCH-HNT", + "description": "Pass arbitrary key/value pairs to the scheduler", + "links": [], + "name": "SchedulerHints", + "namespace": "http://docs.openstack.org/compute/ext/scheduler-hints/api/v2", + "updated": "2011-07-19T00:00:00+00:00" + }, { "alias": "os-admin-actions", "description": "Enable admin-only server actions\n\n Actions include: pause, unpause, suspend, resume, migrate,\n resetNetwork, injectNetworkInfo, lock, unlock, createBackup\n ", @@ -264,14 +272,6 @@ "namespace": "http://docs.openstack.org/compute/ext/rescue/api/v1.1", "updated": "2011-08-18T00:00:00+00:00" }, - { - "alias": "os-scheduler-hints", - "description": "Pass arbitrary key/value pairs to the scheduler", - "links": [], - "name": "SchedulerHints", - "namespace": "http://docs.openstack.org/compute/ext/scheduler-hints/api/v2", - "updated": "2011-07-19T00:00:00+00:00" - }, { "alias": "os-security-groups", "description": "Security group support", @@ -345,4 +345,4 @@ "updated": "2011-03-25T00:00:00+00:00" } ] -} \ No newline at end of file +} diff --git a/doc/api_samples/all_extensions/extensions-get-resp.xml b/doc/api_samples/all_extensions/extensions-get-resp.xml index 4532244d9222..0ecb97c6f469 100644 --- a/doc/api_samples/all_extensions/extensions-get-resp.xml +++ b/doc/api_samples/all_extensions/extensions-get-resp.xml @@ -18,6 +18,9 @@ Provide additional data for flavors + + Pass arbitrary key/value pairs to the scheduler + Enable admin-only server actions @@ -113,9 +116,6 @@ Instance rescue mode - - Pass arbitrary key/value pairs to the scheduler - Security group support @@ -143,4 +143,4 @@ Volumes support - \ No newline at end of file + diff --git a/doc/api_samples/os-scheduler-hints/scheduler-hints-post-req.xml b/doc/api_samples/os-scheduler-hints/scheduler-hints-post-req.xml deleted file mode 100644 index 079289de0c5f..000000000000 --- a/doc/api_samples/os-scheduler-hints/scheduler-hints-post-req.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - xen - eb999657-dd6b-464e-8713-95c532ac3b18 - - \ No newline at end of file diff --git a/nova/api/openstack/compute/contrib/scheduler_hints.py b/nova/api/openstack/compute/contrib/scheduler_hints.py index e8d65a741463..f5c10fea18fb 100644 --- a/nova/api/openstack/compute/contrib/scheduler_hints.py +++ b/nova/api/openstack/compute/contrib/scheduler_hints.py @@ -29,13 +29,13 @@ class SchedulerHintsController(wsgi.Controller): def _extract_scheduler_hints(body): hints = {} + attr = '%s:scheduler_hints' % Scheduler_hints.alias try: - hints.update(body['os:scheduler_hints']) - - # Ignore if data is not present - except KeyError: - pass - + if 'os:scheduler_hints' in body: + # NOTE(vish): This is for legacy support + hints.update(body['os:scheduler_hints']) + elif attr in body: + hints.update(body[attr]) # Fail if non-dict provided except ValueError: msg = _("Malformed scheduler_hints attribute") @@ -56,7 +56,7 @@ class Scheduler_hints(extensions.ExtensionDescriptor): """Pass arbitrary key/value pairs to the scheduler""" name = "SchedulerHints" - alias = "os-scheduler-hints" + alias = "OS-SCH-HNT" namespace = ("http://docs.openstack.org/compute/ext/" "scheduler-hints/api/v2") updated = "2011-07-19T00:00:00+00:00" diff --git a/nova/api/openstack/compute/servers.py b/nova/api/openstack/compute/servers.py index 5cb7369c0093..c9bc4430e209 100644 --- a/nova/api/openstack/compute/servers.py +++ b/nova/api/openstack/compute/servers.py @@ -171,7 +171,7 @@ class CommonDeserializer(wsgi.MetadataXMLDeserializer): scheduler_hints = self._extract_scheduler_hints(server_node) if scheduler_hints: - server['os:scheduler_hints'] = scheduler_hints + server['OS-SCH-HNT:scheduler_hints'] = scheduler_hints metadata_node = self.find_first_child_named(server_node, "metadata") if metadata_node is not None: @@ -193,19 +193,34 @@ class CommonDeserializer(wsgi.MetadataXMLDeserializer): if security_groups is not None: server["security_groups"] = security_groups + # 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. auto_disk_config = server_node.getAttribute('auto_disk_config') if auto_disk_config: - server['auto_disk_config'] = utils.bool_from_str(auto_disk_config) + server['OS-DCF:diskConfig'] = utils.bool_from_str(auto_disk_config) + + auto_disk_config = server_node.getAttribute('OS-DCF:diskConfig') + if auto_disk_config: + server['OS-DCF:diskConfig'] = utils.bool_from_str(auto_disk_config) return server def _extract_scheduler_hints(self, server_node): """Marshal the scheduler hints attribute of a parsed request""" - node = self.find_first_child_named(server_node, "scheduler_hints") + node = self.find_first_child_named(server_node, + "OS-SCH-HNT:scheduler_hints") + # NOTE(vish): Support the os: prefix because it is what we use + # for json, even though OS-SCH-HNT: is more correct + if not node: + node = self.find_first_child_named(server_node, + "os:scheduler_hints") if node: scheduler_hints = {} for child in self.extract_elements(node): - scheduler_hints[child.nodeName] = self.extract_text(child) + scheduler_hints.setdefault(child.nodeName, []) + value = self.extract_text(child).strip() + scheduler_hints[child.nodeName].append(value) return scheduler_hints else: return None @@ -774,7 +789,7 @@ class Controller(wsgi.Controller): auto_disk_config = server_dict.get('auto_disk_config') scheduler_hints = {} - if self.ext_mgr.is_loaded('os-scheduler-hints'): + if self.ext_mgr.is_loaded('OS-SCH-HNT'): scheduler_hints = server_dict.get('scheduler_hints', {}) try: diff --git a/nova/tests/api/openstack/compute/test_servers.py b/nova/tests/api/openstack/compute/test_servers.py index 0aa628d96013..bde59592b6fb 100644 --- a/nova/tests/api/openstack/compute/test_servers.py +++ b/nova/tests/api/openstack/compute/test_servers.py @@ -1972,7 +1972,7 @@ class ServersControllerCreateTest(test.TestCase): self._test_create_extra(params) def test_create_instance_with_scheduler_hints_enabled(self): - self.ext_mgr.extensions = {'os-scheduler-hints': 'fake'} + self.ext_mgr.extensions = {'OS-SCH-HNT': 'fake'} hints = {'a': 'b'} params = {'scheduler_hints': hints} old_create = nova.compute.api.API.create @@ -3288,6 +3288,51 @@ class TestServerCreateRequestXMLDeserializer(test.TestCase): }} self.assertEquals(request['body'], expected) + def test_request_with_disk_config(self): + serial_request = """ + + """ + request = self.deserializer.deserialize(serial_request) + expected = {"server": { + "name": "new-server-test", + "imageRef": "1", + "flavorRef": "1", + "OS-DCF:diskConfig": True, + }} + self.assertEquals(request['body'], expected) + + def test_request_with_scheduler_hints(self): + serial_request = """ + + + + 7329b667-50c7-46a6-b913-cb2a09dfeee0 + + + f31efb24-34d2-43e1-8b44-316052956a39 + + + """ + request = self.deserializer.deserialize(serial_request) + expected = {"server": { + "name": "new-server-test", + "imageRef": "1", + "flavorRef": "1", + "OS-SCH-HNT:scheduler_hints": { + "different_host": [ + "7329b667-50c7-46a6-b913-cb2a09dfeee0", + "f31efb24-34d2-43e1-8b44-316052956a39", + ] + } + }} + self.assertEquals(request['body'], expected) + class TestAddressesXMLSerialization(test.TestCase): diff --git a/nova/tests/integrated/api_samples/os-scheduler-hints/scheduler-hints-post-req.json.tpl b/nova/tests/integrated/api_samples/OS-SCH-HNT/scheduler-hints-post-req.json.tpl similarity index 100% rename from nova/tests/integrated/api_samples/os-scheduler-hints/scheduler-hints-post-req.json.tpl rename to nova/tests/integrated/api_samples/OS-SCH-HNT/scheduler-hints-post-req.json.tpl diff --git a/nova/tests/integrated/api_samples/OS-SCH-HNT/scheduler-hints-post-req.xml.tpl b/nova/tests/integrated/api_samples/OS-SCH-HNT/scheduler-hints-post-req.xml.tpl new file mode 100644 index 000000000000..a680e3476ed7 --- /dev/null +++ b/nova/tests/integrated/api_samples/OS-SCH-HNT/scheduler-hints-post-req.xml.tpl @@ -0,0 +1,12 @@ + + + xen + %(image_near)s + + diff --git a/nova/tests/integrated/api_samples/os-scheduler-hints/scheduler-hints-post-resp.json.tpl b/nova/tests/integrated/api_samples/OS-SCH-HNT/scheduler-hints-post-resp.json.tpl similarity index 100% rename from nova/tests/integrated/api_samples/os-scheduler-hints/scheduler-hints-post-resp.json.tpl rename to nova/tests/integrated/api_samples/OS-SCH-HNT/scheduler-hints-post-resp.json.tpl diff --git a/nova/tests/integrated/api_samples/os-scheduler-hints/scheduler-hints-post-resp.xml.tpl b/nova/tests/integrated/api_samples/OS-SCH-HNT/scheduler-hints-post-resp.xml.tpl similarity index 100% rename from nova/tests/integrated/api_samples/os-scheduler-hints/scheduler-hints-post-resp.xml.tpl rename to nova/tests/integrated/api_samples/OS-SCH-HNT/scheduler-hints-post-resp.xml.tpl diff --git a/nova/tests/integrated/api_samples/all_extensions/extensions-get-resp.json.tpl b/nova/tests/integrated/api_samples/all_extensions/extensions-get-resp.json.tpl index 62f6a8ececb9..f566a5020ff2 100644 --- a/nova/tests/integrated/api_samples/all_extensions/extensions-get-resp.json.tpl +++ b/nova/tests/integrated/api_samples/all_extensions/extensions-get-resp.json.tpl @@ -48,6 +48,14 @@ "namespace": "http://docs.openstack.org/compute/ext/flavor_extra_data/api/v1.1", "updated": "%(timestamp)s" }, + { + "alias": "OS-SCH-HNT", + "description": "%(text)s", + "links": [], + "name": "SchedulerHints", + "namespace": "http://docs.openstack.org/compute/ext/scheduler-hints/api/v2", + "updated": "%(timestamp)s" + }, { "alias": "os-admin-actions", "description": "%(text)s", @@ -264,14 +272,6 @@ "namespace": "http://docs.openstack.org/compute/ext/rescue/api/v1.1", "updated": "%(timestamp)s" }, - { - "alias": "os-scheduler-hints", - "description": "%(text)s", - "links": [], - "name": "SchedulerHints", - "namespace": "http://docs.openstack.org/compute/ext/scheduler-hints/api/v2", - "updated": "%(timestamp)s" - }, { "alias": "os-security-groups", "description": "%(text)s", diff --git a/nova/tests/integrated/api_samples/all_extensions/extensions-get-resp.xml.tpl b/nova/tests/integrated/api_samples/all_extensions/extensions-get-resp.xml.tpl index cc79f8e84007..20e650d7c48a 100644 --- a/nova/tests/integrated/api_samples/all_extensions/extensions-get-resp.xml.tpl +++ b/nova/tests/integrated/api_samples/all_extensions/extensions-get-resp.xml.tpl @@ -18,6 +18,9 @@ %(text)s + + %(text)s + %(text)s @@ -99,9 +102,6 @@ %(text)s - - %(text)s - %(text)s diff --git a/nova/tests/integrated/api_samples/os-scheduler-hints/scheduler-hints-post-req.xml.tpl b/nova/tests/integrated/api_samples/os-scheduler-hints/scheduler-hints-post-req.xml.tpl deleted file mode 100644 index 66327c534b41..000000000000 --- a/nova/tests/integrated/api_samples/os-scheduler-hints/scheduler-hints-post-req.xml.tpl +++ /dev/null @@ -1,10 +0,0 @@ - - - xen - %(image_near)s - -