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.

Conflicts:
	nova/tests/unit/virt/libvirt/test_driver.py

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

View File

@ -7483,6 +7483,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(
@ -7602,6 +7603,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):
@ -7688,6 +7690,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)
@ -7827,7 +7862,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)
@mock.patch.object(fakelibvirt, 'VIR_DOMAIN_XML_MIGRATABLE', None,
@ -7946,6 +7981,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,
@ -7982,6 +8018,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',
@ -8045,6 +8082,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

@ -521,7 +521,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

@ -656,6 +656,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:
@ -5863,9 +5875,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
@ -5897,6 +5916,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

@ -523,11 +523,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 &
@ -563,11 +564,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):