From 96136435f13936574a67955fbca9134ceb565df2 Mon Sep 17 00:00:00 2001 From: Mate Lakat Date: Tue, 25 Sep 2012 16:00:31 +0100 Subject: [PATCH] Fix XenServer's ability to boot xen type images Fixes bug 1055431. As the scheduler wants to boot a vm_mode=xen type of image, the host's "supported_instances" capability is used for finding a good candidate. In the Xapi case, this field was not populated. This fix modifies the xapi xenhost plugin, so the Xen host capabilities are returned back to the compute node, as "host_capabilities". On the compute side, the mentioned information is used, to extract the "supported_instances" information. Change-Id: I2da11ab81f74b5b52e2c30832a694470978e21b0 --- nova/tests/test_xenapi.py | 38 +++++++++++++++++++ nova/virt/xenapi/host.py | 19 ++++++++++ .../xenapi/etc/xapi.d/plugins/xenhost | 4 +- 3 files changed, 60 insertions(+), 1 deletion(-) diff --git a/nova/tests/test_xenapi.py b/nova/tests/test_xenapi.py index b543f3e0f68..a6adb751e6a 100644 --- a/nova/tests/test_xenapi.py +++ b/nova/tests/test_xenapi.py @@ -44,6 +44,7 @@ from nova.virt.xenapi import agent from nova.virt.xenapi import driver as xenapi_conn from nova.virt.xenapi import fake as xenapi_fake +from nova.virt.xenapi import host from nova.virt.xenapi import pool from nova.virt.xenapi import pool_states from nova.virt.xenapi import vm_utils @@ -1275,6 +1276,43 @@ def test_get_host_uptime(self): result = self.conn.get_host_uptime('host') self.assertEqual(result, 'fake uptime') + def test_supported_instances_is_included_in_host_state(self): + stats = self.conn.get_host_stats() + self.assertTrue('supported_instances' in stats) + + def test_supported_instances_is_calculated_by_to_supported_instances(self): + + def to_supported_instances(somedata): + self.assertEquals(None, somedata) + return "SOMERETURNVALUE" + self.stubs.Set(host, 'to_supported_instances', to_supported_instances) + + stats = self.conn.get_host_stats() + self.assertEquals("SOMERETURNVALUE", stats['supported_instances']) + + +class ToSupportedInstancesTestCase(test.TestCase): + def test_default_return_value(self): + self.assertEquals([], + host.to_supported_instances(None)) + + def test_return_value(self): + self.assertEquals([('x86_64', 'xapi', 'xen')], + host.to_supported_instances([u'xen-3.0-x86_64'])) + + def test_invalid_values_do_not_break(self): + self.assertEquals([('x86_64', 'xapi', 'xen')], + host.to_supported_instances([u'xen-3.0-x86_64', 'spam'])) + + def test_multiple_values(self): + self.assertEquals( + [ + ('x86_64', 'xapi', 'xen'), + ('x86_32', 'xapi', 'hvm') + ], + host.to_supported_instances([u'xen-3.0-x86_64', 'hvm-3.0-x86_32']) + ) + class XenAPIAutoDiskConfigTestCase(stubs.XenAPITestBase): def setUp(self): diff --git a/nova/virt/xenapi/host.py b/nova/virt/xenapi/host.py index 9db7089253b..b4361ae0342 100644 --- a/nova/virt/xenapi/host.py +++ b/nova/virt/xenapi/host.py @@ -162,6 +162,9 @@ def update_status(self): data["disk_total"] = total data["disk_used"] = used data["disk_available"] = total - used + data["supported_instances"] = to_supported_instances( + data.get("host_capabilities") + ) host_memory = data.get('host_memory', None) if host_memory: data["host_memory_total"] = host_memory.get('total', 0) @@ -173,6 +176,22 @@ def update_status(self): self._stats = data +def to_supported_instances(host_capabilities): + if not host_capabilities: + return [] + + result = [] + for capability in host_capabilities: + try: + ostype, _version, arch = capability.split("-") + result.append((arch, 'xapi', ostype)) + except ValueError: + LOG.warning( + _("Failed to extract instance support from %s"), capability) + + return result + + def call_xenhost(session, method, arg_dict): """There will be several methods that will need this general handling for interacting with the xenhost plugin, so this abstracts diff --git a/plugins/xenserver/xenapi/etc/xapi.d/plugins/xenhost b/plugins/xenserver/xenapi/etc/xapi.d/plugins/xenhost index e556931bbb3..4d219390860 100755 --- a/plugins/xenserver/xenapi/etc/xapi.d/plugins/xenhost +++ b/plugins/xenserver/xenapi/etc/xapi.d/plugins/xenhost @@ -398,7 +398,9 @@ def cleanup(dct): for oc_fld in oc.split("; "): ock, ocv = strip_kv(oc_fld) ocd[ock] = ocv -# out["host_capabilities"] = dct.get("capabilities", "").split("; ") + + capabilities = dct.get("capabilities", "") + out["host_capabilities"] = capabilities.replace(";", "").split() # out["host_allowed-operations"] = dct.get( # "allowed-operations", "").split("; ") # lsrv = dct.get("license-server", "")