libvirt: Bump MIN_{LIBVIRT,QEMU}_VERSION and NEXT_MIN_{LIBVIRT,QEMU}_VERSION
I8e349849db0b1a540d295c903f1470917b82fd97 bumped these versions late in the Victoria cycle and it's time to do the same again during Wallaby. The new MIN_{LIBVIRT,QEMU}_VERSIONs are: MIN_LIBVIRT_VERSION = (6, 0, 0) MIN_QEMU_VERSION = (4, 2, 0) These versions are met by the three defined LTS distros supported by the Wallaby release [1][2] of Ubuntu 20.04, CentOS 8 and openSUSE Leap 15.2. The following constants are removed as part of this patch as since I864494e11ff697788167c996a39f38d3d833d0d7 we now use these new minimum versions in tests straight away, thus breaking many tests exercising these now obsolete constants. - MIN_LIBVIRT_VTPM - MIN_LIBVIRT_S390X_CPU_COMPARE - MIN_{LIBVIRT,QEMU}_BLOCKDEV The removal of MIN_{LIBVIRT,QEMU}_BLOCKDEV means that the swap_volume will always use the blockCopy libvirt method to copy contents between disks. This in turn requires that fakelibvirt correctly model the required flags and blockCopy method. A future change will look into switching the remaining blockRebase calls in the live snapshot flow to blockCopy. Finally, NEXT_MIN_{LIBVIRT,QEMU}_VERSION are also updated to: NEXT_MIN_LIBVIRT_VERSION = (7, 0, 0) NEXT_MIN_QEMU_VERSION = (5, 2, 0) [1] https://governance.openstack.org/tc/reference/runtimes/wallaby.html [2] https://wiki.openstack.org/wiki/LibvirtDistroSupportMatrix Change-Id: I017083b27cd9d145eecb01106388d4ce880ba823
This commit is contained in:
parent
3a390c2c82
commit
95724bbaef
@ -19,7 +19,6 @@ from castellan.common.objects import passphrase
|
||||
from castellan.key_manager import key_manager
|
||||
from oslo_log import log as logging
|
||||
from oslo_utils import uuidutils
|
||||
from oslo_utils import versionutils
|
||||
|
||||
import nova.conf
|
||||
from nova import context as nova_context
|
||||
@ -28,7 +27,6 @@ from nova import exception
|
||||
from nova import objects
|
||||
from nova.tests.functional.api import client
|
||||
from nova.tests.functional.libvirt import base
|
||||
from nova.virt.libvirt import driver
|
||||
|
||||
CONF = nova.conf.CONF
|
||||
LOG = logging.getLogger(__name__)
|
||||
@ -137,10 +135,7 @@ class VTPMServersTest(base.ServersTestBase):
|
||||
|
||||
# TODO(stephenfin): This should be moved to the base class
|
||||
def start_compute(self, hostname='compute1'):
|
||||
libvirt_version = versionutils.convert_version_to_int(
|
||||
driver.MIN_LIBVIRT_VTPM)
|
||||
fake_connection = self._get_connection(
|
||||
libvirt_version=libvirt_version, hostname=hostname)
|
||||
fake_connection = self._get_connection(hostname=hostname)
|
||||
|
||||
# This is fun. Firstly we need to do a global'ish mock so we can
|
||||
# actually start the service.
|
||||
|
@ -61,6 +61,10 @@ VIR_DOMAIN_XML_INACTIVE = 2
|
||||
VIR_DOMAIN_XML_UPDATE_CPU = 4
|
||||
VIR_DOMAIN_XML_MIGRATABLE = 8
|
||||
|
||||
VIR_DOMAIN_BLOCK_COPY_SHALLOW = 1
|
||||
VIR_DOMAIN_BLOCK_COPY_REUSE_EXT = 2
|
||||
VIR_DOMAIN_BLOCK_COPY_TRANSIENT_JOB = 4
|
||||
|
||||
VIR_DOMAIN_BLOCK_REBASE_SHALLOW = 1
|
||||
VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT = 2
|
||||
VIR_DOMAIN_BLOCK_REBASE_COPY = 8
|
||||
@ -1347,6 +1351,9 @@ class Domain(object):
|
||||
error_domain=VIR_FROM_QEMU)
|
||||
return 0
|
||||
|
||||
def blockCopy(self, disk, base, flags=0):
|
||||
return 0
|
||||
|
||||
def blockCommit(self, disk, base, top, flags):
|
||||
return 0
|
||||
|
||||
|
@ -1625,18 +1625,16 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
||||
)
|
||||
mock_getgrnam.assert_called_with('admins')
|
||||
|
||||
@mock.patch.object(host.Host, 'has_min_version')
|
||||
@mock.patch('shutil.which')
|
||||
@mock.patch('pwd.getpwnam')
|
||||
@mock.patch('grp.getgrnam')
|
||||
def test__check_vtpm_support(
|
||||
self, mock_getgrnam, mock_getpwnam, mock_which, mock_version,
|
||||
self, mock_getgrnam, mock_getpwnam, mock_which
|
||||
):
|
||||
"""Test checking for vTPM support when everything is configured
|
||||
correctly.
|
||||
"""
|
||||
self.flags(swtpm_enabled=True, virt_type='kvm', group='libvirt')
|
||||
mock_version.return_value = True
|
||||
|
||||
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
|
||||
drvr.init_host('dummyhost')
|
||||
@ -1644,7 +1642,6 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
||||
mock_which.assert_has_calls(
|
||||
[mock.call('swtpm_setup'), mock.call().__bool__()],
|
||||
)
|
||||
mock_version.assert_called_with(lv_ver=(5, 6, 0))
|
||||
|
||||
@mock.patch.object(libvirt_driver.LOG, 'warning')
|
||||
def test_check_cpu_set_configuration__no_configuration(self, mock_log):
|
||||
@ -10811,26 +10808,6 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
||||
ret = conn._compare_cpu(None, None, instance)
|
||||
self.assertIsNone(ret)
|
||||
|
||||
def test_compare_cpu_virt_platform_s390x(self):
|
||||
_fake_s390xcpu_info = {
|
||||
"arch": "s390x",
|
||||
"model": "test_model",
|
||||
"vendor": "test_vendor",
|
||||
"topology": {
|
||||
"sockets": 1,
|
||||
"cores": 8,
|
||||
"threads": 16
|
||||
},
|
||||
"features": ["feature1", "feature2"]
|
||||
}
|
||||
|
||||
instance = objects.Instance(**self.test_instance)
|
||||
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
|
||||
ret = conn._compare_cpu(None,
|
||||
jsonutils.dumps(_fake_s390xcpu_info),
|
||||
instance)
|
||||
self.assertIsNone(ret)
|
||||
|
||||
@mock.patch.object(host.Host, 'compare_cpu')
|
||||
@mock.patch.object(nova.virt.libvirt, 'config')
|
||||
def test_compare_cpu_invalid_cpuinfo_raises(self, mock_vconfig,
|
||||
@ -19432,11 +19409,8 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
||||
self.assertRaises(NotImplementedError, drvr.swap_volume, self.context,
|
||||
{}, {}, None, None, None)
|
||||
|
||||
@mock.patch.object(fakelibvirt.Connection, 'getVersion')
|
||||
@mock.patch.object(fakelibvirt.Connection, 'getLibVersion')
|
||||
@mock.patch('nova.virt.libvirt.host.Host.write_instance_config')
|
||||
def test_swap_volume_copy(self, mock_write_instance_config,
|
||||
mock_libvirt_ver, mock_qemu_ver):
|
||||
def test_swap_volume_copy(self, mock_write_instance_config):
|
||||
"""Assert the happy path of calling virDomainBlockCopy to swap"""
|
||||
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI())
|
||||
|
||||
@ -19448,10 +19422,6 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
||||
target_dev=mock.sentinel.target_dev,
|
||||
source_path=None)
|
||||
|
||||
mock_libvirt_ver.return_value = versionutils.convert_version_to_int(
|
||||
libvirt_driver.MIN_LIBVIRT_BLOCKDEV)
|
||||
mock_qemu_ver.return_value = versionutils.convert_version_to_int(
|
||||
libvirt_driver.MIN_QEMU_BLOCKDEV)
|
||||
mock_dev.is_job_complete.return_value = True
|
||||
mock_guest.get_block_device.return_value = mock_dev
|
||||
mock_guest.get_xml_desc.side_effect = [
|
||||
@ -19480,11 +19450,8 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
||||
mock_write_instance_config.assert_called_once_with(
|
||||
mock.sentinel.new_xml_desc)
|
||||
|
||||
@mock.patch.object(fakelibvirt.Connection, 'getVersion')
|
||||
@mock.patch.object(fakelibvirt.Connection, 'getLibVersion')
|
||||
@mock.patch('nova.virt.libvirt.host.Host.write_instance_config')
|
||||
def test_swap_volume_copy_failure(self, mock_write_instance_config,
|
||||
mock_libvirt_ver, mock_qemu_ver):
|
||||
def test_swap_volume_copy_failure(self, mock_write_instance_config):
|
||||
"""Assert that exception.VolumeRebaseFailed is raised on failure"""
|
||||
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI())
|
||||
|
||||
@ -19496,10 +19463,6 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
||||
target_dev=mock.sentinel.target_dev,
|
||||
source_path=None)
|
||||
|
||||
mock_libvirt_ver.return_value = versionutils.convert_version_to_int(
|
||||
libvirt_driver.MIN_LIBVIRT_BLOCKDEV)
|
||||
mock_qemu_ver.return_value = versionutils.convert_version_to_int(
|
||||
libvirt_driver.MIN_QEMU_BLOCKDEV)
|
||||
mock_dev.copy.side_effect = test.TestingException()
|
||||
mock_guest.get_block_device.return_value = mock_dev
|
||||
mock_guest.get_xml_desc.side_effect = [
|
||||
@ -19520,105 +19483,6 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
||||
mock_write_instance_config.assert_called_once_with(
|
||||
mock.sentinel.original_xml_desc)
|
||||
|
||||
@mock.patch('nova.virt.libvirt.guest.BlockDevice.is_job_complete',
|
||||
return_value=True)
|
||||
def _test_swap_volume_rebase(self, mock_is_job_complete, source_type,
|
||||
resize=False, fail=False):
|
||||
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI())
|
||||
image_meta = objects.ImageMeta.from_dict(self.test_image_meta)
|
||||
hw_firmware_type = image_meta.properties.get(
|
||||
'hw_firmware_type')
|
||||
|
||||
mock_dom = mock.MagicMock()
|
||||
guest = libvirt_guest.Guest(mock_dom)
|
||||
|
||||
with mock.patch.object(drvr._conn, 'defineXML',
|
||||
create=True) as mock_define:
|
||||
srcfile = "/first/path"
|
||||
dstfile = "/second/path"
|
||||
orig_xml = str(mock.sentinel.orig_xml)
|
||||
new_xml = str(mock.sentinel.new_xml)
|
||||
|
||||
mock_dom.XMLDesc.return_value = orig_xml
|
||||
mock_dom.isPersistent.return_value = True
|
||||
|
||||
def fake_rebase_success(*args, **kwargs):
|
||||
# Make sure the XML is set after the rebase so we know
|
||||
# get_xml_desc was called after the update.
|
||||
mock_dom.XMLDesc.return_value = new_xml
|
||||
|
||||
if not fail:
|
||||
mock_dom.blockRebase.side_effect = fake_rebase_success
|
||||
# If the swap succeeds, make sure we use the new XML to
|
||||
# redefine the domain.
|
||||
expected_xml = new_xml
|
||||
else:
|
||||
if resize:
|
||||
mock_dom.blockResize.side_effect = test.TestingException()
|
||||
expected_exception = test.TestingException
|
||||
else:
|
||||
mock_dom.blockRebase.side_effect = test.TestingException()
|
||||
expected_exception = exception.VolumeRebaseFailed
|
||||
# If the swap fails, make sure we use the original domain XML
|
||||
# to redefine the domain.
|
||||
expected_xml = orig_xml
|
||||
|
||||
# Run the swap volume code.
|
||||
mock_conf = mock.MagicMock(source_type=source_type,
|
||||
source_path=dstfile)
|
||||
if not fail:
|
||||
drvr._swap_volume(guest, srcfile, mock_conf, 1,
|
||||
hw_firmware_type)
|
||||
else:
|
||||
self.assertRaises(expected_exception, drvr._swap_volume, guest,
|
||||
srcfile, mock_conf, 1, hw_firmware_type)
|
||||
|
||||
# Verify we read the original persistent config.
|
||||
expected_call_count = 1
|
||||
expected_calls = [mock.call(
|
||||
flags=(fakelibvirt.VIR_DOMAIN_XML_INACTIVE |
|
||||
fakelibvirt.VIR_DOMAIN_XML_SECURE))]
|
||||
if not fail:
|
||||
# Verify we read the updated live config.
|
||||
expected_call_count = 2
|
||||
expected_calls.append(
|
||||
mock.call(flags=fakelibvirt.VIR_DOMAIN_XML_SECURE))
|
||||
self.assertEqual(expected_call_count, mock_dom.XMLDesc.call_count)
|
||||
mock_dom.XMLDesc.assert_has_calls(expected_calls)
|
||||
|
||||
# Verify we called with the correct flags.
|
||||
expected_flags = (fakelibvirt.VIR_DOMAIN_BLOCK_REBASE_COPY |
|
||||
fakelibvirt.VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT)
|
||||
if source_type == 'block':
|
||||
expected_flags = (expected_flags |
|
||||
fakelibvirt.VIR_DOMAIN_BLOCK_REBASE_COPY_DEV)
|
||||
mock_dom.blockRebase.assert_called_once_with(srcfile, dstfile, 0,
|
||||
flags=expected_flags)
|
||||
|
||||
# Verify we defined the expected XML.
|
||||
mock_define.assert_called_once_with(expected_xml)
|
||||
|
||||
# Verify we called resize with the correct args.
|
||||
if resize:
|
||||
mock_dom.blockResize.assert_called_once_with(
|
||||
srcfile, 1 * units.Gi, flags=1)
|
||||
|
||||
def test_swap_volume_rebase_file(self):
|
||||
self._test_swap_volume_rebase('file')
|
||||
|
||||
def test_swap_volume_rebase_block(self):
|
||||
"""If the swapped volume is type="block", make sure that we give
|
||||
libvirt the correct VIR_DOMAIN_BLOCK_REBASE_COPY_DEV flag to ensure the
|
||||
correct type="block" XML is generated (bug 1691195)
|
||||
"""
|
||||
self._test_swap_volume_rebase('block')
|
||||
|
||||
def test_swap_volume_rebase_fail(self):
|
||||
self._test_swap_volume_rebase('block', fail=True)
|
||||
|
||||
def test_swap_volume_rebase_resize_fail(self):
|
||||
self._test_swap_volume_rebase('file', resize=True, fail=True)
|
||||
|
||||
@mock.patch('nova.virt.libvirt.driver.LibvirtDriver._disconnect_volume')
|
||||
@mock.patch('nova.virt.libvirt.driver.LibvirtDriver._swap_volume')
|
||||
@mock.patch('nova.virt.libvirt.driver.LibvirtDriver._get_volume_config')
|
||||
@ -19669,99 +19533,17 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
||||
old_connection_info,
|
||||
instance)
|
||||
|
||||
@mock.patch('nova.virt.libvirt.driver.LibvirtDriver._disconnect_volume')
|
||||
@mock.patch('nova.virt.libvirt.driver.LibvirtDriver._swap_volume')
|
||||
@mock.patch('nova.virt.libvirt.driver.LibvirtDriver._get_volume_config')
|
||||
@mock.patch('nova.virt.libvirt.driver.LibvirtDriver._connect_volume')
|
||||
@mock.patch('nova.virt.libvirt.host.Host.get_guest')
|
||||
def test_swap_volume_without_device_path_blocked(self, get_guest,
|
||||
connect_volume, get_volume_config, swap_volume, disconnect_volume):
|
||||
"""Assert that NotImplementedError is raised when swap_volume is called
|
||||
without a source_path prior to MIN_LIBVIRT_BLOCKDEV.
|
||||
"""
|
||||
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI())
|
||||
instance = objects.Instance(**self.test_instance)
|
||||
old_connection_info = {'driver_volume_type': 'rbd',
|
||||
'serial': 'old-volume-id',
|
||||
'data': {'access_mode': 'rw'}}
|
||||
new_connection_info = {'driver_volume_type': 'rbd',
|
||||
'serial': 'new-volume-id',
|
||||
'data': {'access_mode': 'rw'}}
|
||||
|
||||
mock_guest = mock.MagicMock()
|
||||
mock_guest.get_disk.return_value = True
|
||||
get_guest.return_value = mock_guest
|
||||
get_volume_config.return_value = mock.MagicMock(source_path=None)
|
||||
|
||||
self.assertRaises(NotImplementedError, conn.swap_volume, self.context,
|
||||
old_connection_info, new_connection_info, instance,
|
||||
'/dev/vdb', 1)
|
||||
|
||||
@mock.patch.object(fakelibvirt.Connection, 'getVersion')
|
||||
@mock.patch.object(fakelibvirt.Connection, 'getLibVersion')
|
||||
@mock.patch('nova.virt.libvirt.driver.LibvirtDriver._disconnect_volume')
|
||||
@mock.patch('nova.virt.libvirt.driver.LibvirtDriver._swap_volume')
|
||||
@mock.patch('nova.virt.libvirt.driver.LibvirtDriver._get_volume_config')
|
||||
@mock.patch('nova.virt.libvirt.driver.LibvirtDriver._connect_volume')
|
||||
@mock.patch('nova.virt.libvirt.host.Host.get_guest')
|
||||
def test_swap_volume_blockdev_without_device_path(self, get_guest,
|
||||
connect_volume, get_volume_config, swap_volume, disconnect_volume,
|
||||
lib_version, qemu_version):
|
||||
"""Assert that swap_volume correctly calls down to _swap_volume when
|
||||
source_path isn't provided after MIN_LIBVIRT_BLOCKDEV.
|
||||
"""
|
||||
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI())
|
||||
lib_version.return_value = versionutils.convert_version_to_int(
|
||||
libvirt_driver.MIN_LIBVIRT_BLOCKDEV)
|
||||
qemu_version.return_value = versionutils.convert_version_to_int(
|
||||
libvirt_driver.MIN_QEMU_BLOCKDEV)
|
||||
instance = objects.Instance(**self.test_instance)
|
||||
old_connection_info = {'driver_volume_type': 'rbd',
|
||||
'serial': 'old-volume-id',
|
||||
'data': {'access_mode': 'rw'}}
|
||||
new_connection_info = {'driver_volume_type': 'rbd',
|
||||
'serial': 'new-volume-id',
|
||||
'data': {'access_mode': 'rw'}}
|
||||
mock_dom = mock.MagicMock()
|
||||
guest = libvirt_guest.Guest(mock_dom)
|
||||
mock_dom.XMLDesc.return_value = """<domain>
|
||||
<devices>
|
||||
<disk type='file'>
|
||||
<source file='/fake-old-volume'/>
|
||||
<target dev='vdb' bus='virtio'/>
|
||||
</disk>
|
||||
</devices>
|
||||
</domain>
|
||||
"""
|
||||
mock_dom.name.return_value = 'inst'
|
||||
mock_dom.UUIDString.return_value = 'uuid'
|
||||
get_guest.return_value = guest
|
||||
conf = mock.MagicMock(source_path='/fake-new-volume')
|
||||
get_volume_config.return_value = conf
|
||||
|
||||
conn.swap_volume(self.context, old_connection_info,
|
||||
new_connection_info, instance, '/dev/vdb', 1)
|
||||
|
||||
get_guest.assert_called_once_with(instance)
|
||||
connect_volume.assert_called_once_with(self.context,
|
||||
new_connection_info, instance)
|
||||
|
||||
swap_volume.assert_called_once_with(guest, 'vdb', conf, 1, None)
|
||||
disconnect_volume.assert_called_once_with(self.context,
|
||||
old_connection_info,
|
||||
instance)
|
||||
|
||||
@mock.patch.object(libvirt_driver.LibvirtDriver, '_get_volume_encryption')
|
||||
@mock.patch('nova.virt.libvirt.guest.BlockDevice.rebase')
|
||||
@mock.patch('nova.virt.libvirt.guest.BlockDevice.copy')
|
||||
@mock.patch('nova.virt.libvirt.driver.LibvirtDriver._disconnect_volume')
|
||||
@mock.patch('nova.virt.libvirt.driver.LibvirtDriver._connect_volume')
|
||||
@mock.patch('nova.virt.libvirt.driver.LibvirtDriver._get_volume_config')
|
||||
@mock.patch('nova.virt.libvirt.guest.Guest.get_disk')
|
||||
@mock.patch('nova.virt.libvirt.host.Host.get_guest')
|
||||
@mock.patch('nova.virt.libvirt.host.Host.write_instance_config')
|
||||
def test_swap_volume_disconnect_new_volume_on_rebase_error(self,
|
||||
def test_swap_volume_disconnect_new_volume_on_copy_error(self,
|
||||
write_config, get_guest, get_disk, get_volume_config,
|
||||
connect_volume, disconnect_volume, rebase, get_volume_encryption):
|
||||
connect_volume, disconnect_volume, copy, get_volume_encryption):
|
||||
"""Assert that disconnect_volume is called for the new volume if an
|
||||
error is encountered while rebasing
|
||||
"""
|
||||
@ -19772,7 +19554,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
||||
get_volume_encryption.return_value = {}
|
||||
exc = fakelibvirt.make_libvirtError(fakelibvirt.libvirtError,
|
||||
'internal error', error_code=fakelibvirt.VIR_ERR_INTERNAL_ERROR)
|
||||
rebase.side_effect = exc
|
||||
copy.side_effect = exc
|
||||
|
||||
self.assertRaises(exception.VolumeRebaseFailed, conn.swap_volume,
|
||||
self.context, mock.sentinel.old_connection_info,
|
||||
|
@ -101,7 +101,6 @@ import nova.privsep.utils
|
||||
from nova.storage import rbd_utils
|
||||
from nova import utils
|
||||
from nova import version
|
||||
from nova.virt import arch
|
||||
from nova.virt import block_device as driver_block_device
|
||||
from nova.virt import configdrive
|
||||
from nova.virt.disk import api as disk_api
|
||||
@ -219,15 +218,15 @@ 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 = (5, 0, 0)
|
||||
MIN_QEMU_VERSION = (4, 0, 0)
|
||||
MIN_LIBVIRT_VERSION = (6, 0, 0)
|
||||
MIN_QEMU_VERSION = (4, 2, 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
|
||||
# NEXT_MIN_LIBVIRT_VERSION has been at a higher value for
|
||||
# one cycle
|
||||
NEXT_MIN_LIBVIRT_VERSION = (6, 0, 0)
|
||||
NEXT_MIN_QEMU_VERSION = (4, 2, 0)
|
||||
NEXT_MIN_LIBVIRT_VERSION = (7, 0, 0)
|
||||
NEXT_MIN_QEMU_VERSION = (5, 2, 0)
|
||||
|
||||
# Virtuozzo driver support
|
||||
MIN_VIRTUOZZO_VERSION = (7, 0, 0)
|
||||
@ -246,15 +245,6 @@ VGPU_RESOURCE_SEMAPHORE = 'vgpu_resources'
|
||||
|
||||
LIBVIRT_PERF_EVENT_PREFIX = 'VIR_PERF_PARAM_'
|
||||
|
||||
# -blockdev support (replacing -drive)
|
||||
MIN_LIBVIRT_BLOCKDEV = (6, 0, 0)
|
||||
MIN_QEMU_BLOCKDEV = (4, 2, 0)
|
||||
|
||||
# Virtual TPM (vTPM) support
|
||||
MIN_LIBVIRT_VTPM = (5, 6, 0)
|
||||
|
||||
MIN_LIBVIRT_S390X_CPU_COMPARE = (5, 9, 0)
|
||||
|
||||
|
||||
class LibvirtDriver(driver.ComputeDriver):
|
||||
def __init__(self, virtapi, read_only=False):
|
||||
@ -742,14 +732,6 @@ class LibvirtDriver(driver.ComputeDriver):
|
||||
"'kvm'; found '%s'.")
|
||||
raise exception.InvalidConfiguration(msg % CONF.libvirt.virt_type)
|
||||
|
||||
if not self._host.has_min_version(lv_ver=MIN_LIBVIRT_VTPM):
|
||||
msg = _(
|
||||
'vTPM support requires Libvirt version %(libvirt)s or '
|
||||
'greater.')
|
||||
raise exception.InvalidConfiguration(msg % {
|
||||
'libvirt': libvirt_utils.version_to_string(MIN_LIBVIRT_VTPM),
|
||||
})
|
||||
|
||||
# These executables need to be installed for libvirt to make use of
|
||||
# emulated TPM.
|
||||
# NOTE(stephenfin): This checks using the PATH of the user running
|
||||
@ -1888,23 +1870,8 @@ class LibvirtDriver(driver.ComputeDriver):
|
||||
guest.delete_configuration(support_uefi)
|
||||
|
||||
try:
|
||||
# NOTE(lyarwood): Use virDomainBlockCopy from libvirt >= 6.0.0
|
||||
# and QEMU >= 4.2.0 with -blockdev domains allowing QEMU to
|
||||
# copy to remote disks.
|
||||
if self._host.has_min_version(lv_ver=MIN_LIBVIRT_BLOCKDEV,
|
||||
hv_ver=MIN_QEMU_BLOCKDEV):
|
||||
dev.copy(conf.to_xml(), reuse_ext=True)
|
||||
else:
|
||||
# TODO(lyarwood): Remove the following use of
|
||||
# virDomainBlockRebase once MIN_LIBVIRT_VERSION hits >=
|
||||
# 6.0.0 and MIN_QEMU_VERSION hits >= 4.2.0.
|
||||
# Start copy with VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT flag to
|
||||
# allow writing to existing external volume file. Use
|
||||
# VIR_DOMAIN_BLOCK_REBASE_COPY_DEV if it's a block device
|
||||
# to make sure XML is generated correctly (bug 1691195)
|
||||
copy_dev = conf.source_type == 'block'
|
||||
dev.rebase(conf.source_path, copy=True, reuse_ext=True,
|
||||
copy_dev=copy_dev)
|
||||
dev.copy(conf.to_xml(), reuse_ext=True)
|
||||
|
||||
while not dev.is_job_complete():
|
||||
time.sleep(0.5)
|
||||
|
||||
@ -1964,14 +1931,6 @@ class LibvirtDriver(driver.ComputeDriver):
|
||||
# eventually do this for us.
|
||||
self._connect_volume(context, new_connection_info, instance)
|
||||
conf = self._get_volume_config(new_connection_info, disk_info)
|
||||
if (not conf.source_path and not
|
||||
self._host.has_min_version(lv_ver=MIN_LIBVIRT_BLOCKDEV,
|
||||
hv_ver=MIN_QEMU_BLOCKDEV)):
|
||||
self._disconnect_volume(context, new_connection_info, instance)
|
||||
raise NotImplementedError(_("Swap only supports host devices and "
|
||||
"files with Libvirt < 6.0.0 or QEMU "
|
||||
"< 4.2.0"))
|
||||
|
||||
hw_firmware_type = instance.image_meta.properties.get(
|
||||
'hw_firmware_type')
|
||||
|
||||
@ -8798,18 +8757,6 @@ class LibvirtDriver(driver.ComputeDriver):
|
||||
else:
|
||||
cpu = self._vcpu_model_to_cpu_config(guest_cpu)
|
||||
|
||||
# s390x doesn't support cpu model in host info, so compare
|
||||
# cpu info will raise an error anyway, thus have to avoid check
|
||||
# see bug 1854126 for more info
|
||||
if (
|
||||
cpu.arch in (arch.S390X, arch.S390) and
|
||||
not self._host.has_min_version(MIN_LIBVIRT_S390X_CPU_COMPARE)
|
||||
):
|
||||
LOG.debug("on s390x platform, the min libvirt version "
|
||||
"support cpu model compare is %s",
|
||||
MIN_LIBVIRT_S390X_CPU_COMPARE)
|
||||
return
|
||||
|
||||
u = ("http://libvirt.org/html/libvirt-libvirt-host.html#"
|
||||
"virCPUCompareResult")
|
||||
m = _("CPU doesn't have compatibility.\n\n%(ret)s\n\nRefer to %(u)s")
|
||||
|
@ -0,0 +1,13 @@
|
||||
---
|
||||
upgrade:
|
||||
- |
|
||||
The minimum required version of libvirt used by the `nova-compute` service
|
||||
is now 6.0.0. The next minimum required version to be used in a future
|
||||
release is 7.0.0.
|
||||
|
||||
The minimum required version of QEMU used by the `nova-compute` service is
|
||||
now 4.2.0. The next minimum required version to be used in a future release
|
||||
is 5.2.0.
|
||||
|
||||
Failing to meet these minimum versions when using the libvirt compute
|
||||
driver will result in the `nova-compute` service not starting.
|
Loading…
Reference in New Issue
Block a user