Add migrate_uri for invoking the migration

Add migrate_uri parameter in Guest.migrate method, to indicate
the URI where we want to stablish the connection in a non-tunneled
migration.

Change-Id: I6c2ad0170d90560d7d710b578c45287e78c682d1
Closes-Bug: #1614063
This commit is contained in:
Alberto Planas 2016-08-17 17:37:48 +02:00 committed by Pawel Koniszewski
parent bc1b11fdc2
commit 94f89e96f8
5 changed files with 70 additions and 7 deletions

View File

@ -7505,6 +7505,7 @@ class LibvirtConnTestCase(test.NoDBTestCase):
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(
@ -7624,6 +7625,7 @@ class LibvirtConnTestCase(test.NoDBTestCase):
guest, [])
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=0)
def test_update_volume_xml(self):
@ -7710,6 +7712,39 @@ class LibvirtConnTestCase(test.NoDBTestCase):
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
self.assertEqual(forced_uri % dest, drvr._live_migration_uri(dest))
def test_migrate_uri(self):
hypervisor_uri_map = (
('xen', None),
('kvm', 'tcp://%s'),
('qemu', 'tcp://%s'),
)
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._migrate_uri(dest))
def test_migrate_uri_forced_live_migration_uri(self):
dest = 'destination'
self.flags(virt_type='kvm', group='libvirt')
forced_uri = 'qemu+tcp://user:pass@%s/system'
self.flags(live_migration_uri=forced_uri, group='libvirt')
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
self.assertEqual('tcp://%s' % dest, drvr._migrate_uri(dest))
def test_migrate_uri_forced_live_migration_inboud_addr(self):
self.flags(virt_type='kvm', group='libvirt')
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
addresses = ('127.0.0.1', '127.0.0.1:4444',
'0:0:0:0:0:0:0:1', '[0:0:0:0:0:0:0:1]:4444')
for dest in addresses:
self.assertEqual('tcp://%s' % dest, drvr._migrate_uri(dest))
def test_update_volume_xml_no_serial(self):
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
@ -7849,7 +7884,7 @@ class LibvirtConnTestCase(test.NoDBTestCase):
mock_xml.assert_called_once_with(
flags=fakelibvirt.VIR_DOMAIN_XML_MIGRATABLE)
mock_migrate.assert_called_once_with(
drvr._live_migration_uri('dest'),
drvr._live_migration_uri('dest'), miguri=None,
dxml=target_xml, flags=mock.ANY, bandwidth=bandwidth)
def test_live_migration_uses_migrateToURI_without_dest_listen_addrs(self):
@ -7914,6 +7949,7 @@ class LibvirtConnTestCase(test.NoDBTestCase):
dom = fakelibvirt.virDomain
guest = libvirt_guest.Guest(dom)
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
instance = objects.Instance(**self.test_instance)
self.assertRaises(fakelibvirt.libvirtError,
drvr._live_migration_operation,
@ -7950,6 +7986,7 @@ class LibvirtConnTestCase(test.NoDBTestCase):
dom = fakelibvirt.virDomain
guest = libvirt_guest.Guest(dom)
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
drvr._parse_migration_flags()
instance = objects.Instance(**self.test_instance)
drvr._live_migration_operation(self.context, instance, 'dest',
@ -7978,6 +8015,7 @@ class LibvirtConnTestCase(test.NoDBTestCase):
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(

View File

@ -518,7 +518,7 @@ class GuestTestCase(test.NoDBTestCase):
def test_migrate_v2(self):
self.guest.migrate('an-uri', domain_xml='</xml>', flags=1, bandwidth=2)
self.domain.migrateToURI2.assert_called_once_with(
'an-uri', dxml='</xml>', flags=1, bandwidth=2)
'an-uri', miguri=None, dxml='</xml>', flags=1, bandwidth=2)
def test_migrate_v3(self):
self.guest.migrate('an-uri', domain_xml='</xml>',

View File

@ -128,8 +128,8 @@ class _FakeDriverBackendTestCase(object):
def fake_extend(image, size):
pass
def fake_migrate(_self, destination, params=None, flags=0,
domain_xml=None, bandwidth=0):
def fake_migrate(_self, destination, migrate_uri=None, params=None,
flags=0, domain_xml=None, bandwidth=0):
pass
def fake_make_drive(_self, _path):

View File

@ -659,6 +659,18 @@ class LibvirtDriver(driver.ComputeDriver):
raise exception.LiveMigrationURINotAvailable(virt_type=virt_type)
return uri % dest
@staticmethod
def _migrate_uri(dest):
uri = None
# Only QEMU live migrations supports migrate-uri parameter
virt_type = CONF.libvirt.virt_type
if virt_type in ('qemu', 'kvm'):
# QEMU accept two schemes: tcp and rdma. By default
# libvirt build the URI using the remote hostname and the
# tcp schema.
uri = 'tcp://%s' % dest
return uri
def instance_exists(self, instance):
"""Efficient override of base instance_exists method."""
try:
@ -5872,9 +5884,16 @@ class LibvirtDriver(driver.ComputeDriver):
self._check_graphics_addresses_can_live_migrate(listen_addrs)
self._verify_serial_console_is_disabled()
# NOTE(aplanas) migrate_uri will have a value only in the
# case that `live_migration_inbound_addr` parameter is
# set, and we propose a non tunneled migration.
migrate_uri = None
if ('target_connect_addr' in migrate_data and
migrate_data.target_connect_addr is not None):
dest = migrate_data.target_connect_addr
if (migration_flags &
libvirt.VIR_MIGRATE_TUNNELLED == 0):
migrate_uri = self._migrate_uri(dest)
new_xml_str = None
params = None
@ -5905,6 +5924,7 @@ class LibvirtDriver(driver.ComputeDriver):
params.pop('migrate_disks')
guest.migrate(self._live_migration_uri(dest),
migrate_uri=migrate_uri,
flags=migration_flags,
params=params,
domain_xml=new_xml_str,

View File

@ -522,11 +522,12 @@ class Guest(object):
"""
self._domain.suspend()
def migrate(self, destination, params=None, flags=0, domain_xml=None,
bandwidth=0):
def migrate(self, destination, migrate_uri=None, params=None, flags=0,
domain_xml=None, bandwidth=0):
"""Migrate guest object from its current host to the destination
:param destination: URI of host destination where guest will be migrate
:param migrate_uri: URI for invoking the migration
:param flags: May be one of more of the following:
VIR_MIGRATE_LIVE Do not pause the VM during migration
VIR_MIGRATE_PEER2PEER Direct connection between source &
@ -562,11 +563,15 @@ class Guest(object):
destination, flags=flags, bandwidth=bandwidth)
else:
if params:
if migrate_uri:
# In migrateToURI3 this paramenter is searched in
# the `params` dict
params['migrate_uri'] = migrate_uri
self._domain.migrateToURI3(
destination, params=params, flags=flags)
else:
self._domain.migrateToURI2(
destination, dxml=domain_xml,
destination, miguri=migrate_uri, dxml=domain_xml,
flags=flags, bandwidth=bandwidth)
def abort_job(self):