From 403320bc9991618b09ab55c5f650916f5c46dd75 Mon Sep 17 00:00:00 2001 From: Kashyap Chamarthy Date: Wed, 4 Apr 2018 12:44:02 +0200 Subject: [PATCH] libvirt: Bump MIN_{LIBVIRT,QEMU}_VERSION for "Rocky" The last time we incremented versions for libvirt and QEMU was during the "Pike" release (commit: b980df0, 11-Feb-2017); for "Queens" we didn't do any. The advertized NEXT_MIN_{LIBVIRT,QEMU} versions during "Pike" release were set to: libvirt 1.3.1 and QEMU 2.5.0 -- but they weren't actually bumped for "Queens". So let's actually bump them for the "Rocky" release. Fix the affected functional tests. And where applicable, use the FAKE_{LIBVIRT, QEMU}_VERSION constants in tests, instead of hard-coding versions. Also fix the following live migration unit tests in the libvirt driver: - test_live_migration_update_graphics_xml - test_live_migration_update_serial_console_xml - test_live_migration_with_valid_target_connect_addr - test_live_migration_raises_exception In above tests the following, two main changes were made: - "Mock" the migrateToURI3() API instead of migrateToURI2() -- because with the libvirt version bump, Nova's guest.migrate() method will now call libvirt's newer API migrateToURI3() with 'params' dict. So adjust the tests accordingly. - Replace the usage of "Mox" with "Mock" in relevant tests. (I know we should try to stick to the sensible rule of "one logical change per patch". But the tests were already failing and we are systematically removing the usage of Mox in Nova source tree anyway. On that grounds, this seems reasonable.) Also drop the following version constants, which are no longer needed and adjust / remove corresponding unit tests: - MIN_{LIBVIRT_KVM,QEMU}_S390_VERSION - MIN_LIBVIRT_KVM_PPC64_VERSION - Drop MIN_LIBVIRT_VIRTUOZZO_VERSION Note that subsequent patches will handle clean up of remaining (now no longer needed) version constants and compatibility code. Change-Id: If0a091a7441f2c3269148e40ececc3696d69684c Signed-off-by: Kashyap Chamarthy --- .../functional/libvirt/test_numa_servers.py | 6 +- .../libvirt/test_pci_sriov_servers.py | 8 +- .../functional/libvirt/test_rt_servers.py | 32 +- .../regressions/test_bug_1595962.py | 4 +- nova/tests/unit/virt/libvirt/fakelibvirt.py | 4 +- nova/tests/unit/virt/libvirt/test_driver.py | 293 +++++++----------- nova/virt/libvirt/driver.py | 43 +-- ...rt-qemu-min-versions-56412048c12f1f52.yaml | 8 + 8 files changed, 142 insertions(+), 256 deletions(-) create mode 100644 releasenotes/notes/rocky-libvirt-qemu-min-versions-56412048c12f1f52.yaml diff --git a/nova/tests/functional/libvirt/test_numa_servers.py b/nova/tests/functional/libvirt/test_numa_servers.py index 9f4a834ab1c8..34951ffc1c2d 100644 --- a/nova/tests/functional/libvirt/test_numa_servers.py +++ b/nova/tests/functional/libvirt/test_numa_servers.py @@ -102,9 +102,9 @@ class NUMAServersTest(ServersTestBase): def _get_connection(self, host_info): fake_connection = fakelibvirt.Connection('qemu:///system', - version=1002009, - hv_version=2001000, - host_info=host_info) + version=fakelibvirt.FAKE_LIBVIRT_VERSION, + hv_version=fakelibvirt.FAKE_QEMU_VERSION, + host_info=host_info) return fake_connection def _get_topology_filter_spy(self): diff --git a/nova/tests/functional/libvirt/test_pci_sriov_servers.py b/nova/tests/functional/libvirt/test_pci_sriov_servers.py index c21f47f45c10..217872c13365 100644 --- a/nova/tests/functional/libvirt/test_pci_sriov_servers.py +++ b/nova/tests/functional/libvirt/test_pci_sriov_servers.py @@ -85,10 +85,10 @@ class SRIOVServersTest(ServersTestBase): def _get_connection(self, host_info, pci_info): fake_connection = fakelibvirt.Connection('qemu:///system', - version=1002009, - hv_version=2001000, - host_info=host_info, - pci_info=pci_info) + version=fakelibvirt.FAKE_LIBVIRT_VERSION, + hv_version=fakelibvirt.FAKE_QEMU_VERSION, + host_info=host_info, + pci_info=pci_info) return fake_connection def _run_build_test(self, flavor_id, filter_mock, end_status='ACTIVE'): diff --git a/nova/tests/functional/libvirt/test_rt_servers.py b/nova/tests/functional/libvirt/test_rt_servers.py index 127f4bd2a9b1..2eb704a7d80b 100644 --- a/nova/tests/functional/libvirt/test_rt_servers.py +++ b/nova/tests/functional/libvirt/test_rt_servers.py @@ -68,40 +68,14 @@ class RealTimeServersTest(ServersTestBase): client.OpenStackApiException, self.api.post_server, {'server': server}) - def test_invalid_libvirt_version(self): - host_info = fakelibvirt.NUMAHostInfo(cpu_nodes=2, cpu_sockets=1, - cpu_cores=2, cpu_threads=2, - kB_mem=15740000) - fake_connection = fakelibvirt.Connection('qemu:///system', - version=1002009, - hv_version=2001000, - host_info=host_info) - with mock.patch('nova.virt.libvirt.host.Host.get_connection', - return_value=fake_connection): - self.compute = self.start_service('compute', host='test_compute0') - fake_network.set_stub_network_methods(self) - - flavor = self._create_flavor(extra_spec={ - 'hw:cpu_realtime': 'yes', 'hw:cpu_policy': 'dedicated', - 'hw:cpu_realtime_mask': '^1'}) - server = self._build_server(flavor) - created = self.api.post_server({'server': server}) - - instance = self.api.get_server(created['id']) - instance = self._wait_for_state_change(instance, 'BUILD') - - # Realtime policy not supported by hypervisor - self.assertEqual('ERROR', instance['status']) - self._delete_server(instance['id']) - def test_success(self): host_info = fakelibvirt.NUMAHostInfo(cpu_nodes=2, cpu_sockets=1, cpu_cores=2, cpu_threads=2, kB_mem=15740000) fake_connection = fakelibvirt.Connection('qemu:///system', - version=1002013, - hv_version=2001000, - host_info=host_info) + version=fakelibvirt.FAKE_LIBVIRT_VERSION, + hv_version=fakelibvirt.FAKE_QEMU_VERSION, + host_info=host_info) with mock.patch('nova.virt.libvirt.host.Host.get_connection', return_value=fake_connection): self.compute = self.start_service('compute', host='test_compute0') diff --git a/nova/tests/functional/regressions/test_bug_1595962.py b/nova/tests/functional/regressions/test_bug_1595962.py index 7b007ac57807..f6095bf29878 100644 --- a/nova/tests/functional/regressions/test_bug_1595962.py +++ b/nova/tests/functional/regressions/test_bug_1595962.py @@ -109,8 +109,8 @@ class TestSerialConsoleLiveMigrate(test.TestCase): mock_get_job_info.return_value = libvirt_guest.JobInfo( type=fakelibvirt.VIR_DOMAIN_JOB_COMPLETED) fake_connection = fakelibvirt.Connection('qemu:///system', - version=1002007, - hv_version=2001000) + version=fakelibvirt.FAKE_LIBVIRT_VERSION, + hv_version=fakelibvirt.FAKE_QEMU_VERSION) mock_host_get_connection.return_value = fake_connection server_attr = dict(name='server1', diff --git a/nova/tests/unit/virt/libvirt/fakelibvirt.py b/nova/tests/unit/virt/libvirt/fakelibvirt.py index f4e437e07cba..5edc3dd323ca 100644 --- a/nova/tests/unit/virt/libvirt/fakelibvirt.py +++ b/nova/tests/unit/virt/libvirt/fakelibvirt.py @@ -156,9 +156,9 @@ VIR_SECRET_USAGE_TYPE_CEPH = 2 VIR_SECRET_USAGE_TYPE_ISCSI = 3 # Libvirt version to match MIN_LIBVIRT_VERSION in driver.py -FAKE_LIBVIRT_VERSION = 1002009 +FAKE_LIBVIRT_VERSION = 1003001 # Libvirt version to match MIN_QEMU_VERSION in driver.py -FAKE_QEMU_VERSION = 2001000 +FAKE_QEMU_VERSION = 2005000 PF_CAP_TYPE = 'virt_functions' VF_CAP_TYPE = 'phys_function' diff --git a/nova/tests/unit/virt/libvirt/test_driver.py b/nova/tests/unit/virt/libvirt/test_driver.py index 71326fbc58a4..9e6a3631bb10 100644 --- a/nova/tests/unit/virt/libvirt/test_driver.py +++ b/nova/tests/unit/virt/libvirt/test_driver.py @@ -1055,73 +1055,15 @@ class LibvirtConnTestCase(test.NoDBTestCase, drvr.init_host("dummyhost") self.assertEqual(images.QEMU_VERSION, mock.sentinel.qemu_version) - @mock.patch.object(fakelibvirt.Connection, 'getLibVersion', - return_value=versionutils.convert_version_to_int( - libvirt_driver.MIN_LIBVIRT_OTHER_ARCH.get( - fields.Architecture.PPC64)) - 1) @mock.patch.object(fields.Architecture, "from_host", return_value=fields.Architecture.PPC64) - def test_min_version_ppc_old_libvirt(self, mock_libv, mock_arch): - drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True) - self.assertRaises(exception.NovaException, - drvr.init_host, - "dummyhost") - - @mock.patch.object(fakelibvirt.Connection, 'getLibVersion', - return_value=versionutils.convert_version_to_int( - libvirt_driver.MIN_LIBVIRT_OTHER_ARCH.get( - fields.Architecture.PPC64))) - @mock.patch.object(fields.Architecture, "from_host", - return_value=fields.Architecture.PPC64) - def test_min_version_ppc_ok(self, mock_libv, mock_arch): + def test_min_version_ppc_ok(self, mock_arch): drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True) drvr.init_host("dummyhost") - @mock.patch.object(fakelibvirt.Connection, 'getLibVersion', - return_value=versionutils.convert_version_to_int( - libvirt_driver.MIN_LIBVIRT_OTHER_ARCH.get( - fields.Architecture.S390X)) - 1) - @mock.patch.object(fakelibvirt.Connection, 'getVersion', - return_value=versionutils.convert_version_to_int( - libvirt_driver.MIN_QEMU_OTHER_ARCH.get( - fields.Architecture.S390X))) @mock.patch.object(fields.Architecture, "from_host", return_value=fields.Architecture.S390X) - def test_min_version_s390_old_libvirt(self, mock_libv, mock_qemu, - mock_arch): - drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True) - self.assertRaises(exception.NovaException, - drvr.init_host, - "dummyhost") - - @mock.patch.object(fakelibvirt.Connection, 'getLibVersion', - return_value=versionutils.convert_version_to_int( - libvirt_driver.MIN_LIBVIRT_OTHER_ARCH.get( - fields.Architecture.S390X))) - @mock.patch.object(fakelibvirt.Connection, 'getVersion', - return_value=versionutils.convert_version_to_int( - libvirt_driver.MIN_QEMU_OTHER_ARCH.get( - fields.Architecture.S390X)) - 1) - @mock.patch.object(fields.Architecture, "from_host", - return_value=fields.Architecture.S390X) - def test_min_version_s390_old_qemu(self, mock_libv, mock_qemu, - mock_arch): - drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True) - self.assertRaises(exception.NovaException, - drvr.init_host, - "dummyhost") - - @mock.patch.object(fakelibvirt.Connection, 'getLibVersion', - return_value=versionutils.convert_version_to_int( - libvirt_driver.MIN_LIBVIRT_OTHER_ARCH.get( - fields.Architecture.S390X))) - @mock.patch.object(fakelibvirt.Connection, 'getVersion', - return_value=versionutils.convert_version_to_int( - libvirt_driver.MIN_QEMU_OTHER_ARCH.get( - fields.Architecture.S390X))) - @mock.patch.object(fields.Architecture, "from_host", - return_value=fields.Architecture.S390X) - def test_min_version_s390_ok(self, mock_libv, mock_qemu, mock_arch): + def test_min_version_s390_ok(self, mock_arch): drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True) drvr.init_host("dummyhost") @@ -9123,13 +9065,14 @@ class LibvirtConnTestCase(test.NoDBTestCase, 'instance', data, block_device_info=bdi)) self.assertEqual(0, mock_get_instance_disk_info.call_count) - def test_live_migration_update_graphics_xml(self): + @mock.patch.object(host.Host, 'has_min_version', return_value=True) + @mock.patch.object(fakelibvirt.virDomain, "migrateToURI3") + @mock.patch.object(fakelibvirt.virDomain, "XMLDesc") + def test_live_migration_update_graphics_xml(self, mock_xml, + mock_migrateToURI3, + mock_min_version): self.compute = manager.ComputeManager() - instance_dict = dict(self.test_instance) - instance_dict.update({'host': 'fake', - 'power_state': power_state.RUNNING, - 'vm_state': vm_states.ACTIVE}) - instance_ref = objects.Instance(**instance_dict) + instance_ref = self.test_instance xml_tmpl = ("" "" @@ -9153,20 +9096,18 @@ class LibvirtConnTestCase(test.NoDBTestCase, drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False) # Preparing mocks - vdmock = self.mox.CreateMock(fakelibvirt.virDomain) - guest = libvirt_guest.Guest(vdmock) - self.mox.StubOutWithMock(vdmock, "migrateToURI2") - _bandwidth = libvirt_driver.MIN_MIGRATION_SPEED_BW - vdmock.XMLDesc(flags=fakelibvirt.VIR_DOMAIN_XML_MIGRATABLE).AndReturn( - initial_xml) - vdmock.migrateToURI2(drvr._live_migration_uri('dest'), - miguri=None, - dxml=target_xml, - flags=mox.IgnoreArg(), - bandwidth=_bandwidth).AndRaise( - fakelibvirt.libvirtError("ERR")) + mock_xml.return_value = initial_xml + mock_migrateToURI3.side_effect = fakelibvirt.libvirtError("ERR") + + disk_paths = ['vda', 'vdb'] + params = { + 'migrate_disks': ['vda', 'vdb'], + 'bandwidth': libvirt_driver.MIN_MIGRATION_SPEED_BW, + 'destination_xml': target_xml, + } # start test + bandwidth = libvirt_driver.MIN_MIGRATION_SPEED_BW migrate_data = objects.LibvirtLiveMigrateData( graphics_listen_addr_vnc='10.0.0.1', graphics_listen_addr_spice='10.0.0.2', @@ -9174,12 +9115,19 @@ class LibvirtConnTestCase(test.NoDBTestCase, target_connect_addr=None, bdms=[], block_migration=False) - self.mox.ReplayAll() + dom = fakelibvirt.virDomain + guest = libvirt_guest.Guest(dom) + drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False) self.assertRaises(fakelibvirt.libvirtError, drvr._live_migration_operation, self.context, instance_ref, 'dest', - False, migrate_data, guest, [], - _bandwidth) + False, migrate_data, guest, disk_paths, + bandwidth=bandwidth) + mock_xml.assert_called_once_with( + flags=fakelibvirt.VIR_DOMAIN_XML_MIGRATABLE) + mock_migrateToURI3.assert_called_once_with( + drvr._live_migration_uri('dest'), + params=params, flags=0) def test_live_migration_parallels_no_new_xml(self): self.flags(virt_type='parallels', group='libvirt') @@ -9297,17 +9245,35 @@ class LibvirtConnTestCase(test.NoDBTestCase, mupdate.assert_called_once_with( guest, migrate_data, mock.ANY) - def test_live_migration_with_valid_target_connect_addr(self): + @mock.patch.object(host.Host, 'has_min_version', return_value=True) + @mock.patch.object(fakelibvirt.virDomain, "migrateToURI3") + @mock.patch.object(nova.virt.libvirt.migration, + 'get_updated_guest_xml', return_value='') + @mock.patch.object(fakelibvirt.virDomain, "XMLDesc") + def test_live_migration_with_valid_target_connect_addr(self, mock_xml, + mock_updated_guest_xml, + mock_migrateToURI3, + mock_min_version): self.compute = manager.ComputeManager() - instance_dict = dict(self.test_instance) - instance_dict.update({'host': 'fake', - 'power_state': power_state.RUNNING, - 'vm_state': vm_states.ACTIVE}) - instance_ref = objects.Instance(**instance_dict) + instance_ref = self.test_instance + target_connection = '127.0.0.2' + target_xml = self.device_xml_tmpl.format( device_path='/dev/disk/by-path/' 'ip-1.2.3.4:3260-iqn.' 'cde.67890.opst-lun-Z') + + # Prepare mocks + mock_xml.return_value = target_xml + + disk_paths = ['vda', 'vdb'] + params = { + 'migrate_disks': disk_paths, + 'migrate_uri': 'tcp://127.0.0.2', + 'bandwidth': libvirt_driver.MIN_MIGRATION_SPEED_BW, + 'destination_xml': target_xml, + } + # start test connection_info = { u'driver_volume_type': u'iscsi', @@ -9326,26 +9292,21 @@ class LibvirtConnTestCase(test.NoDBTestCase, connection_info=connection_info) migrate_data = objects.LibvirtLiveMigrateData( serial_listen_addr='', - target_connect_addr='127.0.0.2', + target_connect_addr=target_connection, bdms=[bdm], block_migration=False) - + dom = fakelibvirt.virDomain + guest = libvirt_guest.Guest(dom) drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False) - test_mock = mock.MagicMock() - guest = libvirt_guest.Guest(test_mock) + _bandwidth = libvirt_driver.MIN_MIGRATION_SPEED_BW - - with mock.patch.object(libvirt_migrate, - 'get_updated_guest_xml') as mupdate: - - test_mock.XMLDesc.return_value = target_xml - drvr._live_migration_operation(self.context, instance_ref, - 'dest', False, migrate_data, - guest, [], _bandwidth) - test_mock.migrateToURI2.assert_called_once_with( - 'qemu+tcp://127.0.0.2/system', - miguri='tcp://127.0.0.2', - dxml=mupdate(), flags=0, bandwidth=_bandwidth) + mock_updated_guest_xml.return_value = target_xml + drvr._live_migration_operation(self.context, instance_ref, + target_connection, False, migrate_data, + guest, disk_paths, _bandwidth) + mock_migrateToURI3.assert_called_once_with( + drvr._live_migration_uri(target_connection), + params=params, flags=0) def test_update_volume_xml(self): drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False) @@ -9581,12 +9542,15 @@ class LibvirtConnTestCase(test.NoDBTestCase, drvr._get_volume_config) self.assertEqual(target_xml, config) + @mock.patch.object(host.Host, 'has_min_version', return_value=True) @mock.patch.object(libvirt_driver.LibvirtDriver, '_get_serial_ports_from_guest') - @mock.patch.object(fakelibvirt.virDomain, "migrateToURI2") + @mock.patch.object(fakelibvirt.virDomain, "migrateToURI3") @mock.patch.object(fakelibvirt.virDomain, "XMLDesc") def test_live_migration_update_serial_console_xml(self, mock_xml, - mock_migrate, mock_get): + mock_migrateToURI3, + mock_get, + mock_min_version): self.compute = manager.ComputeManager() instance_ref = self.test_instance @@ -9607,7 +9571,14 @@ class LibvirtConnTestCase(test.NoDBTestCase, # Preparing mocks mock_xml.return_value = initial_xml - mock_migrate.side_effect = fakelibvirt.libvirtError("ERR") + mock_migrateToURI3.side_effect = fakelibvirt.libvirtError("ERR") + + disk_paths = ['vda', 'vdb'] + params = { + 'migrate_disks': ['vda', 'vdb'], + 'bandwidth': libvirt_driver.MIN_MIGRATION_SPEED_BW, + 'destination_xml': target_xml, + } # start test bandwidth = libvirt_driver.MIN_MIGRATION_SPEED_BW @@ -9625,13 +9596,13 @@ class LibvirtConnTestCase(test.NoDBTestCase, self.assertRaises(fakelibvirt.libvirtError, drvr._live_migration_operation, self.context, instance_ref, 'dest', - False, migrate_data, guest, [], + False, migrate_data, guest, disk_paths, bandwidth=bandwidth) mock_xml.assert_called_once_with( flags=fakelibvirt.VIR_DOMAIN_XML_MIGRATABLE) - mock_migrate.assert_called_once_with( - drvr._live_migration_uri('dest'), miguri=None, - dxml=target_xml, flags=mock.ANY, bandwidth=bandwidth) + mock_migrateToURI3.assert_called_once_with( + drvr._live_migration_uri('dest'), + params=params, flags=0) def test_live_migration_fails_without_serial_console_address(self): self.compute = manager.ComputeManager() @@ -9801,49 +9772,47 @@ class LibvirtConnTestCase(test.NoDBTestCase, drvr._live_migration_uri('dest'), params=params, flags=expected_flags) - def test_live_migration_raises_exception(self): - # Confirms recover method is called when exceptions are raised. - # Preparing data + @mock.patch.object(host.Host, 'has_min_version', return_value=True) + @mock.patch.object(fakelibvirt.virDomain, "migrateToURI3") + @mock.patch('nova.virt.libvirt.guest.Guest.get_xml_desc', + return_value='') + def test_live_migration_raises_exception(self, mock_xml, + mock_migrateToURI3, + mock_min_version): + # Prepare data self.compute = manager.ComputeManager() - instance_dict = dict(self.test_instance) - instance_dict.update({'host': 'fake', - 'power_state': power_state.RUNNING, - 'vm_state': vm_states.ACTIVE}) - instance_ref = objects.Instance(**instance_dict) + instance_ref = self.test_instance - drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False) + # Prepare mocks + mock_migrateToURI3.side_effect = fakelibvirt.libvirtError("ERR") - # Preparing mocks - vdmock = self.mox.CreateMock(fakelibvirt.virDomain) - guest = libvirt_guest.Guest(vdmock) - self.mox.StubOutWithMock(vdmock, "migrateToURI2") - _bandwidth = libvirt_driver.MIN_MIGRATION_SPEED_BW - vdmock.XMLDesc(flags=fakelibvirt.VIR_DOMAIN_XML_MIGRATABLE - ).AndReturn(FakeVirtDomain().XMLDesc(flags=0)) - vdmock.migrateToURI2(drvr._live_migration_uri('dest'), - miguri=None, - dxml=mox.IgnoreArg(), - flags=mox.IgnoreArg(), - bandwidth=_bandwidth).AndRaise( - fakelibvirt.libvirtError('ERR')) + disk_paths = ['vda', 'vdb'] + params = { + 'migrate_disks': disk_paths, + 'bandwidth': libvirt_driver.MIN_MIGRATION_SPEED_BW, + 'destination_xml': '', + } - # start test + # Start test + bandwidth = libvirt_driver.MIN_MIGRATION_SPEED_BW migrate_data = objects.LibvirtLiveMigrateData( - graphics_listen_addr_vnc='127.0.0.1', - graphics_listen_addr_spice='127.0.0.1', + graphics_listen_addr_vnc='10.0.0.1', + graphics_listen_addr_spice='10.0.0.2', serial_listen_addr='127.0.0.1', target_connect_addr=None, bdms=[], block_migration=False) - self.mox.ReplayAll() + dom = fakelibvirt.virDomain + guest = libvirt_guest.Guest(dom) + drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False) self.assertRaises(fakelibvirt.libvirtError, drvr._live_migration_operation, self.context, instance_ref, 'dest', - False, migrate_data, guest, [], - _bandwidth) - - self.assertEqual(vm_states.ACTIVE, instance_ref.vm_state) - self.assertEqual(power_state.RUNNING, instance_ref.power_state) + False, migrate_data, guest, disk_paths, + bandwidth=bandwidth) + mock_migrateToURI3.assert_called_once_with( + drvr._live_migration_uri('dest'), + params=params, flags=0) @mock.patch('shutil.rmtree') @mock.patch('os.path.exists', return_value=True) @@ -16934,49 +16903,21 @@ class LibvirtConnTestCase(test.NoDBTestCase, def test_virtuozzo_min_version_fail(self): self.flags(virt_type='parallels', group='libvirt') driver = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False) - with test.nested( - mock.patch.object( - driver._conn, 'getVersion'), - mock.patch.object( - driver._conn, 'getLibVersion'))\ - as (mock_getver, mock_getlibver): + with mock.patch.object(driver._conn, 'getVersion') as mock_getver: mock_getver.return_value = \ versionutils.convert_version_to_int( - libvirt_driver.MIN_VIRTUOZZO_VERSION) - 1 - mock_getlibver.return_value = \ - versionutils.convert_version_to_int( - libvirt_driver.MIN_LIBVIRT_VIRTUOZZO_VERSION) + libvirt_driver.MIN_VIRTUOZZO_VERSION) - 1 self.assertRaises(exception.NovaException, driver.init_host, 'wibble') - mock_getver.return_value = \ - versionutils.convert_version_to_int( - libvirt_driver.MIN_VIRTUOZZO_VERSION) - mock_getlibver.return_value = \ - versionutils.convert_version_to_int( - libvirt_driver.MIN_LIBVIRT_VIRTUOZZO_VERSION) - 1 - - self.assertRaises(exception.NovaException, - driver.init_host, 'wibble') - - def test_virtuozzo_min_version_ok(self): + @mock.patch.object(fakelibvirt.Connection, 'getVersion', + return_value=versionutils.convert_version_to_int( + libvirt_driver.MIN_VIRTUOZZO_VERSION)) + def test_virtuozzo_min_version_ok(self, mock_get_virtuozzo_version): self.flags(virt_type='parallels', group='libvirt') driver = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False) - with test.nested( - mock.patch.object( - driver._conn, 'getVersion'), - mock.patch.object( - driver._conn, 'getLibVersion'))\ - as (mock_getver, mock_getlibver): - mock_getver.return_value = \ - versionutils.convert_version_to_int( - libvirt_driver.MIN_VIRTUOZZO_VERSION) - mock_getlibver.return_value = \ - versionutils.convert_version_to_int( - libvirt_driver.MIN_LIBVIRT_VIRTUOZZO_VERSION) - - driver.init_host('wibble') + driver.init_host('wibble') def test_get_guest_config_parallels_vm(self): self.flags(virt_type='parallels', group='libvirt') diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py index d7f068374a11..437e20026340 100644 --- a/nova/virt/libvirt/driver.py +++ b/nova/virt/libvirt/driver.py @@ -216,8 +216,8 @@ patch_tpool_proxy() # versions. Over time, this will become a common min version # for all architectures/hypervisors, as this value rises to # meet them. -MIN_LIBVIRT_VERSION = (1, 2, 9) -MIN_QEMU_VERSION = (2, 1, 0) +MIN_LIBVIRT_VERSION = (1, 3, 1) +MIN_QEMU_VERSION = (2, 5, 0) # TODO(berrange): Re-evaluate this at start of each release cycle # to decide if we want to plan a future min version bump. # MIN_LIBVIRT_VERSION can be updated to match this after @@ -244,7 +244,6 @@ BAD_LIBVIRT_CPU_POLICY_VERSIONS = [(1, 2, 10)] # Virtuozzo driver support MIN_VIRTUOZZO_VERSION = (7, 0, 0) -MIN_LIBVIRT_VIRTUOZZO_VERSION = (1, 2, 12) # Ability to set the user guest password with Qemu MIN_LIBVIRT_SET_ADMIN_PASSWD = (1, 2, 16) @@ -252,10 +251,6 @@ MIN_LIBVIRT_SET_ADMIN_PASSWD = (1, 2, 16) # Ability to set the user guest password with parallels MIN_LIBVIRT_PARALLELS_SET_ADMIN_PASSWD = (2, 0, 0) -# s/390 & s/390x architectures with KVM -MIN_LIBVIRT_KVM_S390_VERSION = (1, 2, 13) -MIN_QEMU_S390_VERSION = (2, 3, 0) - # libvirt < 1.3 reported virt_functions capability # only when VFs are enabled. # libvirt 1.3 fix f391889f4e942e22b9ef8ecca492de05106ce41e @@ -265,10 +260,6 @@ MIN_LIBVIRT_PF_WITH_NO_VFS_CAP_VERSION = (1, 3, 0) MIN_LIBVIRT_VIRTLOGD = (1, 3, 3) MIN_QEMU_VIRTLOGD = (2, 7, 0) -# ppc64/ppc64le architectures with KVM -# NOTE(rfolco): Same levels for Libvirt/Qemu on Big Endian and Little -# Endian giving the nuance around guest vs host architectures -MIN_LIBVIRT_KVM_PPC64_VERSION = (1, 2, 12) # aarch64 architecture with KVM # 'chardev' support got sorted out in 3.6.0 @@ -293,19 +284,9 @@ MIN_LIBVIRT_POSTCOPY_VERSION = (1, 3, 3) MIN_QEMU_POSTCOPY_VERSION = (2, 5, 0) MIN_LIBVIRT_OTHER_ARCH = { - fields.Architecture.S390: MIN_LIBVIRT_KVM_S390_VERSION, - fields.Architecture.S390X: MIN_LIBVIRT_KVM_S390_VERSION, - fields.Architecture.PPC: MIN_LIBVIRT_KVM_PPC64_VERSION, - fields.Architecture.PPC64: MIN_LIBVIRT_KVM_PPC64_VERSION, - fields.Architecture.PPC64LE: MIN_LIBVIRT_KVM_PPC64_VERSION, fields.Architecture.AARCH64: MIN_LIBVIRT_KVM_AARCH64_VERSION, } -MIN_QEMU_OTHER_ARCH = { - fields.Architecture.S390: MIN_QEMU_S390_VERSION, - fields.Architecture.S390X: MIN_QEMU_S390_VERSION, -} - # perf events support MIN_LIBVIRT_PERF_VERSION = (2, 0, 0) LIBVIRT_PERF_EVENT_PREFIX = 'VIR_PERF_PARAM_' @@ -550,12 +531,6 @@ class LibvirtDriver(driver.ComputeDriver): raise exception.InternalError( _('Nova requires Virtuozzo version %s or greater.') % libvirt_utils.version_to_string(MIN_VIRTUOZZO_VERSION)) - if not self._host.has_min_version(MIN_LIBVIRT_VIRTUOZZO_VERSION): - raise exception.InternalError( - _('Running Nova with parallels virt_type requires ' - 'libvirt version %s') % - libvirt_utils.version_to_string( - MIN_LIBVIRT_VIRTUOZZO_VERSION)) # Give the cloud admin a heads up if we are intending to # change the MIN_LIBVIRT_VERSION in the next release. @@ -579,19 +554,7 @@ class LibvirtDriver(driver.ComputeDriver): if (CONF.libvirt.virt_type in ('kvm', 'qemu') and kvm_arch in MIN_LIBVIRT_OTHER_ARCH and not self._host.has_min_version( - MIN_LIBVIRT_OTHER_ARCH.get(kvm_arch), - MIN_QEMU_OTHER_ARCH.get(kvm_arch))): - if MIN_QEMU_OTHER_ARCH.get(kvm_arch): - raise exception.InternalError( - _('Running Nova with qemu/kvm virt_type on %(arch)s ' - 'requires libvirt version %(libvirt_ver)s and ' - 'qemu version %(qemu_ver)s, or greater') % - {'arch': kvm_arch, - 'libvirt_ver': libvirt_utils.version_to_string( - MIN_LIBVIRT_OTHER_ARCH.get(kvm_arch)), - 'qemu_ver': libvirt_utils.version_to_string( - MIN_QEMU_OTHER_ARCH.get(kvm_arch))}) - # no qemu version in the error message + MIN_LIBVIRT_OTHER_ARCH.get(kvm_arch))): raise exception.InternalError( _('Running Nova with qemu/kvm virt_type on %(arch)s ' 'requires libvirt version %(libvirt_ver)s or greater') % diff --git a/releasenotes/notes/rocky-libvirt-qemu-min-versions-56412048c12f1f52.yaml b/releasenotes/notes/rocky-libvirt-qemu-min-versions-56412048c12f1f52.yaml new file mode 100644 index 000000000000..7714d27cb535 --- /dev/null +++ b/releasenotes/notes/rocky-libvirt-qemu-min-versions-56412048c12f1f52.yaml @@ -0,0 +1,8 @@ +--- +upgrade: + - | + The minimum required version of libvirt used by the `nova-compute` + service is now 1.3.1. And the minimum required version of QEMU used + by the `nova-compute` service is now 2.5.0. Failing to meet these + minimum versions when using the libvirt compute driver will result + in the `nova-compute` service not starting.