From 8fcd1b2c73dad8e2a7b4d299da270934fd5328cc Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Fri, 25 Jul 2014 12:55:40 +0100 Subject: [PATCH] virt: use compute.vm_mode constants and validate vm mode type Where we have hardcoded vm modes, use compute.vm_mode constants. Where we get vm modes from external systems, validate them against the list of acceptable names. The baremetal/ironic drivers are reporting a bogus vm mode of 'baremetal' for supported instances which is confusing the vm mode with the Nova driver type. These drivers use the native ABI for their architecture, so should be reporting 'hvm' as the vm mode, which indicates an unmodified native OS ABI. On the other side, the ImagePropertiesFilter will canonicalize the hvtype it fetches from image metadata, so that 'baremetal' gets remapped to 'hvm' during comparison. Closes-bug: #1348629 Change-Id: Ibda7c5ab0759aee672870d84974ccdea25f14407 --- nova/compute/vm_mode.py | 3 ++ nova/tests/compute/test_vmmode.py | 4 ++ nova/tests/scheduler/test_host_filters.py | 55 ++++++++++++++--------- nova/tests/virt/baremetal/test_driver.py | 2 +- nova/virt/baremetal/driver.py | 3 +- nova/virt/hyperv/hostops.py | 5 ++- nova/virt/ironic/driver.py | 6 ++- nova/virt/libvirt/driver.py | 2 +- nova/virt/vmwareapi/host.py | 5 ++- nova/virt/xenapi/host.py | 2 + 10 files changed, 59 insertions(+), 28 deletions(-) diff --git a/nova/compute/vm_mode.py b/nova/compute/vm_mode.py index dd2706c7643d..d42eea2079f8 100644 --- a/nova/compute/vm_mode.py +++ b/nova/compute/vm_mode.py @@ -78,6 +78,9 @@ def canonicalize(mode): if mode == "hv": mode = HVM + if mode == "baremetal": + mode = HVM + if not is_valid(mode): raise exception.InvalidVirtualMachineMode(vmmode=mode) diff --git a/nova/tests/compute/test_vmmode.py b/nova/tests/compute/test_vmmode.py index ce05d2cbb8bc..67475ecbb39e 100644 --- a/nova/tests/compute/test_vmmode.py +++ b/nova/tests/compute/test_vmmode.py @@ -53,6 +53,10 @@ class ComputeVMModeTest(test.NoDBTestCase): mode = vm_mode.canonicalize('hv') self.assertEqual(vm_mode.HVM, mode) + def test_name_baremetal_compat(self): + mode = vm_mode.canonicalize('baremetal') + self.assertEqual(vm_mode.HVM, mode) + def test_name_hvm(self): mode = vm_mode.canonicalize('hvm') self.assertEqual(vm_mode.HVM, mode) diff --git a/nova/tests/scheduler/test_host_filters.py b/nova/tests/scheduler/test_host_filters.py index e2426fb28221..ffe751f24e86 100644 --- a/nova/tests/scheduler/test_host_filters.py +++ b/nova/tests/scheduler/test_host_filters.py @@ -24,6 +24,7 @@ import stubout from nova.compute import arch from nova.compute import hvtype +from nova.compute import vm_mode from nova import context from nova import db from nova import objects @@ -678,13 +679,13 @@ class HostFiltersTestCase(test.NoDBTestCase): filt_cls = self.class_map['ImagePropertiesFilter']() img_props = {'properties': {'_architecture': arch.X86_64, 'hypervisor_type': hvtype.KVM, - 'vm_mode': 'hvm', + 'vm_mode': vm_mode.HVM, 'hypervisor_version_requires': '>=6.0,<6.2' }} filter_properties = {'request_spec': {'image': img_props}} hypervisor_version = utils.convert_version_to_int('6.0.0') capabilities = {'supported_instances': - [(arch.X86_64, hvtype.KVM, 'hvm')], + [(arch.X86_64, hvtype.KVM, vm_mode.HVM)], 'hypervisor_version': hypervisor_version} host = fakes.FakeHostState('host1', 'node1', capabilities) self.assertTrue(filt_cls.host_passes(host, filter_properties)) @@ -694,11 +695,11 @@ class HostFiltersTestCase(test.NoDBTestCase): filt_cls = self.class_map['ImagePropertiesFilter']() img_props = {'properties': {'architecture': arch.ARMV7, 'hypervisor_type': hvtype.QEMU, - 'vm_mode': 'hvm'}} + 'vm_mode': vm_mode.HVM}} filter_properties = {'request_spec': {'image': img_props}} hypervisor_version = utils.convert_version_to_int('6.0.0') capabilities = {'supported_instances': - [(arch.X86_64, hvtype.KVM, 'hvm')], + [(arch.X86_64, hvtype.KVM, vm_mode.HVM)], 'hypervisor_version': hypervisor_version} host = fakes.FakeHostState('host1', 'node1', capabilities) self.assertFalse(filt_cls.host_passes(host, filter_properties)) @@ -708,13 +709,13 @@ class HostFiltersTestCase(test.NoDBTestCase): filt_cls = self.class_map['ImagePropertiesFilter']() img_props = {'properties': {'architecture': arch.X86_64, 'hypervisor_type': hvtype.KVM, - 'vm_mode': 'hvm', + 'vm_mode': vm_mode.HVM, 'hypervisor_version_requires': '>=6.2'}} filter_properties = {'request_spec': {'image': img_props}} hypervisor_version = utils.convert_version_to_int('6.0.0') capabilities = {'enabled': True, 'supported_instances': - [(arch.X86_64, hvtype.KVM, 'hvm')], + [(arch.X86_64, hvtype.KVM, vm_mode.HVM)], 'hypervisor_version': hypervisor_version} host = fakes.FakeHostState('host1', 'node1', capabilities) self.assertFalse(filt_cls.host_passes(host, filter_properties)) @@ -723,11 +724,11 @@ class HostFiltersTestCase(test.NoDBTestCase): self._stub_service_is_up(True) filt_cls = self.class_map['ImagePropertiesFilter']() img_props = {'properties': {'architecture': arch.X86_64, - 'vm_mode': 'hvm'}} + 'vm_mode': vm_mode.HVM}} filter_properties = {'request_spec': {'image': img_props}} hypervisor_version = utils.convert_version_to_int('6.0.0') capabilities = {'supported_instances': - [(arch.X86_64, hvtype.KVM, 'hvm')], + [(arch.X86_64, hvtype.KVM, vm_mode.HVM)], 'hypervisor_version': hypervisor_version} host = fakes.FakeHostState('host1', 'node1', capabilities) self.assertTrue(filt_cls.host_passes(host, filter_properties)) @@ -736,11 +737,11 @@ class HostFiltersTestCase(test.NoDBTestCase): self._stub_service_is_up(True) filt_cls = self.class_map['ImagePropertiesFilter']() img_props = {'properties': {'architecture': arch.X86_64, - 'vm_mode': 'hvm'}} + 'vm_mode': vm_mode.HVM}} filter_properties = {'request_spec': {'image': img_props}} hypervisor_version = utils.convert_version_to_int('6.0.0') capabilities = {'supported_instances': - [(arch.X86_64, hvtype.XEN, 'xen')], + [(arch.X86_64, hvtype.XEN, vm_mode.XEN)], 'hypervisor_version': hypervisor_version} host = fakes.FakeHostState('host1', 'node1', capabilities) self.assertFalse(filt_cls.host_passes(host, filter_properties)) @@ -751,7 +752,7 @@ class HostFiltersTestCase(test.NoDBTestCase): filter_properties = {'request_spec': {}} hypervisor_version = utils.convert_version_to_int('6.0.0') capabilities = {'supported_instances': - [(arch.X86_64, hvtype.KVM, 'hvm')], + [(arch.X86_64, hvtype.KVM, vm_mode.HVM)], 'hypervisor_version': hypervisor_version} host = fakes.FakeHostState('host1', 'node1', capabilities) self.assertTrue(filt_cls.host_passes(host, filter_properties)) @@ -761,7 +762,7 @@ class HostFiltersTestCase(test.NoDBTestCase): filt_cls = self.class_map['ImagePropertiesFilter']() img_props = {'properties': {'architecture': arch.X86_64, 'hypervisor_type': hvtype.KVM, - 'vm_mode': 'hvm'}} + 'vm_mode': vm_mode.HVM}} filter_properties = {'request_spec': {'image': img_props}} hypervisor_version = utils.convert_version_to_int('6.0.0') capabilities = {'enabled': True, @@ -774,12 +775,12 @@ class HostFiltersTestCase(test.NoDBTestCase): filt_cls = self.class_map['ImagePropertiesFilter']() img_props = {'properties': {'architecture': arch.X86_64, 'hypervisor_type': hvtype.KVM, - 'vm_mode': 'hvm', + 'vm_mode': vm_mode.HVM, 'hypervisor_version_requires': '>=6.0'}} filter_properties = {'request_spec': {'image': img_props}} capabilities = {'enabled': True, 'supported_instances': - [(arch.X86_64, hvtype.KVM, 'hvm')]} + [(arch.X86_64, hvtype.KVM, vm_mode.HVM)]} host = fakes.FakeHostState('host1', 'node1', capabilities) self.assertTrue(filt_cls.host_passes(host, filter_properties)) @@ -788,12 +789,12 @@ class HostFiltersTestCase(test.NoDBTestCase): filt_cls = self.class_map['ImagePropertiesFilter']() img_props = {'properties': {'architecture': arch.X86_64, 'hypervisor_type': hvtype.KVM, - 'vm_mode': 'hvm', + 'vm_mode': vm_mode.HVM, 'hypervisor_version_requires': '>=6.0'}} filter_properties = {'request_spec': {'image': img_props}} capabilities = {'enabled': True, 'supported_instances': - [(arch.X86_64, hvtype.KVM, 'hvm')], + [(arch.X86_64, hvtype.KVM, vm_mode.HVM)], 'hypervisor_version': 5000} host = fakes.FakeHostState('host1', 'node1', capabilities) self.assertFalse(filt_cls.host_passes(host, filter_properties)) @@ -806,7 +807,7 @@ class HostFiltersTestCase(test.NoDBTestCase): filter_properties = {'request_spec': {'image': img_props}} hypervisor_version = utils.convert_version_to_int('6.0.0') capabilities = {'supported_instances': - [(arch.X86_64, hvtype.XEN, 'xen')], + [(arch.X86_64, hvtype.XEN, vm_mode.XEN)], 'hypervisor_version': hypervisor_version} host = fakes.FakeHostState('host1', 'node1', capabilities) self.assertTrue(filt_cls.host_passes(host, filter_properties)) @@ -819,7 +820,7 @@ class HostFiltersTestCase(test.NoDBTestCase): filter_properties = {'request_spec': {'image': img_props}} hypervisor_version = utils.convert_version_to_int('6.0.0') capabilities = {'supported_instances': - [(arch.X86_64, hvtype.KVM, 'hvm')], + [(arch.X86_64, hvtype.KVM, vm_mode.HVM)], 'hypervisor_version': hypervisor_version} host = fakes.FakeHostState('host1', 'node1', capabilities) self.assertTrue(filt_cls.host_passes(host, filter_properties)) @@ -832,7 +833,7 @@ class HostFiltersTestCase(test.NoDBTestCase): filter_properties = {'request_spec': {'image': img_props}} hypervisor_version = utils.convert_version_to_int('6.0.0') capabilities = {'supported_instances': - [(arch.I686, hvtype.KVM, 'hvm')], + [(arch.I686, hvtype.KVM, vm_mode.HVM)], 'hypervisor_version': hypervisor_version} host = fakes.FakeHostState('host1', 'node1', capabilities) self.assertTrue(filt_cls.host_passes(host, filter_properties)) @@ -845,7 +846,21 @@ class HostFiltersTestCase(test.NoDBTestCase): filter_properties = {'request_spec': {'image': img_props}} hypervisor_version = utils.convert_version_to_int('6.0.0') capabilities = {'supported_instances': - [(arch.I686, hvtype.XEN, 'hvm')], + [(arch.I686, hvtype.XEN, vm_mode.HVM)], + 'hypervisor_version': hypervisor_version} + host = fakes.FakeHostState('host1', 'node1', capabilities) + self.assertTrue(filt_cls.host_passes(host, filter_properties)) + + def test_image_properties_filter_baremetal_vmmode_compat(self): + # if an old image has 'baremetal' for vmmode it should be + # treated as hvm + self._stub_service_is_up(True) + filt_cls = self.class_map['ImagePropertiesFilter']() + img_props = {'properties': {'vm_mode': 'baremetal'}} + filter_properties = {'request_spec': {'image': img_props}} + hypervisor_version = utils.convert_version_to_int('6.0.0') + capabilities = {'supported_instances': + [(arch.I686, hvtype.BAREMETAL, vm_mode.HVM)], 'hypervisor_version': hypervisor_version} host = fakes.FakeHostState('host1', 'node1', capabilities) self.assertTrue(filt_cls.host_passes(host, filter_properties)) diff --git a/nova/tests/virt/baremetal/test_driver.py b/nova/tests/virt/baremetal/test_driver.py index b13df0c89c43..ec3ccfea77b0 100644 --- a/nova/tests/virt/baremetal/test_driver.py +++ b/nova/tests/virt/baremetal/test_driver.py @@ -397,7 +397,7 @@ class BareMetalDriverWithDBTestCase(bm_db_base.BMDBTestCase): node['node_info']['memory_mb']) self.assertEqual(resources['memory_mb_used'], 0) self.assertEqual(resources['supported_instances'], - '[["x86_64", "baremetal", "baremetal"]]') + '[["x86_64", "baremetal", "hvm"]]') self.assertEqual(resources['stats'], '{"cpu_arch": "x86_64", "baremetal_driver": ' '"nova.virt.baremetal.fake.FakeDriver", ' diff --git a/nova/virt/baremetal/driver.py b/nova/virt/baremetal/driver.py index 98646eb5031f..84ec7b05926b 100644 --- a/nova/virt/baremetal/driver.py +++ b/nova/virt/baremetal/driver.py @@ -27,6 +27,7 @@ from nova.compute import flavors from nova.compute import hvtype from nova.compute import power_state from nova.compute import task_states +from nova.compute import vm_mode from nova import context as nova_context from nova import exception from nova.i18n import _ @@ -155,7 +156,7 @@ class BareMetalDriver(driver.ComputeDriver): self.supported_instances = [( arch.canonicalize(extra_specs['cpu_arch']), hvtype.BAREMETAL, - 'baremetal' + vm_mode.HVM ), ] @classmethod diff --git a/nova/virt/hyperv/hostops.py b/nova/virt/hyperv/hostops.py index 3fbfd2853ba8..98d8e4cd0149 100644 --- a/nova/virt/hyperv/hostops.py +++ b/nova/virt/hyperv/hostops.py @@ -25,6 +25,7 @@ from oslo.config import cfg from nova.compute import arch from nova.compute import hvtype +from nova.compute import vm_mode from nova.openstack.common import jsonutils from nova.openstack.common import log as logging from nova.openstack.common import units @@ -131,8 +132,8 @@ class HostOps(object): 'vcpus_used': 0, 'cpu_info': jsonutils.dumps(cpu_info), 'supported_instances': jsonutils.dumps( - [(arch.I686, hvtype.HYPERV, 'hvm'), - (arch.X86_64, hvtype.HYPERV, 'hvm')]), + [(arch.I686, hvtype.HYPERV, vm_mode.HVM), + (arch.X86_64, hvtype.HYPERV, vm_mode.HVM)]), 'numa_topology': None, } diff --git a/nova/virt/ironic/driver.py b/nova/virt/ironic/driver.py index 14a02bf19022..e0c0c067acad 100644 --- a/nova/virt/ironic/driver.py +++ b/nova/virt/ironic/driver.py @@ -27,8 +27,10 @@ from oslo.config import cfg import six from nova.compute import arch +from nova.compute import hvtype from nova.compute import power_state from nova.compute import task_states +from nova.compute import vm_mode from nova import context as nova_context from nova import exception from nova.i18n import _ @@ -120,7 +122,9 @@ def _get_nodes_supported_instances(cpu_arch=None): """Return supported instances for a node.""" if not cpu_arch: return [] - return [(cpu_arch, 'baremetal', 'baremetal')] + return [(cpu_arch, + hvtype.BAREMETAL, + vm_mode.HVM)] def _log_ironic_polling(what, node, instance): diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py index 1499b6b1239f..2a0c75f3317e 100644 --- a/nova/virt/libvirt/driver.py +++ b/nova/virt/libvirt/driver.py @@ -4699,7 +4699,7 @@ class LibvirtDriver(driver.ComputeDriver): instance_cap = ( arch.canonicalize(g.arch), hvtype.canonicalize(dt), - g.ostype) + vm_mode.canonicalize(g.ostype)) instance_caps.append(instance_cap) return instance_caps diff --git a/nova/virt/vmwareapi/host.py b/nova/virt/vmwareapi/host.py index 16fad99e54b0..f398f8ee7088 100644 --- a/nova/virt/vmwareapi/host.py +++ b/nova/virt/vmwareapi/host.py @@ -19,6 +19,7 @@ Management class for host-related functions (start, reboot, etc). from nova.compute import arch from nova.compute import hvtype +from nova.compute import vm_mode from nova import exception from nova.openstack.common import log as logging from nova.openstack.common import units @@ -92,8 +93,8 @@ class HostState(object): str(summary.config.product.version)) data["hypervisor_hostname"] = self._host_name data["supported_instances"] = [ - (arch.I686, hvtype.VMWARE, 'hvm'), - (arch.X86_64, hvtype.VMWARE, 'hvm')] + (arch.I686, hvtype.VMWARE, vm_mode.HVM), + (arch.X86_64, hvtype.VMWARE, vm_mode.HVM)] self._stats = data return data diff --git a/nova/virt/xenapi/host.py b/nova/virt/xenapi/host.py index e8f6d468cb4e..3204d048d526 100644 --- a/nova/virt/xenapi/host.py +++ b/nova/virt/xenapi/host.py @@ -24,6 +24,7 @@ from oslo.config import cfg from nova.compute import arch from nova.compute import hvtype from nova.compute import task_states +from nova.compute import vm_mode from nova.compute import vm_states from nova import context from nova import exception @@ -285,6 +286,7 @@ def to_supported_instances(host_capabilities): ostype, _version, guestarch = capability.split("-") guestarch = arch.canonicalize(guestarch) + ostype = vm_mode.canonicalize(ostype) result.append((guestarch, hvtype.XEN, ostype)) except ValueError: