diff --git a/nova/tests/functional/libvirt/test_machine_type.py b/nova/tests/functional/libvirt/test_machine_type.py
index 3b496189d0bd..04c38b7338a6 100644
--- a/nova/tests/functional/libvirt/test_machine_type.py
+++ b/nova/tests/functional/libvirt/test_machine_type.py
@@ -103,7 +103,7 @@ class LibvirtMachineTypeTest(base.ServersTestBase):
self.computes['compute1'].stop()
self._unset_machine_type(server_without['id'])
- self.flags(hw_machine_type='x86_64=pc-q35-1.2.3', group='libvirt')
+ self.flags(hw_machine_type='x86_64=pc-q35-2.4', group='libvirt')
# Restart the compute
self.computes['compute1'].start()
@@ -115,9 +115,9 @@ class LibvirtMachineTypeTest(base.ServersTestBase):
# is able to pass. This just keeps the tests clean.
self._reboot_server(server_without, hard=True)
- # Assert server_without now has a machine type of pc-q35-1.2.3 picked
+ # Assert server_without now has a machine type of pc-q35-2.4 picked
# up from [libvirt]hw_machine_type during init_host
- self._assert_machine_type(server_without['id'], 'pc-q35-1.2.3')
+ self._assert_machine_type(server_without['id'], 'pc-q35-2.4')
def test_machine_type_after_config_change(self):
"""Assert new instances pick up a new default machine type after the
@@ -129,11 +129,11 @@ class LibvirtMachineTypeTest(base.ServersTestBase):
self._assert_machine_type(server_with['id'], 'q35')
self._assert_machine_type(server_without['id'], 'pc')
- self.flags(hw_machine_type='x86_64=pc-q35-1.2.3', group='libvirt')
+ self.flags(hw_machine_type='x86_64=pc-q35-2.4', group='libvirt')
server_with_new, server_without_new = self._create_servers()
self._assert_machine_type(server_with_new['id'], 'q35')
- self._assert_machine_type(server_without_new['id'], 'pc-q35-1.2.3')
+ self._assert_machine_type(server_without_new['id'], 'pc-q35-2.4')
def test_machine_type_after_server_rebuild(self):
"""Assert that the machine type of an instance changes with a full
@@ -202,26 +202,26 @@ class LibvirtMachineTypeTest(base.ServersTestBase):
)
def test_machine_type_update_stopped(self):
- self.flags(hw_machine_type='x86_64=pc-1.2.3', group='libvirt')
+ self.flags(hw_machine_type='x86_64=pc-1.2', group='libvirt')
server = self._create_server(networks='none')
- self._assert_machine_type(server['id'], 'pc-1.2.3')
+ self._assert_machine_type(server['id'], 'pc-1.2')
self._stop_server(server)
machine_type_utils.update_machine_type(
self.context,
server['id'],
- 'pc-1.2.4'
+ 'pc-1.2'
)
self._start_server(server)
- self._assert_machine_type(server['id'], 'pc-1.2.4')
+ self._assert_machine_type(server['id'], 'pc-1.2')
def test_machine_type_update_blocked_active(self):
- self.flags(hw_machine_type='x86_64=pc-1.2.3', group='libvirt')
+ self.flags(hw_machine_type='x86_64=pc-1.2', group='libvirt')
server = self._create_server(networks='none')
- self._assert_machine_type(server['id'], 'pc-1.2.3')
+ self._assert_machine_type(server['id'], 'pc-1.2')
self.assertRaises(
exception.InstanceInvalidState,
@@ -247,10 +247,10 @@ class LibvirtMachineTypeTest(base.ServersTestBase):
)
def test_machine_type_update_blocked_between_versioned_and_alias(self):
- self.flags(hw_machine_type='x86_64=pc-1.2.3', group='libvirt')
+ self.flags(hw_machine_type='x86_64=pc-1.2', group='libvirt')
server = self._create_server(networks='none')
- self._assert_machine_type(server['id'], 'pc-1.2.3')
+ self._assert_machine_type(server['id'], 'pc-1.2')
self._stop_server(server)
self.assertRaises(
@@ -372,7 +372,7 @@ class LibvirtMachineTypeTest(base.ServersTestBase):
)
# Change the actual config on the compute
- self.flags(hw_machine_type='x86_64=pc-q35-1.2', group='libvirt')
+ self.flags(hw_machine_type='x86_64=pc-q35-2.4', group='libvirt')
# Assert the existing instances remain the same after being rebooted or
# unshelved, rebuilding their domain configs
@@ -389,4 +389,4 @@ class LibvirtMachineTypeTest(base.ServersTestBase):
# Assert that new instances are spawned with the expected machine types
server_with_new, server_without_new = self._create_servers()
self._assert_machine_type(server_with_new['id'], 'q35')
- self._assert_machine_type(server_without_new['id'], 'pc-q35-1.2')
+ self._assert_machine_type(server_without_new['id'], 'pc-q35-2.4')
diff --git a/nova/tests/unit/virt/libvirt/test_driver.py b/nova/tests/unit/virt/libvirt/test_driver.py
index 7233c00a72cc..5f4f20ef4558 100644
--- a/nova/tests/unit/virt/libvirt/test_driver.py
+++ b/nova/tests/unit/virt/libvirt/test_driver.py
@@ -2677,6 +2677,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
self.assertEqual(33550336,
cfg.metadata[0].flavor.swap)
+ @mock.patch.object(host.Host, "_check_machine_type", new=mock.Mock())
def test_get_guest_config_q35(self):
self.flags(virt_type="kvm",
group='libvirt')
@@ -2711,6 +2712,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
self.assertEqual(TEST_AMOUNT_OF_PCIE_SLOTS, num_ports)
+ @mock.patch.object(host.Host, "_check_machine_type", new=mock.Mock())
def test_get_guest_config_pcie_i440fx(self):
self.flags(virt_type="kvm",
group='libvirt')
@@ -2746,6 +2748,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
# i440fx is not pcie machine so there should be no pcie ports
self.assertEqual(0, num_ports)
+ @mock.patch.object(host.Host, "_check_machine_type", new=mock.Mock())
@mock.patch('nova.virt.libvirt.utils.get_default_machine_type',
new=mock.Mock(return_value='config-machine_type'))
def test_get_guest_config_records_machine_type_in_instance(self):
@@ -2957,6 +2960,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
'fake-instance-numa-topology',
'fake-flavor', 'fake-image-meta').obj_to_primitive())
+ @mock.patch.object(host.Host, "_check_machine_type", new=mock.Mock())
@mock.patch.object(
host.Host, "is_cpu_control_policy_capable", return_value=True)
def test_get_guest_config_numa_host_instance_fits(self, is_able):
@@ -2994,6 +2998,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
self.assertEqual(0, len(cfg.cputune.vcpupin))
self.assertIsNone(cfg.cpu.numa)
+ @mock.patch.object(host.Host, "_check_machine_type", new=mock.Mock())
@mock.patch('nova.privsep.utils.supports_direct_io',
new=mock.Mock(return_value=True))
@mock.patch.object(
@@ -3389,6 +3394,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
self._test_get_guest_memory_backing_config,
host_topology, inst_topology, numa_tune)
+ @mock.patch.object(host.Host, "_check_machine_type", new=mock.Mock())
@mock.patch.object(
host.Host, "is_cpu_control_policy_capable", return_value=True)
def test_get_guest_config_numa_host_instance_pci_no_numa_info(
@@ -3439,11 +3445,13 @@ class LibvirtConnTestCase(test.NoDBTestCase,
self.assertEqual(0, len(cfg.cputune.vcpupin))
self.assertIsNone(cfg.cpu.numa)
+ @mock.patch.object(host.Host, "_check_machine_type", new=mock.Mock())
@mock.patch('nova.privsep.utils.supports_direct_io',
new=mock.Mock(return_value=True))
@mock.patch.object(
host.Host, "is_cpu_control_policy_capable", return_value=True)
- def test_get_guest_config_numa_host_instance_2pci_no_fit(self, is_able):
+ def test_get_guest_config_numa_host_instance_2pci_no_fit(
+ self, is_able):
self.flags(cpu_shared_set='3', cpu_dedicated_set=None,
group='compute')
instance_ref = objects.Instance(**self.test_instance)
@@ -3551,6 +3559,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
exception.NUMATopologyUnsupported,
None)
+ @mock.patch.object(host.Host, "_check_machine_type", new=mock.Mock())
@mock.patch.object(
host.Host, "is_cpu_control_policy_capable", return_value=True)
def test_get_guest_config_numa_host_instance_fit_w_cpu_pinset(
@@ -3592,9 +3601,11 @@ class LibvirtConnTestCase(test.NoDBTestCase,
self.assertEqual(0, len(cfg.cputune.vcpupin))
self.assertIsNone(cfg.cpu.numa)
+ @mock.patch.object(host.Host, "_check_machine_type", new=mock.Mock())
@mock.patch.object(
host.Host, "is_cpu_control_policy_capable", return_value=True)
- def test_get_guest_config_non_numa_host_instance_topo(self, is_able):
+ def test_get_guest_config_non_numa_host_instance_topo(
+ self, is_able):
instance_topology = objects.InstanceNUMATopology(cells=[
objects.InstanceNUMACell(
id=0, cpuset=set([0]), pcpuset=set(), memory=1024),
@@ -3641,9 +3652,11 @@ class LibvirtConnTestCase(test.NoDBTestCase,
self.assertEqual(instance_cell.memory * units.Ki,
numa_cfg_cell.memory)
+ @mock.patch.object(host.Host, "_check_machine_type", new=mock.Mock())
@mock.patch.object(
host.Host, "is_cpu_control_policy_capable", return_value=True)
- def test_get_guest_config_numa_host_instance_topo(self, is_able):
+ def test_get_guest_config_numa_host_instance_topo(
+ self, is_able):
self.flags(cpu_shared_set='0-5', cpu_dedicated_set=None,
group='compute')
@@ -3724,6 +3737,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
self.assertEqual([instance_cell.id], memnode.nodeset)
self.assertEqual("strict", memnode.mode)
+ @mock.patch.object(host.Host, "_check_machine_type", new=mock.Mock())
def test_get_guest_config_numa_host_instance_topo_reordered(self):
instance_topology = objects.InstanceNUMATopology(cells=[
objects.InstanceNUMACell(
@@ -3799,6 +3813,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
self.assertEqual([instance_cell.id], memnode.nodeset)
self.assertEqual("strict", memnode.mode)
+ @mock.patch.object(host.Host, "_check_machine_type", new=mock.Mock())
def test_get_guest_config_numa_host_instance_topo_cpu_pinning(self):
instance_topology = objects.InstanceNUMATopology(cells=[
objects.InstanceNUMACell(
@@ -3877,6 +3892,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
self.assertEqual([instance_cell.id], memnode.nodeset)
self.assertEqual("strict", memnode.mode)
+ @mock.patch.object(host.Host, "_check_machine_type", new=mock.Mock())
def test_get_guest_config_numa_host_instance_cpu_mixed(self):
"""Test to create mixed instance libvirt configuration which has a
default emulator thread policy and verify the NUMA topology related
@@ -3994,7 +4010,9 @@ class LibvirtConnTestCase(test.NoDBTestCase,
self.assertEqual(i, memnode.cellid)
self.assertEqual([instance_cell.id], memnode.nodeset)
- def test_get_guest_config_numa_host_instance_cpu_mixed_isolated_emu(self):
+ @mock.patch.object(host.Host, "_check_machine_type", new=mock.Mock())
+ def test_get_guest_config_numa_host_instance_cpu_mixed_isolated_emu(
+ self):
"""Test to create mixed instance libvirt configuration which has an
ISOLATED emulator thread policy and verify the NUMA topology related
settings.
@@ -4081,6 +4099,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
self.assertEqual(i, memnode.cellid)
self.assertEqual([instance_cell.id], memnode.nodeset)
+ @mock.patch.object(host.Host, "_check_machine_type", new=mock.Mock())
def test_get_guest_config_numa_host_instance_cpu_mixed_realtime(self):
"""Test of creating mixed instance libvirt configuration. which is
created through 'hw:cpu_realtime_mask' and 'hw:cpu_realtime' extra
@@ -4206,6 +4225,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
self.assertEqual("fifo", cfg.cputune.vcpusched[0].scheduler)
self.assertEqual(set([0, 1, 4, 5]), cfg.cputune.vcpusched[0].vcpus)
+ @mock.patch.object(host.Host, "_check_machine_type", new=mock.Mock())
def test_get_guest_config_numa_host_mempages_shared(self):
self.flags(cpu_shared_set='2-5', cpu_dedicated_set=None,
group='compute')
@@ -4279,7 +4299,9 @@ class LibvirtConnTestCase(test.NoDBTestCase,
self.assertEqual(0, len(cfg.cputune.vcpusched))
self.assertEqual(set([2, 3, 4, 5]), cfg.cputune.emulatorpin.cpuset)
- def test_get_guest_config_numa_host_instance_cpu_pinning_realtime(self):
+ @mock.patch.object(host.Host, "_check_machine_type", new=mock.Mock())
+ def test_get_guest_config_numa_host_instance_cpu_pinning_realtime(
+ self):
self.flags(cpu_shared_set=None, cpu_dedicated_set='4-7',
group='compute')
@@ -4374,6 +4396,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
# which are 6, 7
self.assertEqual(set([2, 3]), cfg.cputune.vcpusched[0].vcpus)
+ @mock.patch.object(host.Host, "_check_machine_type", new=mock.Mock())
def test_get_guest_config_numa_host_instance_isolated_emulthreads(self):
self.flags(cpu_shared_set=None, cpu_dedicated_set='4-8',
group='compute')
@@ -4480,8 +4503,8 @@ class LibvirtConnTestCase(test.NoDBTestCase,
self.assertRaises(exception.Invalid, drvr._get_guest_config,
instance_ref, [], image_meta, disk_info)
- def test_get_guest_config_numa_host_instance_shared_emulator_threads(
- self):
+ @mock.patch.object(host.Host, "_check_machine_type", new=mock.Mock())
+ def test_get_guest_config_numa_host_instance_shared_emulator_threads(self):
self.flags(cpu_shared_set='0,1', cpu_dedicated_set='2-7',
group='compute')
instance_topology = objects.InstanceNUMATopology(
@@ -4687,6 +4710,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
self.assertTrue(drvr._wants_hugepages(host_topology,
instance_topology))
+ @mock.patch.object(host.Host, "_check_machine_type", new=mock.Mock())
def test_get_guest_config_clock(self):
self.flags(virt_type='kvm', group='libvirt')
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
@@ -4730,6 +4754,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
else:
self.assertEqual(2, len(cfg.clock.timers))
+ @mock.patch.object(host.Host, "_check_machine_type", new=mock.Mock())
def test_get_guest_config_clock_hpet_false(self):
self.flags(virt_type='kvm', group='libvirt')
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
@@ -4775,6 +4800,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
else:
self.assertEqual(2, len(cfg.clock.timers))
+ @mock.patch.object(host.Host, "_check_machine_type", new=mock.Mock())
def test_get_guest_config_clock_hpet_true(self):
self.flags(virt_type='kvm', group='libvirt')
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
@@ -4821,6 +4847,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
else:
self.assertEqual(2, len(cfg.clock.timers))
+ @mock.patch.object(host.Host, "_check_machine_type", new=mock.Mock())
def test_get_guest_config_clock_hpet_invalid(self):
self.flags(virt_type='kvm', group='libvirt')
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
@@ -5314,6 +5341,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
self.assertEqual(cfg.devices[2].target_dev, 'vdd')
mock_save.assert_called_with()
+ @mock.patch.object(host.Host, "_check_machine_type", new=mock.Mock())
def test_get_guest_config_with_configdrive(self):
# It's necessary to check if the architecture is power, because
# power doesn't have support to ide, and so libvirt translate
@@ -5700,6 +5728,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
self.assertIsNone(cfg.devices[3].keymap)
self.assertEqual(cfg.devices[5].type, 'tablet')
+ @mock.patch.object(host.Host, "_check_machine_type", new=mock.Mock())
def test_get_guest_config_with_spice_and_agent(self):
self.flags(enabled=False, group='vnc')
self.flags(virt_type='kvm', group='libvirt')
@@ -6175,6 +6204,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
i = drvr._get_scsi_controller_next_unit(guest)
self.assertEqual(expect_num, i)
+ @mock.patch.object(host.Host, "_check_machine_type", new=mock.Mock())
def test_get_guest_config_with_type_kvm_on_s390(self):
self.flags(enabled=False, group='vnc')
self.flags(virt_type='kvm', group='libvirt')
@@ -7674,16 +7704,20 @@ class LibvirtConnTestCase(test.NoDBTestCase,
return drvr._get_guest_config(
instance_ref, _fake_network_info(self), image_meta, disk_info)
+ @mock.patch.object(host.Host, "_check_machine_type", new=mock.Mock())
def test_get_guest_config_machine_type_through_image_meta(self):
cfg = self._get_guest_config_machine_type_through_image_meta(
"fake_machine_type")
self.assertEqual(cfg.os_mach_type, "fake_machine_type")
- def test_get_guest_config_machine_type_through_image_meta_sev(self):
+ @mock.patch.object(host.Host, "_check_machine_type", new=mock.Mock())
+ def test_get_guest_config_machine_type_through_image_meta_sev(
+ self):
fake_q35 = "fake-q35-2.11"
cfg = self._get_guest_config_machine_type_through_image_meta(fake_q35)
self.assertEqual(cfg.os_mach_type, fake_q35)
+ @mock.patch.object(host.Host, "_check_machine_type", new=mock.Mock())
def test_get_guest_config_machine_type_from_config(self):
self.flags(virt_type='kvm', group='libvirt')
self.flags(hw_machine_type=['x86_64=fake_machine_type'],
@@ -7812,11 +7846,14 @@ class LibvirtConnTestCase(test.NoDBTestCase,
cfg.devices[device_index], vconfig.LibvirtConfigGuestVideo)
self.assertEqual(cfg.devices[device_index].type, 'vga')
+ @mock.patch.object(host.Host, "_check_machine_type", new=mock.Mock())
def test_get_guest_config_ppc64_through_image_meta_vnc_enabled(self):
self.flags(enabled=True, group='vnc')
self._test_get_guest_config_ppc64(4)
- def test_get_guest_config_ppc64_through_image_meta_spice_enabled(self):
+ @mock.patch.object(host.Host, "_check_machine_type", new=mock.Mock())
+ def test_get_guest_config_ppc64_through_image_meta_spice_enabled(
+ self):
self.flags(enabled=True,
agent_enabled=True,
group='spice')
@@ -7904,6 +7941,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
image_meta, disk_info)
self.assertIsNone(conf.cpu)
+ @mock.patch.object(host.Host, "_check_machine_type", new=mock.Mock())
def test_get_guest_cpu_config_automatic(self):
expected = {
fields.Architecture.X86_64: "host-model",
@@ -8481,6 +8519,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
break
self.assertTrue(no_exist)
+ @mock.patch.object(host.Host, "_check_machine_type", new=mock.Mock())
def test_get_guest_usb_controller(self):
self.flags(enabled=True, group='vnc')
@@ -8633,6 +8672,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
None,
(("disk", "virtio", "vda"),))
+ @mock.patch.object(host.Host, "_check_machine_type", new=mock.Mock())
def test_xml_disk_bus_ide(self):
# It's necessary to check if the architecture is power, because
# power doesn't have support to ide, and so libvirt translate
@@ -8668,6 +8708,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
block_device_info,
(expected,))
+ @mock.patch.object(host.Host, "_check_machine_type", new=mock.Mock())
def test_xml_disk_bus_ide_and_virtio(self):
expected = {
fields.Architecture.X86_64: ("cdrom", "ide", "hda"),
@@ -14809,6 +14850,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
mock_stat.assert_called_once_with(path)
mock_get_size.assert_called_once_with(path)
+ @mock.patch.object(host.Host, "_check_machine_type", new=mock.Mock())
@mock.patch.object(libvirt_driver.LibvirtDriver,
'_register_undefined_instance_details',
new=mock.Mock())
@@ -14946,6 +14988,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
mock_build_device_metadata.assert_called_once_with(self.context,
instance)
+ @mock.patch.object(host.Host, "_check_machine_type", new=mock.Mock())
def test_spawn_power_on_false(self):
self.test_spawn_with_network_info(power_on=False)
diff --git a/nova/tests/unit/virt/libvirt/test_host.py b/nova/tests/unit/virt/libvirt/test_host.py
index 5bd45cd83a0c..7082c3ad9532 100644
--- a/nova/tests/unit/virt/libvirt/test_host.py
+++ b/nova/tests/unit/virt/libvirt/test_host.py
@@ -1096,6 +1096,48 @@ Active: 8381604 kB
guest = self.host.write_instance_config(fake_dom_xml)
self.assertIsInstance(guest, libvirt_guest.Guest)
+ def test_check_machine_type_invalid(self):
+ fake_dom_xml = u"""
+
+
+ hvm
+
+ /usr/bin/qemu-system-alpha
+ q35
+ integratorcp
+ versatileab
+
+
+
+
+ """
+
+ self.assertRaises(
+ exception.InvalidMachineType,
+ self.host._check_machine_type, fake_dom_xml, 'Q35'
+ )
+
+ def test_check_machine_type_valid(self):
+ fake_dom_xml = u"""
+
+
+ hvm
+
+ /usr/bin/qemu-system-alpha
+ q35
+ integratorcp
+ versatileab
+
+
+
+
+ """
+
+ self.assertIsNone(
+ self.host._check_machine_type(fake_dom_xml, 'q35'),
+ "None msg"
+ )
+
@mock.patch.object(fakelibvirt.virConnect, "nodeDeviceLookupByName")
def test_device_lookup_by_name(self, mock_nodeDeviceLookupByName):
self.host.device_lookup_by_name("foo")
diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py
index b35f17fe3ae4..a473f6304145 100644
--- a/nova/virt/libvirt/driver.py
+++ b/nova/virt/libvirt/driver.py
@@ -6446,6 +6446,8 @@ class LibvirtDriver(driver.ComputeDriver):
guest.os_smbios = vconfig.LibvirtConfigGuestSMBIOS()
mach_type = libvirt_utils.get_machine_type(image_meta)
+ self._host._check_machine_type(caps, mach_type)
+
guest.os_mach_type = mach_type
hw_firmware_type = image_meta.properties.get('hw_firmware_type')
diff --git a/nova/virt/libvirt/host.py b/nova/virt/libvirt/host.py
index 3f5cc085377a..2bc2bb337a0f 100644
--- a/nova/virt/libvirt/host.py
+++ b/nova/virt/libvirt/host.py
@@ -31,6 +31,7 @@ from collections import defaultdict
import fnmatch
import glob
import inspect
+from lxml import etree
import operator
import os
import queue
@@ -1198,6 +1199,25 @@ class Host(object):
stats["frequency"] = self._get_hardware_info()[3]
return stats
+ def _check_machine_type(self, caps, mach_type):
+ """Validate if hw machine type is in capabilities of the host
+
+ :param caps: host capabilities
+ :param mach_type: machine type
+ """
+ possible_machine_types = []
+
+ caps_tree = etree.fromstring(str(caps))
+ for guest in caps_tree.findall('guest'):
+ for machine in guest.xpath('arch/machine'):
+ possible_machine_types.append(machine.text)
+
+ if mach_type not in possible_machine_types:
+ raise exception.InvalidMachineType(
+ message="'%s' is not valid/supported machine type, "
+ "Supported machine types are: %s" % (
+ mach_type, possible_machine_types))
+
def write_instance_config(self, xml):
"""Defines a domain, but does not start it.
diff --git a/releasenotes/notes/validate-machine-type-0d5f3dbd1e2ace31.yaml b/releasenotes/notes/validate-machine-type-0d5f3dbd1e2ace31.yaml
new file mode 100644
index 000000000000..51e8031487f0
--- /dev/null
+++ b/releasenotes/notes/validate-machine-type-0d5f3dbd1e2ace31.yaml
@@ -0,0 +1,9 @@
+---
+fixes:
+ - |
+ Added validation for image machine type property. Different APIs which
+ uses machine type for server creation, resize or rebuild will raise
+ InvalidMachineType exception with message "provided machine type is not
+ supported by host" and suggest possible/valid machine types in compute logs.
+
+ .. _bug 1933097: https://bugs.launchpad.net/nova/+bug/1933097