diff --git a/nova/tests/unit/virt/libvirt/fakelibvirt.py b/nova/tests/unit/virt/libvirt/fakelibvirt.py index 502179129b81..8761e69c1716 100644 --- a/nova/tests/unit/virt/libvirt/fakelibvirt.py +++ b/nova/tests/unit/virt/libvirt/fakelibvirt.py @@ -152,6 +152,8 @@ VIR_SECRET_USAGE_TYPE_ISCSI = 3 # Libvirt version to match MIN_LIBVIRT_VERSION in driver.py FAKE_LIBVIRT_VERSION = 1002001 +# Libvirt version to match MIN_QEMU_VERSION in driver.py +FAKE_QEMU_VERSION = 1005003 class HostInfo(object): @@ -799,7 +801,7 @@ class DomainSnapshot(object): class Connection(object): def __init__(self, uri=None, readonly=False, version=FAKE_LIBVIRT_VERSION, - hv_version=1001000, host_info=None): + hv_version=FAKE_QEMU_VERSION, host_info=None): if not uri or uri == '': if allow_default_uri_connection: uri = 'qemu:///session' diff --git a/nova/tests/unit/virt/libvirt/test_driver.py b/nova/tests/unit/virt/libvirt/test_driver.py index b57924ecd815..e3835759cd1e 100644 --- a/nova/tests/unit/virt/libvirt/test_driver.py +++ b/nova/tests/unit/virt/libvirt/test_driver.py @@ -767,6 +767,34 @@ class LibvirtConnTestCase(test.NoDBTestCase): break self.assertTrue(version_arg_found) + @mock.patch.object(fakelibvirt.Connection, 'getVersion', + return_value=versionutils.convert_version_to_int( + libvirt_driver.NEXT_MIN_QEMU_VERSION) - 1) + @mock.patch.object(libvirt_driver.LOG, 'warning') + def test_next_min_qemu_version_deprecation_warning(self, mock_warning, + mock_get_libversion): + # Skip test if there's no currently planned new min version + if (versionutils.convert_version_to_int( + libvirt_driver.NEXT_MIN_QEMU_VERSION) == + versionutils.convert_version_to_int( + libvirt_driver.MIN_QEMU_VERSION)): + self.skipTest("NEXT_MIN_QEMU_VERSION == MIN_QEMU_VERSION") + + # Test that a warning is logged if the libvirt version is less than + # the next required minimum version. + drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True) + drvr.init_host("dummyhost") + # assert that the next min version is in a warning message + expected_arg = {'version': versionutils.convert_version_to_str( + versionutils.convert_version_to_int( + libvirt_driver.NEXT_MIN_QEMU_VERSION))} + version_arg_found = False + for call in mock_warning.call_args_list: + if call[0][1] == expected_arg: + version_arg_found = True + break + self.assertTrue(version_arg_found) + @mock.patch.object(fakelibvirt.Connection, 'getLibVersion', return_value=versionutils.convert_version_to_int( libvirt_driver.NEXT_MIN_LIBVIRT_VERSION)) @@ -795,6 +823,34 @@ class LibvirtConnTestCase(test.NoDBTestCase): break self.assertFalse(version_arg_found) + @mock.patch.object(fakelibvirt.Connection, 'getVersion', + return_value=versionutils.convert_version_to_int( + libvirt_driver.NEXT_MIN_QEMU_VERSION)) + @mock.patch.object(libvirt_driver.LOG, 'warning') + def test_next_min_qemu_version_ok(self, mock_warning, mock_get_libversion): + # Skip test if there's no currently planned new min version + + if (versionutils.convert_version_to_int( + libvirt_driver.NEXT_MIN_QEMU_VERSION) == + versionutils.convert_version_to_int( + libvirt_driver.MIN_QEMU_VERSION)): + self.skipTest("NEXT_MIN_QEMU_VERSION == MIN_QEMU_VERSION") + + # Test that a warning is not logged if the libvirt version is greater + # than or equal to NEXT_MIN_QEMU_VERSION. + drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True) + drvr.init_host("dummyhost") + # assert that the next min version is in a warning message + expected_arg = {'version': versionutils.convert_version_to_str( + versionutils.convert_version_to_int( + libvirt_driver.NEXT_MIN_QEMU_VERSION))} + version_arg_found = False + for call in mock_warning.call_args_list: + if call[0][1] == expected_arg: + version_arg_found = True + break + self.assertFalse(version_arg_found) + @mock.patch.object(fakelibvirt.Connection, 'getLibVersion', return_value=versionutils.convert_version_to_int( libvirt_driver.MIN_LIBVIRT_OTHER_ARCH.get( @@ -13737,7 +13793,8 @@ class HostStateTestCase(test.NoDBTestCase): self.assertEqual(stats["memory_mb_used"], 88) self.assertEqual(stats["local_gb_used"], 20) self.assertEqual(stats["hypervisor_type"], 'QEMU') - self.assertEqual(stats["hypervisor_version"], 1001000) + self.assertEqual(stats["hypervisor_version"], + fakelibvirt.FAKE_QEMU_VERSION) self.assertEqual(stats["hypervisor_hostname"], 'compute1') cpu_info = jsonutils.loads(stats["cpu_info"]) self.assertEqual(cpu_info, diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py index 4165598d2301..8eafd9b19863 100644 --- a/nova/virt/libvirt/driver.py +++ b/nova/virt/libvirt/driver.py @@ -395,12 +395,14 @@ patch_tpool_proxy() # for all architectures/hypervisors, as this value rises to # meet them. MIN_LIBVIRT_VERSION = (1, 2, 1) +MIN_QEMU_VERSION = (1, 5, 3) # 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 # NEXT_MIN_LIBVIRT_VERSION has been at a higher value for # one cycle NEXT_MIN_LIBVIRT_VERSION = (1, 2, 1) +NEXT_MIN_QEMU_VERSION = (1, 5, 3) # When the above version matches/exceeds this version # delete it & corresponding code using it @@ -663,6 +665,12 @@ class LibvirtDriver(driver.ComputeDriver): _('Nova requires libvirt version %s or greater.') % self._version_to_string(MIN_LIBVIRT_VERSION)) + if (CONF.libvirt.virt_type in ("qemu", "kvm") and + not self._host.has_min_version(hv_ver=MIN_QEMU_VERSION)): + raise exception.NovaException( + _('Nova requires QEMU version %s or greater.') % + self._version_to_string(MIN_QEMU_VERSION)) + if (CONF.libvirt.virt_type == 'parallels' and not self._host.has_min_version(MIN_LIBVIRT_PARALLELS_VERSION)): raise exception.NovaException( @@ -679,6 +687,14 @@ class LibvirtDriver(driver.ComputeDriver): 'in the next release.'), {'version': self._version_to_string( NEXT_MIN_LIBVIRT_VERSION)}) + if (CONF.libvirt.virt_type in ("qemu", "kvm") and + not self._host.has_min_version(NEXT_MIN_QEMU_VERSION)): + LOG.warning(_LW('Running Nova with a QEMU version less than ' + '%(version)s is deprecated. The required minimum ' + 'version of QEMU will be raised to %(version)s ' + 'in the next release.'), + {'version': self._version_to_string( + NEXT_MIN_QEMU_VERSION)}) kvm_arch = arch.from_host() if (CONF.libvirt.virt_type in ('kvm', 'qemu') and diff --git a/releasenotes/notes/min-required-qemu-c987a8a5c6c4fee0.yaml b/releasenotes/notes/min-required-qemu-c987a8a5c6c4fee0.yaml new file mode 100644 index 000000000000..91b21170e17b --- /dev/null +++ b/releasenotes/notes/min-required-qemu-c987a8a5c6c4fee0.yaml @@ -0,0 +1,4 @@ +--- +upgrade: + - The minimum required QEMU version is now checked and + has been set to 1.5.3