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 <kchamart@redhat.com>
This commit is contained in:
parent
6efbed5e70
commit
403320bc99
nova
tests
functional
libvirt
regressions
unit/virt/libvirt
virt/libvirt
releasenotes/notes
@ -102,8 +102,8 @@ class NUMAServersTest(ServersTestBase):
|
|||||||
|
|
||||||
def _get_connection(self, host_info):
|
def _get_connection(self, host_info):
|
||||||
fake_connection = fakelibvirt.Connection('qemu:///system',
|
fake_connection = fakelibvirt.Connection('qemu:///system',
|
||||||
version=1002009,
|
version=fakelibvirt.FAKE_LIBVIRT_VERSION,
|
||||||
hv_version=2001000,
|
hv_version=fakelibvirt.FAKE_QEMU_VERSION,
|
||||||
host_info=host_info)
|
host_info=host_info)
|
||||||
return fake_connection
|
return fake_connection
|
||||||
|
|
||||||
|
@ -85,8 +85,8 @@ class SRIOVServersTest(ServersTestBase):
|
|||||||
|
|
||||||
def _get_connection(self, host_info, pci_info):
|
def _get_connection(self, host_info, pci_info):
|
||||||
fake_connection = fakelibvirt.Connection('qemu:///system',
|
fake_connection = fakelibvirt.Connection('qemu:///system',
|
||||||
version=1002009,
|
version=fakelibvirt.FAKE_LIBVIRT_VERSION,
|
||||||
hv_version=2001000,
|
hv_version=fakelibvirt.FAKE_QEMU_VERSION,
|
||||||
host_info=host_info,
|
host_info=host_info,
|
||||||
pci_info=pci_info)
|
pci_info=pci_info)
|
||||||
return fake_connection
|
return fake_connection
|
||||||
|
@ -68,39 +68,13 @@ class RealTimeServersTest(ServersTestBase):
|
|||||||
client.OpenStackApiException,
|
client.OpenStackApiException,
|
||||||
self.api.post_server, {'server': server})
|
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):
|
def test_success(self):
|
||||||
host_info = fakelibvirt.NUMAHostInfo(cpu_nodes=2, cpu_sockets=1,
|
host_info = fakelibvirt.NUMAHostInfo(cpu_nodes=2, cpu_sockets=1,
|
||||||
cpu_cores=2, cpu_threads=2,
|
cpu_cores=2, cpu_threads=2,
|
||||||
kB_mem=15740000)
|
kB_mem=15740000)
|
||||||
fake_connection = fakelibvirt.Connection('qemu:///system',
|
fake_connection = fakelibvirt.Connection('qemu:///system',
|
||||||
version=1002013,
|
version=fakelibvirt.FAKE_LIBVIRT_VERSION,
|
||||||
hv_version=2001000,
|
hv_version=fakelibvirt.FAKE_QEMU_VERSION,
|
||||||
host_info=host_info)
|
host_info=host_info)
|
||||||
with mock.patch('nova.virt.libvirt.host.Host.get_connection',
|
with mock.patch('nova.virt.libvirt.host.Host.get_connection',
|
||||||
return_value=fake_connection):
|
return_value=fake_connection):
|
||||||
|
@ -109,8 +109,8 @@ class TestSerialConsoleLiveMigrate(test.TestCase):
|
|||||||
mock_get_job_info.return_value = libvirt_guest.JobInfo(
|
mock_get_job_info.return_value = libvirt_guest.JobInfo(
|
||||||
type=fakelibvirt.VIR_DOMAIN_JOB_COMPLETED)
|
type=fakelibvirt.VIR_DOMAIN_JOB_COMPLETED)
|
||||||
fake_connection = fakelibvirt.Connection('qemu:///system',
|
fake_connection = fakelibvirt.Connection('qemu:///system',
|
||||||
version=1002007,
|
version=fakelibvirt.FAKE_LIBVIRT_VERSION,
|
||||||
hv_version=2001000)
|
hv_version=fakelibvirt.FAKE_QEMU_VERSION)
|
||||||
mock_host_get_connection.return_value = fake_connection
|
mock_host_get_connection.return_value = fake_connection
|
||||||
|
|
||||||
server_attr = dict(name='server1',
|
server_attr = dict(name='server1',
|
||||||
|
@ -156,9 +156,9 @@ VIR_SECRET_USAGE_TYPE_CEPH = 2
|
|||||||
VIR_SECRET_USAGE_TYPE_ISCSI = 3
|
VIR_SECRET_USAGE_TYPE_ISCSI = 3
|
||||||
|
|
||||||
# Libvirt version to match MIN_LIBVIRT_VERSION in driver.py
|
# 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
|
# Libvirt version to match MIN_QEMU_VERSION in driver.py
|
||||||
FAKE_QEMU_VERSION = 2001000
|
FAKE_QEMU_VERSION = 2005000
|
||||||
|
|
||||||
PF_CAP_TYPE = 'virt_functions'
|
PF_CAP_TYPE = 'virt_functions'
|
||||||
VF_CAP_TYPE = 'phys_function'
|
VF_CAP_TYPE = 'phys_function'
|
||||||
|
@ -1055,73 +1055,15 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||||||
drvr.init_host("dummyhost")
|
drvr.init_host("dummyhost")
|
||||||
self.assertEqual(images.QEMU_VERSION, mock.sentinel.qemu_version)
|
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",
|
@mock.patch.object(fields.Architecture, "from_host",
|
||||||
return_value=fields.Architecture.PPC64)
|
return_value=fields.Architecture.PPC64)
|
||||||
def test_min_version_ppc_old_libvirt(self, mock_libv, mock_arch):
|
def test_min_version_ppc_ok(self, 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):
|
|
||||||
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
|
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
|
||||||
drvr.init_host("dummyhost")
|
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",
|
@mock.patch.object(fields.Architecture, "from_host",
|
||||||
return_value=fields.Architecture.S390X)
|
return_value=fields.Architecture.S390X)
|
||||||
def test_min_version_s390_old_libvirt(self, mock_libv, mock_qemu,
|
def test_min_version_s390_ok(self, mock_arch):
|
||||||
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):
|
|
||||||
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
|
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
|
||||||
drvr.init_host("dummyhost")
|
drvr.init_host("dummyhost")
|
||||||
|
|
||||||
@ -9123,13 +9065,14 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||||||
'instance', data, block_device_info=bdi))
|
'instance', data, block_device_info=bdi))
|
||||||
self.assertEqual(0, mock_get_instance_disk_info.call_count)
|
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()
|
self.compute = manager.ComputeManager()
|
||||||
instance_dict = dict(self.test_instance)
|
instance_ref = self.test_instance
|
||||||
instance_dict.update({'host': 'fake',
|
|
||||||
'power_state': power_state.RUNNING,
|
|
||||||
'vm_state': vm_states.ACTIVE})
|
|
||||||
instance_ref = objects.Instance(**instance_dict)
|
|
||||||
|
|
||||||
xml_tmpl = ("<domain type='kvm'>"
|
xml_tmpl = ("<domain type='kvm'>"
|
||||||
"<devices>"
|
"<devices>"
|
||||||
@ -9153,20 +9096,18 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||||||
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
|
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
|
||||||
|
|
||||||
# Preparing mocks
|
# Preparing mocks
|
||||||
vdmock = self.mox.CreateMock(fakelibvirt.virDomain)
|
mock_xml.return_value = initial_xml
|
||||||
guest = libvirt_guest.Guest(vdmock)
|
mock_migrateToURI3.side_effect = fakelibvirt.libvirtError("ERR")
|
||||||
self.mox.StubOutWithMock(vdmock, "migrateToURI2")
|
|
||||||
_bandwidth = libvirt_driver.MIN_MIGRATION_SPEED_BW
|
disk_paths = ['vda', 'vdb']
|
||||||
vdmock.XMLDesc(flags=fakelibvirt.VIR_DOMAIN_XML_MIGRATABLE).AndReturn(
|
params = {
|
||||||
initial_xml)
|
'migrate_disks': ['vda', 'vdb'],
|
||||||
vdmock.migrateToURI2(drvr._live_migration_uri('dest'),
|
'bandwidth': libvirt_driver.MIN_MIGRATION_SPEED_BW,
|
||||||
miguri=None,
|
'destination_xml': target_xml,
|
||||||
dxml=target_xml,
|
}
|
||||||
flags=mox.IgnoreArg(),
|
|
||||||
bandwidth=_bandwidth).AndRaise(
|
|
||||||
fakelibvirt.libvirtError("ERR"))
|
|
||||||
|
|
||||||
# start test
|
# start test
|
||||||
|
bandwidth = libvirt_driver.MIN_MIGRATION_SPEED_BW
|
||||||
migrate_data = objects.LibvirtLiveMigrateData(
|
migrate_data = objects.LibvirtLiveMigrateData(
|
||||||
graphics_listen_addr_vnc='10.0.0.1',
|
graphics_listen_addr_vnc='10.0.0.1',
|
||||||
graphics_listen_addr_spice='10.0.0.2',
|
graphics_listen_addr_spice='10.0.0.2',
|
||||||
@ -9174,12 +9115,19 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||||||
target_connect_addr=None,
|
target_connect_addr=None,
|
||||||
bdms=[],
|
bdms=[],
|
||||||
block_migration=False)
|
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,
|
self.assertRaises(fakelibvirt.libvirtError,
|
||||||
drvr._live_migration_operation,
|
drvr._live_migration_operation,
|
||||||
self.context, instance_ref, 'dest',
|
self.context, instance_ref, 'dest',
|
||||||
False, migrate_data, guest, [],
|
False, migrate_data, guest, disk_paths,
|
||||||
_bandwidth)
|
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):
|
def test_live_migration_parallels_no_new_xml(self):
|
||||||
self.flags(virt_type='parallels', group='libvirt')
|
self.flags(virt_type='parallels', group='libvirt')
|
||||||
@ -9297,17 +9245,35 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||||||
mupdate.assert_called_once_with(
|
mupdate.assert_called_once_with(
|
||||||
guest, migrate_data, mock.ANY)
|
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()
|
self.compute = manager.ComputeManager()
|
||||||
instance_dict = dict(self.test_instance)
|
instance_ref = self.test_instance
|
||||||
instance_dict.update({'host': 'fake',
|
target_connection = '127.0.0.2'
|
||||||
'power_state': power_state.RUNNING,
|
|
||||||
'vm_state': vm_states.ACTIVE})
|
|
||||||
instance_ref = objects.Instance(**instance_dict)
|
|
||||||
target_xml = self.device_xml_tmpl.format(
|
target_xml = self.device_xml_tmpl.format(
|
||||||
device_path='/dev/disk/by-path/'
|
device_path='/dev/disk/by-path/'
|
||||||
'ip-1.2.3.4:3260-iqn.'
|
'ip-1.2.3.4:3260-iqn.'
|
||||||
'cde.67890.opst-lun-Z')
|
'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
|
# start test
|
||||||
connection_info = {
|
connection_info = {
|
||||||
u'driver_volume_type': u'iscsi',
|
u'driver_volume_type': u'iscsi',
|
||||||
@ -9326,26 +9292,21 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||||||
connection_info=connection_info)
|
connection_info=connection_info)
|
||||||
migrate_data = objects.LibvirtLiveMigrateData(
|
migrate_data = objects.LibvirtLiveMigrateData(
|
||||||
serial_listen_addr='',
|
serial_listen_addr='',
|
||||||
target_connect_addr='127.0.0.2',
|
target_connect_addr=target_connection,
|
||||||
bdms=[bdm],
|
bdms=[bdm],
|
||||||
block_migration=False)
|
block_migration=False)
|
||||||
|
dom = fakelibvirt.virDomain
|
||||||
|
guest = libvirt_guest.Guest(dom)
|
||||||
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
|
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
|
||||||
test_mock = mock.MagicMock()
|
|
||||||
guest = libvirt_guest.Guest(test_mock)
|
|
||||||
_bandwidth = libvirt_driver.MIN_MIGRATION_SPEED_BW
|
_bandwidth = libvirt_driver.MIN_MIGRATION_SPEED_BW
|
||||||
|
mock_updated_guest_xml.return_value = target_xml
|
||||||
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,
|
drvr._live_migration_operation(self.context, instance_ref,
|
||||||
'dest', False, migrate_data,
|
target_connection, False, migrate_data,
|
||||||
guest, [], _bandwidth)
|
guest, disk_paths, _bandwidth)
|
||||||
test_mock.migrateToURI2.assert_called_once_with(
|
mock_migrateToURI3.assert_called_once_with(
|
||||||
'qemu+tcp://127.0.0.2/system',
|
drvr._live_migration_uri(target_connection),
|
||||||
miguri='tcp://127.0.0.2',
|
params=params, flags=0)
|
||||||
dxml=mupdate(), flags=0, bandwidth=_bandwidth)
|
|
||||||
|
|
||||||
def test_update_volume_xml(self):
|
def test_update_volume_xml(self):
|
||||||
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
|
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
|
||||||
@ -9581,12 +9542,15 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||||||
drvr._get_volume_config)
|
drvr._get_volume_config)
|
||||||
self.assertEqual(target_xml, config)
|
self.assertEqual(target_xml, config)
|
||||||
|
|
||||||
|
@mock.patch.object(host.Host, 'has_min_version', return_value=True)
|
||||||
@mock.patch.object(libvirt_driver.LibvirtDriver,
|
@mock.patch.object(libvirt_driver.LibvirtDriver,
|
||||||
'_get_serial_ports_from_guest')
|
'_get_serial_ports_from_guest')
|
||||||
@mock.patch.object(fakelibvirt.virDomain, "migrateToURI2")
|
@mock.patch.object(fakelibvirt.virDomain, "migrateToURI3")
|
||||||
@mock.patch.object(fakelibvirt.virDomain, "XMLDesc")
|
@mock.patch.object(fakelibvirt.virDomain, "XMLDesc")
|
||||||
def test_live_migration_update_serial_console_xml(self, mock_xml,
|
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()
|
self.compute = manager.ComputeManager()
|
||||||
instance_ref = self.test_instance
|
instance_ref = self.test_instance
|
||||||
|
|
||||||
@ -9607,7 +9571,14 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||||||
|
|
||||||
# Preparing mocks
|
# Preparing mocks
|
||||||
mock_xml.return_value = initial_xml
|
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
|
# start test
|
||||||
bandwidth = libvirt_driver.MIN_MIGRATION_SPEED_BW
|
bandwidth = libvirt_driver.MIN_MIGRATION_SPEED_BW
|
||||||
@ -9625,13 +9596,13 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||||||
self.assertRaises(fakelibvirt.libvirtError,
|
self.assertRaises(fakelibvirt.libvirtError,
|
||||||
drvr._live_migration_operation,
|
drvr._live_migration_operation,
|
||||||
self.context, instance_ref, 'dest',
|
self.context, instance_ref, 'dest',
|
||||||
False, migrate_data, guest, [],
|
False, migrate_data, guest, disk_paths,
|
||||||
bandwidth=bandwidth)
|
bandwidth=bandwidth)
|
||||||
mock_xml.assert_called_once_with(
|
mock_xml.assert_called_once_with(
|
||||||
flags=fakelibvirt.VIR_DOMAIN_XML_MIGRATABLE)
|
flags=fakelibvirt.VIR_DOMAIN_XML_MIGRATABLE)
|
||||||
mock_migrate.assert_called_once_with(
|
mock_migrateToURI3.assert_called_once_with(
|
||||||
drvr._live_migration_uri('dest'), miguri=None,
|
drvr._live_migration_uri('dest'),
|
||||||
dxml=target_xml, flags=mock.ANY, bandwidth=bandwidth)
|
params=params, flags=0)
|
||||||
|
|
||||||
def test_live_migration_fails_without_serial_console_address(self):
|
def test_live_migration_fails_without_serial_console_address(self):
|
||||||
self.compute = manager.ComputeManager()
|
self.compute = manager.ComputeManager()
|
||||||
@ -9801,49 +9772,47 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||||||
drvr._live_migration_uri('dest'),
|
drvr._live_migration_uri('dest'),
|
||||||
params=params, flags=expected_flags)
|
params=params, flags=expected_flags)
|
||||||
|
|
||||||
def test_live_migration_raises_exception(self):
|
@mock.patch.object(host.Host, 'has_min_version', return_value=True)
|
||||||
# Confirms recover method is called when exceptions are raised.
|
@mock.patch.object(fakelibvirt.virDomain, "migrateToURI3")
|
||||||
# Preparing data
|
@mock.patch('nova.virt.libvirt.guest.Guest.get_xml_desc',
|
||||||
|
return_value='<xml/>')
|
||||||
|
def test_live_migration_raises_exception(self, mock_xml,
|
||||||
|
mock_migrateToURI3,
|
||||||
|
mock_min_version):
|
||||||
|
# Prepare data
|
||||||
self.compute = manager.ComputeManager()
|
self.compute = manager.ComputeManager()
|
||||||
instance_dict = dict(self.test_instance)
|
instance_ref = self.test_instance
|
||||||
instance_dict.update({'host': 'fake',
|
|
||||||
'power_state': power_state.RUNNING,
|
|
||||||
'vm_state': vm_states.ACTIVE})
|
|
||||||
instance_ref = objects.Instance(**instance_dict)
|
|
||||||
|
|
||||||
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
|
# Prepare mocks
|
||||||
|
mock_migrateToURI3.side_effect = fakelibvirt.libvirtError("ERR")
|
||||||
|
|
||||||
# Preparing mocks
|
disk_paths = ['vda', 'vdb']
|
||||||
vdmock = self.mox.CreateMock(fakelibvirt.virDomain)
|
params = {
|
||||||
guest = libvirt_guest.Guest(vdmock)
|
'migrate_disks': disk_paths,
|
||||||
self.mox.StubOutWithMock(vdmock, "migrateToURI2")
|
'bandwidth': libvirt_driver.MIN_MIGRATION_SPEED_BW,
|
||||||
_bandwidth = libvirt_driver.MIN_MIGRATION_SPEED_BW
|
'destination_xml': '<xml/>',
|
||||||
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'))
|
|
||||||
|
|
||||||
# start test
|
# Start test
|
||||||
|
bandwidth = libvirt_driver.MIN_MIGRATION_SPEED_BW
|
||||||
migrate_data = objects.LibvirtLiveMigrateData(
|
migrate_data = objects.LibvirtLiveMigrateData(
|
||||||
graphics_listen_addr_vnc='127.0.0.1',
|
graphics_listen_addr_vnc='10.0.0.1',
|
||||||
graphics_listen_addr_spice='127.0.0.1',
|
graphics_listen_addr_spice='10.0.0.2',
|
||||||
serial_listen_addr='127.0.0.1',
|
serial_listen_addr='127.0.0.1',
|
||||||
target_connect_addr=None,
|
target_connect_addr=None,
|
||||||
bdms=[],
|
bdms=[],
|
||||||
block_migration=False)
|
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,
|
self.assertRaises(fakelibvirt.libvirtError,
|
||||||
drvr._live_migration_operation,
|
drvr._live_migration_operation,
|
||||||
self.context, instance_ref, 'dest',
|
self.context, instance_ref, 'dest',
|
||||||
False, migrate_data, guest, [],
|
False, migrate_data, guest, disk_paths,
|
||||||
_bandwidth)
|
bandwidth=bandwidth)
|
||||||
|
mock_migrateToURI3.assert_called_once_with(
|
||||||
self.assertEqual(vm_states.ACTIVE, instance_ref.vm_state)
|
drvr._live_migration_uri('dest'),
|
||||||
self.assertEqual(power_state.RUNNING, instance_ref.power_state)
|
params=params, flags=0)
|
||||||
|
|
||||||
@mock.patch('shutil.rmtree')
|
@mock.patch('shutil.rmtree')
|
||||||
@mock.patch('os.path.exists', return_value=True)
|
@mock.patch('os.path.exists', return_value=True)
|
||||||
@ -16934,48 +16903,20 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||||||
def test_virtuozzo_min_version_fail(self):
|
def test_virtuozzo_min_version_fail(self):
|
||||||
self.flags(virt_type='parallels', group='libvirt')
|
self.flags(virt_type='parallels', group='libvirt')
|
||||||
driver = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
|
driver = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
|
||||||
with test.nested(
|
with mock.patch.object(driver._conn, 'getVersion') as mock_getver:
|
||||||
mock.patch.object(
|
|
||||||
driver._conn, 'getVersion'),
|
|
||||||
mock.patch.object(
|
|
||||||
driver._conn, 'getLibVersion'))\
|
|
||||||
as (mock_getver, mock_getlibver):
|
|
||||||
mock_getver.return_value = \
|
mock_getver.return_value = \
|
||||||
versionutils.convert_version_to_int(
|
versionutils.convert_version_to_int(
|
||||||
libvirt_driver.MIN_VIRTUOZZO_VERSION) - 1
|
libvirt_driver.MIN_VIRTUOZZO_VERSION) - 1
|
||||||
mock_getlibver.return_value = \
|
|
||||||
versionutils.convert_version_to_int(
|
|
||||||
libvirt_driver.MIN_LIBVIRT_VIRTUOZZO_VERSION)
|
|
||||||
|
|
||||||
self.assertRaises(exception.NovaException,
|
self.assertRaises(exception.NovaException,
|
||||||
driver.init_host, 'wibble')
|
driver.init_host, 'wibble')
|
||||||
|
|
||||||
mock_getver.return_value = \
|
@mock.patch.object(fakelibvirt.Connection, 'getVersion',
|
||||||
versionutils.convert_version_to_int(
|
return_value=versionutils.convert_version_to_int(
|
||||||
libvirt_driver.MIN_VIRTUOZZO_VERSION)
|
libvirt_driver.MIN_VIRTUOZZO_VERSION))
|
||||||
mock_getlibver.return_value = \
|
def test_virtuozzo_min_version_ok(self, mock_get_virtuozzo_version):
|
||||||
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):
|
|
||||||
self.flags(virt_type='parallels', group='libvirt')
|
self.flags(virt_type='parallels', group='libvirt')
|
||||||
driver = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
|
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):
|
def test_get_guest_config_parallels_vm(self):
|
||||||
|
@ -216,8 +216,8 @@ patch_tpool_proxy()
|
|||||||
# versions. Over time, this will become a common min version
|
# versions. Over time, this will become a common min version
|
||||||
# for all architectures/hypervisors, as this value rises to
|
# for all architectures/hypervisors, as this value rises to
|
||||||
# meet them.
|
# meet them.
|
||||||
MIN_LIBVIRT_VERSION = (1, 2, 9)
|
MIN_LIBVIRT_VERSION = (1, 3, 1)
|
||||||
MIN_QEMU_VERSION = (2, 1, 0)
|
MIN_QEMU_VERSION = (2, 5, 0)
|
||||||
# TODO(berrange): Re-evaluate this at start of each release cycle
|
# TODO(berrange): Re-evaluate this at start of each release cycle
|
||||||
# to decide if we want to plan a future min version bump.
|
# to decide if we want to plan a future min version bump.
|
||||||
# MIN_LIBVIRT_VERSION can be updated to match this after
|
# 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
|
# Virtuozzo driver support
|
||||||
MIN_VIRTUOZZO_VERSION = (7, 0, 0)
|
MIN_VIRTUOZZO_VERSION = (7, 0, 0)
|
||||||
MIN_LIBVIRT_VIRTUOZZO_VERSION = (1, 2, 12)
|
|
||||||
|
|
||||||
# Ability to set the user guest password with Qemu
|
# Ability to set the user guest password with Qemu
|
||||||
MIN_LIBVIRT_SET_ADMIN_PASSWD = (1, 2, 16)
|
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
|
# Ability to set the user guest password with parallels
|
||||||
MIN_LIBVIRT_PARALLELS_SET_ADMIN_PASSWD = (2, 0, 0)
|
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
|
# libvirt < 1.3 reported virt_functions capability
|
||||||
# only when VFs are enabled.
|
# only when VFs are enabled.
|
||||||
# libvirt 1.3 fix f391889f4e942e22b9ef8ecca492de05106ce41e
|
# 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_LIBVIRT_VIRTLOGD = (1, 3, 3)
|
||||||
MIN_QEMU_VIRTLOGD = (2, 7, 0)
|
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
|
# aarch64 architecture with KVM
|
||||||
# 'chardev' support got sorted out in 3.6.0
|
# '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_QEMU_POSTCOPY_VERSION = (2, 5, 0)
|
||||||
|
|
||||||
MIN_LIBVIRT_OTHER_ARCH = {
|
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,
|
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
|
# perf events support
|
||||||
MIN_LIBVIRT_PERF_VERSION = (2, 0, 0)
|
MIN_LIBVIRT_PERF_VERSION = (2, 0, 0)
|
||||||
LIBVIRT_PERF_EVENT_PREFIX = 'VIR_PERF_PARAM_'
|
LIBVIRT_PERF_EVENT_PREFIX = 'VIR_PERF_PARAM_'
|
||||||
@ -550,12 +531,6 @@ class LibvirtDriver(driver.ComputeDriver):
|
|||||||
raise exception.InternalError(
|
raise exception.InternalError(
|
||||||
_('Nova requires Virtuozzo version %s or greater.') %
|
_('Nova requires Virtuozzo version %s or greater.') %
|
||||||
libvirt_utils.version_to_string(MIN_VIRTUOZZO_VERSION))
|
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
|
# Give the cloud admin a heads up if we are intending to
|
||||||
# change the MIN_LIBVIRT_VERSION in the next release.
|
# 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
|
if (CONF.libvirt.virt_type in ('kvm', 'qemu') and
|
||||||
kvm_arch in MIN_LIBVIRT_OTHER_ARCH and
|
kvm_arch in MIN_LIBVIRT_OTHER_ARCH and
|
||||||
not self._host.has_min_version(
|
not self._host.has_min_version(
|
||||||
MIN_LIBVIRT_OTHER_ARCH.get(kvm_arch),
|
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
|
|
||||||
raise exception.InternalError(
|
raise exception.InternalError(
|
||||||
_('Running Nova with qemu/kvm virt_type on %(arch)s '
|
_('Running Nova with qemu/kvm virt_type on %(arch)s '
|
||||||
'requires libvirt version %(libvirt_ver)s or greater') %
|
'requires libvirt version %(libvirt_ver)s or greater') %
|
||||||
|
@ -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.
|
Loading…
Reference in New Issue
Block a user