[openstack-nova] fix an exception when querying a server through the API (#803905)

Pádraig Brady pbrady at fedoraproject.org
Fri Mar 16 23:35:00 UTC 2012


commit a655c414b6ed7c9bc5bafad2b3e96c6e73ca7899
Author: Pádraig Brady <P at draigBrady.com>
Date:   Fri Mar 16 23:04:08 2012 +0000

    fix an exception when querying a server through the API (#803905)

 ...-representation-of-ext_srv_attr-extension.patch |  349 ++++++++++++++++++++
 openstack-nova.spec                                |    3 +
 2 files changed, 352 insertions(+), 0 deletions(-)
---
diff --git a/0007-Fixes-xml-representation-of-ext_srv_attr-extension.patch b/0007-Fixes-xml-representation-of-ext_srv_attr-extension.patch
new file mode 100644
index 0000000..6a22090
--- /dev/null
+++ b/0007-Fixes-xml-representation-of-ext_srv_attr-extension.patch
@@ -0,0 +1,349 @@
+From cf7f92fcc755c33f3754a4a5450238cf951f0326 Mon Sep 17 00:00:00 2001
+From: Vishvananda Ishaya <vishvananda at gmail.com>
+Date: Sat, 10 Mar 2012 15:31:55 -0800
+Subject: [PATCH] Fixes xml representation of ext_srv_attr extension
+
+ * adds tests for xml extended_server_attributes
+ * modifies extended_status to match
+ * fixes bug 951863
+
+Change-Id: I54aa55bac9ce62b071e62c510ba1b71f1d5b1288
+---
+ .../compute/contrib/extended_server_attributes.py  |    2 +-
+ .../contrib/test_extended_server_attributes.py     |   36 +++++--
+ .../compute/contrib/test_extended_status.py        |  120 ++++++++++++++++++++
+ .../compute/contrib/test_extendedstatus.py         |  101 ----------------
+ 4 files changed, 149 insertions(+), 110 deletions(-)
+ create mode 100644 nova/tests/api/openstack/compute/contrib/test_extended_status.py
+ delete mode 100644 nova/tests/api/openstack/compute/contrib/test_extendedstatus.py
+
+diff --git a/nova/api/openstack/compute/contrib/extended_server_attributes.py b/nova/api/openstack/compute/contrib/extended_server_attributes.py
+index 102477d..cacd0c9 100644
+--- a/nova/api/openstack/compute/contrib/extended_server_attributes.py
++++ b/nova/api/openstack/compute/contrib/extended_server_attributes.py
+@@ -57,7 +57,7 @@ class ExtendedServerAttributesController(wsgi.Controller):
+         context = req.environ['nova.context']
+         if authorize(context):
+             # Attach our slave template to the response object
+-            resp_obj.attach(xml=ExtendedServerAttributesTemplate())
++            resp_obj.attach(xml=ExtendedServerAttributeTemplate())
+ 
+             try:
+                 instance = self.compute_api.get(context, id)
+diff --git a/nova/tests/api/openstack/compute/contrib/test_extended_server_attributes.py b/nova/tests/api/openstack/compute/contrib/test_extended_server_attributes.py
+index 9944fc0..80fb5ea 100644
+--- a/nova/tests/api/openstack/compute/contrib/test_extended_server_attributes.py
++++ b/nova/tests/api/openstack/compute/contrib/test_extended_server_attributes.py
+@@ -16,7 +16,9 @@
+ import json
+ 
+ import webob
++from lxml import etree
+ 
++from nova.api.openstack.compute.contrib import extended_server_attributes
+ from nova import compute
+ from nova import exception
+ from nova import flags
+@@ -44,6 +46,8 @@ def fake_compute_get_all(*args, **kwargs):
+ 
+ 
+ class ExtendedServerAttributesTest(test.TestCase):
++    content_type = 'application/json'
++    prefix = 'OS-EXT-SRV-ATTR:'
+ 
+     def setUp(self):
+         super(ExtendedServerAttributesTest, self).setUp()
+@@ -53,32 +57,36 @@ class ExtendedServerAttributesTest(test.TestCase):
+ 
+     def _make_request(self, url):
+         req = webob.Request.blank(url)
+-        req.headers['Accept'] = 'application/json'
++        req.headers['Accept'] = self.content_type
+         res = req.get_response(fakes.wsgi_app())
+         return res
+ 
++    def _get_server(self, body):
++        return json.loads(body).get('server')
++
++    def _get_servers(self, body):
++        return json.loads(body).get('servers')
++
+     def assertServerAttributes(self, server, host, instance_name):
+-        self.assertEqual(server.get('OS-EXT-SRV-ATTR:host'), host)
+-        self.assertEqual(server.get('OS-EXT-SRV-ATTR:instance_name'),
+-                                    instance_name)
++        self.assertEqual(server.get('%shost' % self.prefix), host)
++        self.assertEqual(server.get('%sinstance_name' % self.prefix),
++                         instance_name)
+ 
+     def test_show(self):
+         url = '/v2/fake/servers/%s' % UUID3
+         res = self._make_request(url)
+-        body = json.loads(res.body)
+ 
+         self.assertEqual(res.status_int, 200)
+-        self.assertServerAttributes(body['server'],
++        self.assertServerAttributes(self._get_server(res.body),
+                                 host='host-fake',
+                                 instance_name='instance-1')
+ 
+     def test_detail(self):
+         url = '/v2/fake/servers/detail'
+         res = self._make_request(url)
+-        body = json.loads(res.body)
+ 
+         self.assertEqual(res.status_int, 200)
+-        for i, server in enumerate(body['servers']):
++        for i, server in enumerate(self._get_servers(res.body)):
+             self.assertServerAttributes(server,
+                                     host='host-%s' % (i + 1),
+                                     instance_name='instance-%s' % (i + 1))
+@@ -93,3 +101,15 @@ class ExtendedServerAttributesTest(test.TestCase):
+         res = self._make_request(url)
+ 
+         self.assertEqual(res.status_int, 404)
++
++
++class ExtendedServerAttributesXmlTest(ExtendedServerAttributesTest):
++    content_type = 'application/xml'
++    ext = extended_server_attributes
++    prefix = '{%s}' % ext.Extended_server_attributes.namespace
++
++    def _get_server(self, body):
++        return etree.XML(body)
++
++    def _get_servers(self, body):
++        return etree.XML(body).getchildren()
+diff --git a/nova/tests/api/openstack/compute/contrib/test_extended_status.py b/nova/tests/api/openstack/compute/contrib/test_extended_status.py
+new file mode 100644
+index 0000000..b63c08c
+--- /dev/null
++++ b/nova/tests/api/openstack/compute/contrib/test_extended_status.py
+@@ -0,0 +1,120 @@
++# Copyright 2011 OpenStack LLC.
++# All Rights Reserved.
++#
++#    Licensed under the Apache License, Version 2.0 (the "License"); you may
++#    not use this file except in compliance with the License. You may obtain
++#    a copy of the License at
++#
++#         http://www.apache.org/licenses/LICENSE-2.0
++#
++#    Unless required by applicable law or agreed to in writing, software
++#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
++#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
++#    License for the specific language governing permissions and limitations
++#    under the License.
++
++import json
++
++import webob
++from lxml import etree
++
++from nova.api.openstack.compute.contrib import extended_status
++from nova import compute
++from nova import exception
++from nova import flags
++from nova import test
++from nova.tests.api.openstack import fakes
++
++
++FLAGS = flags.FLAGS
++
++
++UUID1 = '00000000-0000-0000-0000-000000000001'
++UUID2 = '00000000-0000-0000-0000-000000000002'
++UUID3 = '00000000-0000-0000-0000-000000000003'
++
++
++def fake_compute_get(*args, **kwargs):
++    return fakes.stub_instance(1, uuid=UUID3, task_state="kayaking",
++            vm_state="slightly crunchy", power_state="empowered")
++
++
++def fake_compute_get_all(*args, **kwargs):
++    return [
++        fakes.stub_instance(1, uuid=UUID1, task_state="task-1",
++                vm_state="vm-1", power_state="power-1"),
++        fakes.stub_instance(2, uuid=UUID2, task_state="task-2",
++                vm_state="vm-2", power_state="power-2"),
++    ]
++
++
++class ExtendedStatusTest(test.TestCase):
++    content_type = 'application/json'
++    prefix = 'OS-EXT-STS:'
++
++    def setUp(self):
++        super(ExtendedStatusTest, self).setUp()
++        fakes.stub_out_nw_api(self.stubs)
++        self.stubs.Set(compute.api.API, 'get', fake_compute_get)
++        self.stubs.Set(compute.api.API, 'get_all', fake_compute_get_all)
++
++    def _make_request(self, url):
++        req = webob.Request.blank(url)
++        req.headers['Accept'] = self.content_type
++        res = req.get_response(fakes.wsgi_app())
++        return res
++
++    def _get_server(self, body):
++        return json.loads(body).get('server')
++
++    def _get_servers(self, body):
++        return json.loads(body).get('servers')
++
++    def assertServerStates(self, server, vm_state, power_state, task_state):
++        self.assertEqual(server.get('%svm_state' % self.prefix), vm_state)
++        self.assertEqual(server.get('%spower_state' % self.prefix),
++                         power_state)
++        self.assertEqual(server.get('%stask_state' % self.prefix), task_state)
++
++    def test_show(self):
++        url = '/v2/fake/servers/%s' % UUID3
++        res = self._make_request(url)
++
++        self.assertEqual(res.status_int, 200)
++        self.assertServerStates(self._get_server(res.body),
++                                vm_state='slightly crunchy',
++                                power_state='empowered',
++                                task_state='kayaking')
++
++    def test_detail(self):
++        url = '/v2/fake/servers/detail'
++        res = self._make_request(url)
++
++        self.assertEqual(res.status_int, 200)
++        for i, server in enumerate(self._get_servers(res.body)):
++            self.assertServerStates(server,
++                                    vm_state='vm-%s' % (i + 1),
++                                    power_state='power-%s' % (i + 1),
++                                    task_state='task-%s' % (i + 1))
++
++    def test_no_instance_passthrough_404(self):
++
++        def fake_compute_get(*args, **kwargs):
++            raise exception.InstanceNotFound()
++
++        self.stubs.Set(compute.api.API, 'get', fake_compute_get)
++        url = '/v2/fake/servers/70f6db34-de8d-4fbd-aafb-4065bdfa6115'
++        res = self._make_request(url)
++
++        self.assertEqual(res.status_int, 404)
++
++
++class ExtendedStatusXmlTest(ExtendedStatusTest):
++    content_type = 'application/xml'
++    prefix = '{%s}' % extended_status.Extended_status.namespace
++
++    def _get_server(self, body):
++        return etree.XML(body)
++
++    def _get_servers(self, body):
++        return etree.XML(body).getchildren()
+diff --git a/nova/tests/api/openstack/compute/contrib/test_extendedstatus.py b/nova/tests/api/openstack/compute/contrib/test_extendedstatus.py
+deleted file mode 100644
+index ba832cf..0000000
+--- a/nova/tests/api/openstack/compute/contrib/test_extendedstatus.py
++++ /dev/null
+@@ -1,101 +0,0 @@
+-# Copyright 2011 OpenStack LLC.
+-# All Rights Reserved.
+-#
+-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+-#    not use this file except in compliance with the License. You may obtain
+-#    a copy of the License at
+-#
+-#         http://www.apache.org/licenses/LICENSE-2.0
+-#
+-#    Unless required by applicable law or agreed to in writing, software
+-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+-#    License for the specific language governing permissions and limitations
+-#    under the License.
+-
+-import json
+-
+-import webob
+-
+-from nova import compute
+-from nova import exception
+-from nova import flags
+-from nova import test
+-from nova.tests.api.openstack import fakes
+-
+-
+-FLAGS = flags.FLAGS
+-
+-
+-UUID1 = '70f6db34-de8d-4fbd-aafb-4065bdfa6114'
+-UUID2 = '65ba6da7-3b9a-4b71-bc08-f81fbdb72d1a'
+-UUID3 = 'b55c356f-4c22-47ed-b622-cc6ba0f4b1ab'
+-
+-
+-def fake_compute_get(*args, **kwargs):
+-    return fakes.stub_instance(1, uuid=UUID3, task_state="kayaking",
+-            vm_state="slightly crunchy", power_state="empowered")
+-
+-
+-def fake_compute_get_all(*args, **kwargs):
+-    return [
+-        fakes.stub_instance(1, uuid=UUID1, task_state="task%s" % UUID1,
+-                vm_state="vm%s" % UUID1, power_state="power%s" % UUID1),
+-        fakes.stub_instance(2, uuid=UUID2, task_state="task%s" % UUID2,
+-                vm_state="vm%s" % UUID2, power_state="power%s" % UUID2),
+-    ]
+-
+-
+-class ExtendedStatusTest(test.TestCase):
+-
+-    def setUp(self):
+-        super(ExtendedStatusTest, self).setUp()
+-        fakes.stub_out_nw_api(self.stubs)
+-        self.stubs.Set(compute.api.API, 'get', fake_compute_get)
+-        self.stubs.Set(compute.api.API, 'get_all', fake_compute_get_all)
+-
+-    def _make_request(self, url):
+-        req = webob.Request.blank(url)
+-        req.headers['Accept'] = 'application/json'
+-        res = req.get_response(fakes.wsgi_app())
+-        return res
+-
+-    def assertServerStates(self, server, vm_state, power_state, task_state):
+-        self.assertEqual(server.get('OS-EXT-STS:vm_state'), vm_state)
+-        self.assertEqual(server.get('OS-EXT-STS:power_state'), power_state)
+-        self.assertEqual(server.get('OS-EXT-STS:task_state'), task_state)
+-
+-    def test_show(self):
+-        url = '/v2/fake/servers/%s' % UUID3
+-        res = self._make_request(url)
+-        body = json.loads(res.body)
+-
+-        self.assertEqual(res.status_int, 200)
+-        self.assertServerStates(body['server'],
+-                                vm_state='slightly crunchy',
+-                                power_state='empowered',
+-                                task_state='kayaking')
+-
+-    def test_detail(self):
+-        url = '/v2/fake/servers/detail'
+-        res = self._make_request(url)
+-        body = json.loads(res.body)
+-
+-        self.assertEqual(res.status_int, 200)
+-        for server in body['servers']:
+-            sid = server['id']
+-            self.assertServerStates(server,
+-                                    vm_state='vm%s' % sid,
+-                                    power_state='power%s' % sid,
+-                                    task_state='task%s' % sid)
+-
+-    def test_no_instance_passthrough_404(self):
+-
+-        def fake_compute_get(*args, **kwargs):
+-            raise exception.InstanceNotFound()
+-
+-        self.stubs.Set(compute.api.API, 'get', fake_compute_get)
+-        url = '/v2/fake/servers/70f6db34-de8d-4fbd-aafb-4065bdfa6115'
+-        res = self._make_request(url)
+-
+-        self.assertEqual(res.status_int, 404)
diff --git a/openstack-nova.spec b/openstack-nova.spec
index bacab4e..b84c78d 100644
--- a/openstack-nova.spec
+++ b/openstack-nova.spec
@@ -40,6 +40,7 @@ Patch0003: 0003-Adds-soft-reboot-support-to-libvirt.patch
 Patch0004: 0004-Allows-new-style-config-to-be-used-for-flagfile.patch
 Patch0005: 0005-Fix-_sync_power_states-to-obtain-correct-state.patch
 Patch0006: 0006-nonblocking-libvirt-mode-using-tpool.patch
+Patch0007: 0007-Fixes-xml-representation-of-ext_srv_attr-extension.patch
 
 BuildArch:        noarch
 BuildRequires:    intltool
@@ -181,6 +182,7 @@ This package contains documentation files for nova.
 %patch0004 -p1
 %patch0005 -p1
 %patch0006 -p1
+%patch0007 -p1
 
 find . \( -name .gitignore -o -name .placeholder \) -delete
 
@@ -374,6 +376,7 @@ fi
 * Fri Mar  8 2012 Pádraig Brady <P at draigBrady.com> - 2012.1-0.8.e4
 - Include an upstream fix for errors logged when syncing power states
 - Support non blocking libvirt operations
+- Fix an exception when querying a server through the API (#803905)
 
 * Fri Mar  6 2012 Alan Pevec <apevec at redhat.com> - 2012.1-0.7.e4
 - Fixup permissions on nova config files


More information about the scm-commits mailing list