Merge "libvirt: make live_migration_uri flag dependent on virt_type"
This commit is contained in:
commit
ee12a3a82e
@ -1858,6 +1858,11 @@ class LiveMigrationWithOldNovaNotSafe(NovaException):
|
|||||||
"Upgrade Nova on %(server)s and try again.")
|
"Upgrade Nova on %(server)s and try again.")
|
||||||
|
|
||||||
|
|
||||||
|
class LiveMigrationURINotAvailable(NovaException):
|
||||||
|
msg_fmt = _('No live migration URI configured and no default available '
|
||||||
|
'for "%(virt_type)s" hypervisor virtualization type.')
|
||||||
|
|
||||||
|
|
||||||
class UnshelveException(NovaException):
|
class UnshelveException(NovaException):
|
||||||
msg_fmt = _("Error during unshelve instance %(instance_id)s: %(reason)s")
|
msg_fmt = _("Error during unshelve instance %(instance_id)s: %(reason)s")
|
||||||
|
|
||||||
|
@ -6852,13 +6852,15 @@ class LibvirtConnTestCase(test.NoDBTestCase):
|
|||||||
spice='10.0.0.2')
|
spice='10.0.0.2')
|
||||||
target_xml = etree.tostring(etree.fromstring(target_xml))
|
target_xml = etree.tostring(etree.fromstring(target_xml))
|
||||||
|
|
||||||
|
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
|
||||||
|
|
||||||
# Preparing mocks
|
# Preparing mocks
|
||||||
vdmock = self.mox.CreateMock(fakelibvirt.virDomain)
|
vdmock = self.mox.CreateMock(fakelibvirt.virDomain)
|
||||||
self.mox.StubOutWithMock(vdmock, "migrateToURI2")
|
self.mox.StubOutWithMock(vdmock, "migrateToURI2")
|
||||||
_bandwidth = CONF.libvirt.live_migration_bandwidth
|
_bandwidth = CONF.libvirt.live_migration_bandwidth
|
||||||
vdmock.XMLDesc(flags=fakelibvirt.VIR_DOMAIN_XML_MIGRATABLE).AndReturn(
|
vdmock.XMLDesc(flags=fakelibvirt.VIR_DOMAIN_XML_MIGRATABLE).AndReturn(
|
||||||
initial_xml)
|
initial_xml)
|
||||||
vdmock.migrateToURI2(CONF.libvirt.live_migration_uri % 'dest',
|
vdmock.migrateToURI2(drvr._live_migration_uri('dest'),
|
||||||
None,
|
None,
|
||||||
target_xml,
|
target_xml,
|
||||||
mox.IgnoreArg(),
|
mox.IgnoreArg(),
|
||||||
@ -6877,7 +6879,6 @@ class LibvirtConnTestCase(test.NoDBTestCase):
|
|||||||
target_connect_addr=None,
|
target_connect_addr=None,
|
||||||
bdms=[])
|
bdms=[])
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
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',
|
||||||
@ -7024,6 +7025,39 @@ class LibvirtConnTestCase(test.NoDBTestCase):
|
|||||||
xml_doc = etree.fromstring(target_xml, parser)
|
xml_doc = etree.fromstring(target_xml, parser)
|
||||||
self.assertEqual(etree.tostring(xml_doc), etree.tostring(config))
|
self.assertEqual(etree.tostring(xml_doc), etree.tostring(config))
|
||||||
|
|
||||||
|
def test_live_migration_uri(self):
|
||||||
|
hypervisor_uri_map = (
|
||||||
|
('xen', 'xenmigr://%s/system'),
|
||||||
|
('kvm', 'qemu+tcp://%s/system'),
|
||||||
|
('qemu', 'qemu+tcp://%s/system'),
|
||||||
|
# anything else will return None
|
||||||
|
('lxc', None),
|
||||||
|
('parallels', None),
|
||||||
|
('', None),
|
||||||
|
)
|
||||||
|
dest = 'destination'
|
||||||
|
for hyperv, uri in hypervisor_uri_map:
|
||||||
|
self.flags(virt_type=hyperv, group='libvirt')
|
||||||
|
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
|
||||||
|
if uri is not None:
|
||||||
|
uri = uri % dest
|
||||||
|
self.assertEqual(uri, drvr._live_migration_uri(dest))
|
||||||
|
else:
|
||||||
|
self.assertRaises(exception.LiveMigrationURINotAvailable,
|
||||||
|
drvr._live_migration_uri,
|
||||||
|
dest)
|
||||||
|
|
||||||
|
def test_live_migration_uri_forced(self):
|
||||||
|
dest = 'destination'
|
||||||
|
for hyperv in ('kvm', 'xen'):
|
||||||
|
self.flags(virt_type=hyperv, group='libvirt')
|
||||||
|
|
||||||
|
forced_uri = 'foo://%s/bar'
|
||||||
|
self.flags(live_migration_uri=forced_uri, group='libvirt')
|
||||||
|
|
||||||
|
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
|
||||||
|
self.assertEqual(forced_uri % dest, drvr._live_migration_uri(dest))
|
||||||
|
|
||||||
def test_update_volume_xml_no_serial(self):
|
def test_update_volume_xml_no_serial(self):
|
||||||
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
|
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
|
||||||
|
|
||||||
@ -7150,7 +7184,7 @@ class LibvirtConnTestCase(test.NoDBTestCase):
|
|||||||
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_migrate.assert_called_once_with(
|
||||||
CONF.libvirt.live_migration_uri % 'dest',
|
drvr._live_migration_uri('dest'),
|
||||||
None, target_xml, mock.ANY, None, bandwidth)
|
None, target_xml, mock.ANY, None, bandwidth)
|
||||||
|
|
||||||
@mock.patch.object(fakelibvirt, 'VIR_DOMAIN_XML_MIGRATABLE', None,
|
@mock.patch.object(fakelibvirt, 'VIR_DOMAIN_XML_MIGRATABLE', None,
|
||||||
@ -7180,11 +7214,13 @@ class LibvirtConnTestCase(test.NoDBTestCase):
|
|||||||
'vm_state': vm_states.ACTIVE})
|
'vm_state': vm_states.ACTIVE})
|
||||||
instance_ref = objects.Instance(**instance_dict)
|
instance_ref = objects.Instance(**instance_dict)
|
||||||
|
|
||||||
|
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
|
||||||
|
|
||||||
# Preparing mocks
|
# Preparing mocks
|
||||||
vdmock = self.mox.CreateMock(fakelibvirt.virDomain)
|
vdmock = self.mox.CreateMock(fakelibvirt.virDomain)
|
||||||
self.mox.StubOutWithMock(vdmock, "migrateToURI")
|
self.mox.StubOutWithMock(vdmock, "migrateToURI")
|
||||||
_bandwidth = CONF.libvirt.live_migration_bandwidth
|
_bandwidth = CONF.libvirt.live_migration_bandwidth
|
||||||
vdmock.migrateToURI(CONF.libvirt.live_migration_uri % 'dest',
|
vdmock.migrateToURI(drvr._live_migration_uri('dest'),
|
||||||
mox.IgnoreArg(),
|
mox.IgnoreArg(),
|
||||||
None,
|
None,
|
||||||
_bandwidth).AndRaise(
|
_bandwidth).AndRaise(
|
||||||
@ -7198,7 +7234,6 @@ class LibvirtConnTestCase(test.NoDBTestCase):
|
|||||||
target_connect_addr=None,
|
target_connect_addr=None,
|
||||||
bdms=[])
|
bdms=[])
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
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',
|
||||||
@ -7212,11 +7247,13 @@ class LibvirtConnTestCase(test.NoDBTestCase):
|
|||||||
'vm_state': vm_states.ACTIVE})
|
'vm_state': vm_states.ACTIVE})
|
||||||
instance_ref = objects.Instance(**instance_dict)
|
instance_ref = objects.Instance(**instance_dict)
|
||||||
|
|
||||||
|
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
|
||||||
|
|
||||||
# Preparing mocks
|
# Preparing mocks
|
||||||
vdmock = self.mox.CreateMock(fakelibvirt.virDomain)
|
vdmock = self.mox.CreateMock(fakelibvirt.virDomain)
|
||||||
self.mox.StubOutWithMock(vdmock, "migrateToURI")
|
self.mox.StubOutWithMock(vdmock, "migrateToURI")
|
||||||
_bandwidth = CONF.libvirt.live_migration_bandwidth
|
_bandwidth = CONF.libvirt.live_migration_bandwidth
|
||||||
vdmock.migrateToURI(CONF.libvirt.live_migration_uri % 'dest',
|
vdmock.migrateToURI(drvr._live_migration_uri('dest'),
|
||||||
mox.IgnoreArg(),
|
mox.IgnoreArg(),
|
||||||
None,
|
None,
|
||||||
_bandwidth).AndRaise(
|
_bandwidth).AndRaise(
|
||||||
@ -7228,7 +7265,6 @@ class LibvirtConnTestCase(test.NoDBTestCase):
|
|||||||
target_connect_addr=None,
|
target_connect_addr=None,
|
||||||
bdms=[])
|
bdms=[])
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
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',
|
||||||
@ -7267,7 +7303,7 @@ class LibvirtConnTestCase(test.NoDBTestCase):
|
|||||||
self.context, instance, 'dest',
|
self.context, instance, 'dest',
|
||||||
False, migrate_data, dom, disk_paths)
|
False, migrate_data, dom, disk_paths)
|
||||||
mock_migrateToURI3.assert_called_once_with(
|
mock_migrateToURI3.assert_called_once_with(
|
||||||
CONF.libvirt.live_migration_uri % 'dest', params, None)
|
drvr._live_migration_uri('dest'), params, None)
|
||||||
|
|
||||||
@mock.patch.object(fakelibvirt, 'VIR_DOMAIN_XML_MIGRATABLE', None,
|
@mock.patch.object(fakelibvirt, 'VIR_DOMAIN_XML_MIGRATABLE', None,
|
||||||
create=True)
|
create=True)
|
||||||
@ -7307,12 +7343,14 @@ class LibvirtConnTestCase(test.NoDBTestCase):
|
|||||||
'vm_state': vm_states.ACTIVE})
|
'vm_state': vm_states.ACTIVE})
|
||||||
instance_ref = objects.Instance(**instance_dict)
|
instance_ref = objects.Instance(**instance_dict)
|
||||||
|
|
||||||
|
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
|
||||||
|
|
||||||
# Preparing mocks
|
# Preparing mocks
|
||||||
vdmock = self.mox.CreateMock(fakelibvirt.virDomain)
|
vdmock = self.mox.CreateMock(fakelibvirt.virDomain)
|
||||||
self.mox.StubOutWithMock(vdmock, "migrateToURI2")
|
self.mox.StubOutWithMock(vdmock, "migrateToURI2")
|
||||||
_bandwidth = CONF.libvirt.live_migration_bandwidth
|
_bandwidth = CONF.libvirt.live_migration_bandwidth
|
||||||
if getattr(fakelibvirt, 'VIR_DOMAIN_XML_MIGRATABLE', None) is None:
|
if getattr(fakelibvirt, 'VIR_DOMAIN_XML_MIGRATABLE', None) is None:
|
||||||
vdmock.migrateToURI(CONF.libvirt.live_migration_uri % 'dest',
|
vdmock.migrateToURI(drvr._live_migration_uri('dest'),
|
||||||
mox.IgnoreArg(),
|
mox.IgnoreArg(),
|
||||||
None,
|
None,
|
||||||
_bandwidth).AndRaise(
|
_bandwidth).AndRaise(
|
||||||
@ -7320,7 +7358,7 @@ class LibvirtConnTestCase(test.NoDBTestCase):
|
|||||||
else:
|
else:
|
||||||
vdmock.XMLDesc(flags=fakelibvirt.VIR_DOMAIN_XML_MIGRATABLE
|
vdmock.XMLDesc(flags=fakelibvirt.VIR_DOMAIN_XML_MIGRATABLE
|
||||||
).AndReturn(FakeVirtDomain().XMLDesc(flags=0))
|
).AndReturn(FakeVirtDomain().XMLDesc(flags=0))
|
||||||
vdmock.migrateToURI2(CONF.libvirt.live_migration_uri % 'dest',
|
vdmock.migrateToURI2(drvr._live_migration_uri('dest'),
|
||||||
None,
|
None,
|
||||||
mox.IgnoreArg(),
|
mox.IgnoreArg(),
|
||||||
mox.IgnoreArg(),
|
mox.IgnoreArg(),
|
||||||
@ -7336,7 +7374,6 @@ class LibvirtConnTestCase(test.NoDBTestCase):
|
|||||||
target_connect_addr=None,
|
target_connect_addr=None,
|
||||||
bdms=[])
|
bdms=[])
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
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',
|
||||||
@ -7352,6 +7389,8 @@ class LibvirtConnTestCase(test.NoDBTestCase):
|
|||||||
# Preparing data
|
# Preparing data
|
||||||
instance_ref = objects.Instance(**self.test_instance)
|
instance_ref = objects.Instance(**self.test_instance)
|
||||||
|
|
||||||
|
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
|
||||||
|
|
||||||
# Preparing mocks
|
# Preparing mocks
|
||||||
vdmock = self.mox.CreateMock(fakelibvirt.virDomain)
|
vdmock = self.mox.CreateMock(fakelibvirt.virDomain)
|
||||||
self.mox.StubOutWithMock(vdmock, 'migrateToURI2')
|
self.mox.StubOutWithMock(vdmock, 'migrateToURI2')
|
||||||
@ -7364,13 +7403,13 @@ class LibvirtConnTestCase(test.NoDBTestCase):
|
|||||||
fakelibvirt.VIR_ERR_CONFIG_UNSUPPORTED,)
|
fakelibvirt.VIR_ERR_CONFIG_UNSUPPORTED,)
|
||||||
# This is the first error we hit but since the error code is
|
# This is the first error we hit but since the error code is
|
||||||
# VIR_ERR_CONFIG_UNSUPPORTED we'll try migrateToURI.
|
# VIR_ERR_CONFIG_UNSUPPORTED we'll try migrateToURI.
|
||||||
vdmock.migrateToURI2(CONF.libvirt.live_migration_uri % 'dest', None,
|
vdmock.migrateToURI2(drvr._live_migration_uri('dest'), None,
|
||||||
mox.IgnoreArg(), mox.IgnoreArg(), None,
|
mox.IgnoreArg(), mox.IgnoreArg(), None,
|
||||||
_bandwidth).AndRaise(unsupported_config_error)
|
_bandwidth).AndRaise(unsupported_config_error)
|
||||||
# This is the second and final error that will actually kill the run,
|
# This is the second and final error that will actually kill the run,
|
||||||
# we use TestingException to make sure it's not the same libvirtError
|
# we use TestingException to make sure it's not the same libvirtError
|
||||||
# above.
|
# above.
|
||||||
vdmock.migrateToURI(CONF.libvirt.live_migration_uri % 'dest',
|
vdmock.migrateToURI(drvr._live_migration_uri('dest'),
|
||||||
mox.IgnoreArg(), None,
|
mox.IgnoreArg(), None,
|
||||||
_bandwidth).AndRaise(test.TestingException('oops'))
|
_bandwidth).AndRaise(test.TestingException('oops'))
|
||||||
|
|
||||||
|
@ -164,8 +164,8 @@ libvirt_opts = [
|
|||||||
'the hostname of the migration target'
|
'the hostname of the migration target'
|
||||||
'compute node will be used)'),
|
'compute node will be used)'),
|
||||||
cfg.StrOpt('live_migration_uri',
|
cfg.StrOpt('live_migration_uri',
|
||||||
default="qemu+tcp://%s/system",
|
help='Override the default libvirt live migration target URI '
|
||||||
help='Migration target URI '
|
'(which is dependent on virt_type) '
|
||||||
'(any included "%s" is replaced with '
|
'(any included "%s" is replaced with '
|
||||||
'the migration target hostname)'),
|
'the migration target hostname)'),
|
||||||
cfg.StrOpt('live_migration_flag',
|
cfg.StrOpt('live_migration_flag',
|
||||||
@ -836,6 +836,21 @@ class LibvirtDriver(driver.ComputeDriver):
|
|||||||
uri = CONF.libvirt.connection_uri or 'qemu:///system'
|
uri = CONF.libvirt.connection_uri or 'qemu:///system'
|
||||||
return uri
|
return uri
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _live_migration_uri(dest):
|
||||||
|
# Only Xen and QEMU support live migration, see
|
||||||
|
# https://libvirt.org/migration.html#scenarios for reference
|
||||||
|
uris = {
|
||||||
|
'kvm': 'qemu+tcp://%s/system',
|
||||||
|
'qemu': 'qemu+tcp://%s/system',
|
||||||
|
'xen': 'xenmigr://%s/system',
|
||||||
|
}
|
||||||
|
virt_type = CONF.libvirt.virt_type
|
||||||
|
uri = CONF.libvirt.live_migration_uri or uris.get(virt_type)
|
||||||
|
if uri is None:
|
||||||
|
raise exception.LiveMigrationURINotAvailable(virt_type=virt_type)
|
||||||
|
return uri % dest
|
||||||
|
|
||||||
def instance_exists(self, instance):
|
def instance_exists(self, instance):
|
||||||
"""Efficient override of base instance_exists method."""
|
"""Efficient override of base instance_exists method."""
|
||||||
try:
|
try:
|
||||||
@ -5956,7 +5971,7 @@ class LibvirtDriver(driver.ComputeDriver):
|
|||||||
# check_can_live_migrate_destination/source phase
|
# check_can_live_migrate_destination/source phase
|
||||||
self._check_graphics_addresses_can_live_migrate(listen_addrs)
|
self._check_graphics_addresses_can_live_migrate(listen_addrs)
|
||||||
self._verify_serial_console_is_disabled()
|
self._verify_serial_console_is_disabled()
|
||||||
dom.migrateToURI(CONF.libvirt.live_migration_uri % dest,
|
dom.migrateToURI(self._live_migration_uri(dest),
|
||||||
migration_flags,
|
migration_flags,
|
||||||
None,
|
None,
|
||||||
CONF.libvirt.live_migration_bandwidth)
|
CONF.libvirt.live_migration_bandwidth)
|
||||||
@ -5975,12 +5990,12 @@ class LibvirtDriver(driver.ComputeDriver):
|
|||||||
'migrate_disks': device_names,
|
'migrate_disks': device_names,
|
||||||
}
|
}
|
||||||
dom.migrateToURI3(
|
dom.migrateToURI3(
|
||||||
CONF.libvirt.live_migration_uri % dest,
|
self._live_migration_uri(dest),
|
||||||
params,
|
params,
|
||||||
migration_flags)
|
migration_flags)
|
||||||
else:
|
else:
|
||||||
dom.migrateToURI2(
|
dom.migrateToURI2(
|
||||||
CONF.libvirt.live_migration_uri % dest,
|
self._live_migration_uri(dest),
|
||||||
None,
|
None,
|
||||||
new_xml_str,
|
new_xml_str,
|
||||||
migration_flags,
|
migration_flags,
|
||||||
@ -6008,7 +6023,7 @@ class LibvirtDriver(driver.ComputeDriver):
|
|||||||
listen_addrs)
|
listen_addrs)
|
||||||
self._verify_serial_console_is_disabled()
|
self._verify_serial_console_is_disabled()
|
||||||
dom.migrateToURI(
|
dom.migrateToURI(
|
||||||
CONF.libvirt.live_migration_uri % dest,
|
self._live_migration_uri(dest),
|
||||||
migration_flags,
|
migration_flags,
|
||||||
None,
|
None,
|
||||||
CONF.libvirt.live_migration_bandwidth)
|
CONF.libvirt.live_migration_bandwidth)
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
upgrade:
|
||||||
|
- The libvirt driver has changed the default value of the
|
||||||
|
'live_migration_uri' flag, that now is dependent on the 'virt_type'. The
|
||||||
|
old default 'qemu+tcp://%s/system' now is adjusted for each of the
|
||||||
|
configured hypervisors. For Xen this will be 'xenmigr://%s/system', for
|
||||||
|
kvm/qemu this will be 'qemu+tcp://%s/system'.
|
Loading…
x
Reference in New Issue
Block a user