Merge "Actually pass the migration data object down to the virt drivers"

This commit is contained in:
Jenkins
2016-01-14 08:55:50 +00:00
committed by Gerrit Code Review
7 changed files with 218 additions and 164 deletions
+34 -13
View File
@@ -5110,7 +5110,10 @@ class ComputeManager(manager.Manager):
migrate_data)
if isinstance(pre_live_migration_data,
migrate_data_obj.LiveMigrateData):
pre_live_migration_data = pre_live_migration_data.to_legacy_dict()
pre_live_migration_data = pre_live_migration_data.to_legacy_dict(
pre_migration_result=True)
pre_live_migration_data = pre_live_migration_data[
'pre_live_migration_result']
# NOTE(tr3buchet): setup networks on destination host
self.network_api.setup_networks_on_host(context, instance,
@@ -5131,6 +5134,21 @@ class ComputeManager(manager.Manager):
return pre_live_migration_data
def _get_migrate_data_obj(self):
# FIXME(danms): A couple patches from now, we'll be able to
# avoid this failure _if_ we get a new-style call with the
# object.
if CONF.compute_driver.startswith('libvirt'):
return objects.LibvirtLiveMigrateData()
elif CONF.compute_driver.startswith('xenapi'):
return objects.XenapiLiveMigrateData()
else:
LOG.error(_('Older RPC caller and unsupported virt driver in '
'use. Unable to handle this!'))
raise exception.MigrationError(
_('Unknown compute driver while providing compatibility '
'with older RPC formats'))
def _do_live_migration(self, context, dest, instance, block_migration,
migration, migrate_data):
# NOTE(danms): We should enhance the RT to account for migrations
@@ -5154,7 +5172,8 @@ class ComputeManager(manager.Manager):
context, instance,
block_migration, disk, dest, migrate_data)
migrate_data['pre_live_migration_result'] = pre_migration_data
migrate_data_obj = self._get_migrate_data_obj()
migrate_data_obj.from_legacy_dict(migrate_data)
except Exception:
with excutils.save_and_reraise_exception():
LOG.exception(_LE('Pre live migration failed at %s'),
@@ -5165,12 +5184,12 @@ class ComputeManager(manager.Manager):
self._set_migration_status(migration, 'running')
migrate_data['migration'] = migration
migrate_data_obj.migration = migration
try:
self.driver.live_migration(context, instance, dest,
self._post_live_migration,
self._rollback_live_migration,
block_migration, migrate_data)
block_migration, migrate_data_obj)
except Exception:
# Executing live migration
# live_migration might raises exceptions, but
@@ -5227,11 +5246,9 @@ class ComputeManager(manager.Manager):
# block storage or instance path were shared
is_shared_block_storage = not block_migration
is_shared_instance_path = not block_migration
if migrate_data:
is_shared_block_storage = migrate_data.get(
'is_shared_block_storage', is_shared_block_storage)
is_shared_instance_path = migrate_data.get(
'is_shared_instance_path', is_shared_instance_path)
if isinstance(migrate_data, objects.LibvirtLiveMigrateData):
is_shared_block_storage = migrate_data.is_shared_block_storage
is_shared_instance_path = migrate_data.is_shared_instance_path
# No instance booting at source host, but instance dir
# must be deleted for preparing next block migration
@@ -5348,9 +5365,9 @@ class ComputeManager(manager.Manager):
instance=instance)
self._clean_instance_console_tokens(ctxt, instance)
if migrate_data and migrate_data.get('migration'):
migrate_data['migration'].status = 'completed'
migrate_data['migration'].save()
if migrate_data and migrate_data.obj_attr_is_set('migration'):
migrate_data.migration.status = 'completed'
migrate_data.migration.save()
def _consoles_enabled(self):
"""Returns whether a console is enable."""
@@ -5451,8 +5468,10 @@ class ComputeManager(manager.Manager):
# NOTE(danms): Pop out the migration object so we don't pass
# it over RPC unintentionally below
if migrate_data:
if isinstance(migrate_data, dict):
migration = migrate_data.pop('migration', None)
elif isinstance(migrate_data, migrate_data_obj.LiveMigrateData):
migration = migrate_data.migration
else:
migration = None
@@ -5473,6 +5492,8 @@ class ComputeManager(manager.Manager):
block_migration, migrate_data)
if do_cleanup:
if isinstance(migrate_data, migrate_data_obj.LiveMigrateData):
migrate_data = migrate_data.to_legacy_dict()
self.compute_rpcapi.rollback_live_migration_at_destination(
context, instance, dest, destroy_disks=destroy_disks,
migrate_data=migrate_data)
+20 -11
View File
@@ -68,6 +68,7 @@ from nova.network.security_group import openstack_driver
from nova import objects
from nova.objects import block_device as block_device_obj
from nova.objects import instance as instance_obj
from nova.objects import migrate_data as migrate_data_obj
from nova import policy
from nova import quota
from nova.scheduler import client as scheduler_client
@@ -5625,11 +5626,13 @@ class ComputeTestCase(BaseTestCase):
migration = objects.Migration()
ret = self.compute.live_migration(c, dest=dest,
instance=instance,
block_migration=False,
migration=migration,
migrate_data=migrate_data)
with mock.patch.object(self.compute, '_get_migrate_data_obj') as gmdo:
gmdo.return_value = migrate_data_obj.LiveMigrateData()
ret = self.compute.live_migration(c, dest=dest,
instance=instance,
block_migration=False,
migration=migration,
migrate_data=migrate_data)
self.assertIsNone(ret)
event_mock.assert_called_with(
@@ -5688,7 +5691,10 @@ class ComputeTestCase(BaseTestCase):
# start test
self.mox.ReplayAll()
migrate_data = {'is_shared_instance_path': False}
migrate_data = objects.LibvirtLiveMigrateData(
is_shared_instance_path=False,
is_shared_block_storage=False,
block_migration=False)
self.compute._post_live_migration(c, instance, dest,
migrate_data=migrate_data)
self.assertIn('cleanup', result)
@@ -5711,7 +5717,9 @@ class ComputeTestCase(BaseTestCase):
'power_state': power_state.PAUSED})
instance.save()
migrate_data = {'migration': mock.MagicMock()}
migration_obj = objects.Migration()
migrate_data = migrate_data_obj.LiveMigrateData(
migration=migration_obj)
# creating mocks
with test.nested(
@@ -5727,12 +5735,13 @@ class ComputeTestCase(BaseTestCase):
'setup_networks_on_host'),
mock.patch.object(self.compute.instance_events,
'clear_events_for_instance'),
mock.patch.object(self.compute, 'update_available_resource')
mock.patch.object(self.compute, 'update_available_resource'),
mock.patch.object(migration_obj, 'save'),
) as (
post_live_migration, unfilter_instance,
migrate_instance_start, post_live_migration_at_destination,
post_live_migration_at_source, setup_networks_on_host,
clear_events, update_available_resource
clear_events, update_available_resource, mig_save
):
self.compute._post_live_migration(c, instance, dest,
migrate_data=migrate_data)
@@ -5753,8 +5762,8 @@ class ComputeTestCase(BaseTestCase):
[mock.call(c, instance, [])])
clear_events.assert_called_once_with(instance)
update_available_resource.assert_has_calls([mock.call(c)])
self.assertEqual('completed', migrate_data['migration'].status)
migrate_data['migration'].save.assert_called_once_with()
self.assertEqual('completed', migration_obj.status)
mig_save.assert_called_once_with()
def test_post_live_migration_terminate_volume_connections(self):
c = context.get_admin_context()
+2 -1
View File
@@ -176,9 +176,10 @@ class _TestLibvirtLiveMigrateData(object):
serial_listen_addr='127.0.0.1',
bdms=[test_bdmi])
obj2 = migrate_data.LibvirtLiveMigrateData()
obj2.from_legacy_dict(obj.to_legacy_dict())
obj2.from_legacy_dict(obj.to_legacy_dict(pre_migration_result=True))
self.assertEqual(obj.to_legacy_dict(),
obj2.to_legacy_dict())
self.assertEqual(obj.bdms[0].serial, obj2.bdms[0].serial)
class TestLibvirtLiveMigrateData(test_objects._LocalTest,
+102 -79
View File
@@ -6523,6 +6523,11 @@ class LibvirtConnTestCase(test.NoDBTestCase):
migrate_data = {'pre_live_migration_result':
{'graphics_listen_addrs':
{'vnc': '10.0.0.1', 'spice': '10.0.0.2'}}}
migrate_data = objects.LibvirtLiveMigrateData(
graphics_listen_addr_vnc='10.0.0.1',
graphics_listen_addr_spice='10.0.0.2',
serial_listen_addr='127.0.0.1',
bdms=[])
self.mox.ReplayAll()
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
self.assertRaises(fakelibvirt.libvirtError,
@@ -6542,21 +6547,24 @@ class LibvirtConnTestCase(test.NoDBTestCase):
'ip-1.2.3.4:3260-iqn.'
'cde.67890.opst-lun-Z')
# start test
migrate_data = {'pre_live_migration_result':
{'volume': {u'58a84f6d-3f0c-4e19-a0af-eb657b790657':
{'connection_info': {u'driver_volume_type': u'iscsi',
'serial': u'58a84f6d-3f0c-4e19-a0af-eb657b790657',
u'data': {u'access_mode': u'rw', u'target_discovered': False,
u'target_iqn': u'ip-1.2.3.4:3260-iqn.cde.67890.opst-lun-Z',
u'volume_id': u'58a84f6d-3f0c-4e19-a0af-eb657b790657',
'device_path':
u'/dev/disk/by-path/ip-1.2.3.4:3260-iqn.cde.67890.opst-lun-Z'}},
'disk_info': {'bus': u'virtio', 'type': u'disk', 'dev': u'vdb'}}}},
'graphics_listen_addrs': {}}
pre_live_migrate_data = ((migrate_data or {}).
get('pre_live_migration_result', {}))
volume = pre_live_migrate_data.get('volume')
connection_info = {
u'driver_volume_type': u'iscsi',
u'serial': u'58a84f6d-3f0c-4e19-a0af-eb657b790657',
u'data': {
u'access_mode': u'rw', u'target_discovered': False,
u'target_iqn': u'ip-1.2.3.4:3260-iqn.cde.67890.opst-lun-Z',
u'volume_id': u'58a84f6d-3f0c-4e19-a0af-eb657b790657',
'device_path':
u'/dev/disk/by-path/ip-1.2.3.4:3260-iqn.cde.67890.opst-lun-Z',
},
}
bdm = objects.LibvirtLiveMigrateBDMInfo(
serial='58a84f6d-3f0c-4e19-a0af-eb657b790657',
bus='virtio', type='disk', dev='vdb',
connection_info=connection_info)
migrate_data = objects.LibvirtLiveMigrateData(
serial_listen_addr='',
bdms=[bdm])
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
test_mock = mock.MagicMock()
@@ -6574,7 +6582,8 @@ class LibvirtConnTestCase(test.NoDBTestCase):
self.assertFalse(drvr._live_migration_operation(
self.context, instance_ref, 'dest', False,
migrate_data, test_mock))
mupdate.assert_called_once_with(target_xml, volume, None, None)
mupdate.assert_called_once_with(target_xml, migrate_data.bdms,
{}, '')
def test_update_volume_xml(self):
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
@@ -6589,40 +6598,35 @@ class LibvirtConnTestCase(test.NoDBTestCase):
'cde.67890.opst-lun-Z')
target_xml = etree.tostring(etree.fromstring(target_xml))
serial = "58a84f6d-3f0c-4e19-a0af-eb657b790657"
volume_xml = {'volume': {}}
volume_xml['volume'][serial] = {'connection_info': {}, 'disk_info': {}}
volume_xml['volume'][serial]['connection_info'] = \
{u'driver_volume_type': u'iscsi',
bdmi = objects.LibvirtLiveMigrateBDMInfo(serial=serial,
bus='virtio',
type='disk',
dev='vdb')
bdmi.connection_info = {u'driver_volume_type': u'iscsi',
'serial': u'58a84f6d-3f0c-4e19-a0af-eb657b790657',
u'data': {u'access_mode': u'rw', u'target_discovered': False,
u'target_iqn': u'ip-1.2.3.4:3260-iqn.cde.67890.opst-lun-Z',
u'volume_id': u'58a84f6d-3f0c-4e19-a0af-eb657b790657',
'device_path':
u'/dev/disk/by-path/ip-1.2.3.4:3260-iqn.cde.67890.opst-lun-Z'}}
volume_xml['volume'][serial]['disk_info'] = {'bus': u'virtio',
'type': u'disk',
'dev': u'vdb'}
connection_info = volume_xml['volume'][serial]['connection_info']
disk_info = volume_xml['volume'][serial]['disk_info']
conf = vconfig.LibvirtConfigGuestDisk()
conf.source_device = disk_info['type']
conf.source_device = bdmi.type
conf.driver_name = "qemu"
conf.driver_format = "raw"
conf.driver_cache = "none"
conf.target_dev = disk_info['dev']
conf.target_bus = disk_info['bus']
conf.serial = connection_info.get('serial')
conf.target_dev = bdmi.dev
conf.target_bus = bdmi.bus
conf.serial = bdmi.connection_info.get('serial')
conf.source_type = "block"
conf.source_path = connection_info['data'].get('device_path')
conf.source_path = bdmi.connection_info['data'].get('device_path')
with mock.patch.object(drvr, '_get_volume_config',
return_value=conf):
parser = etree.XMLParser(remove_blank_text=True)
xml_doc = etree.fromstring(initial_xml, parser)
config = drvr._update_volume_xml(xml_doc,
volume_xml['volume'])
config = drvr._update_volume_xml(xml_doc, [bdmi])
xml_doc = etree.fromstring(target_xml, parser)
self.assertEqual(etree.tostring(xml_doc), etree.tostring(config))
@@ -6652,39 +6656,38 @@ class LibvirtConnTestCase(test.NoDBTestCase):
'abc.12345.opst-lun-X')
target_xml = etree.tostring(etree.fromstring(target_xml))
serial = "58a84f6d-3f0c-4e19-a0af-eb657b790657"
volume_xml = {'volume': {}}
volume_xml['volume'][serial] = {'connection_info': {}, 'disk_info': {}}
volume_xml['volume'][serial]['connection_info'] = \
{u'driver_volume_type': u'iscsi',
'serial': u'58a84f6d-3f0c-4e19-a0af-eb657b790657',
u'data': {u'access_mode': u'rw', u'target_discovered': False,
u'target_iqn': u'ip-1.2.3.4:3260-iqn.cde.67890.opst-lun-Z',
u'volume_id': u'58a84f6d-3f0c-4e19-a0af-eb657b790657',
'device_path':
u'/dev/disk/by-path/ip-1.2.3.4:3260-iqn.cde.67890.opst-lun-Z'}}
volume_xml['volume'][serial]['disk_info'] = {'bus': u'virtio',
'type': u'disk',
'dev': u'vdb'}
connection_info = volume_xml['volume'][serial]['connection_info']
disk_info = volume_xml['volume'][serial]['disk_info']
connection_info = {
u'driver_volume_type': u'iscsi',
'serial': u'58a84f6d-3f0c-4e19-a0af-eb657b790657',
u'data': {
u'access_mode': u'rw', u'target_discovered': False,
u'target_iqn': u'ip-1.2.3.4:3260-iqn.cde.67890.opst-lun-Z',
u'volume_id': u'58a84f6d-3f0c-4e19-a0af-eb657b790657',
u'device_path':
u'/dev/disk/by-path/ip-1.2.3.4:3260-iqn.cde.67890.opst-lun-Z',
},
}
bdmi = objects.LibvirtLiveMigrateBDMInfo(serial=serial,
bus='virtio',
dev='vdb',
type='disk')
bdmi.connection_info = connection_info
conf = vconfig.LibvirtConfigGuestDisk()
conf.source_device = disk_info['type']
conf.source_device = bdmi.type
conf.driver_name = "qemu"
conf.driver_format = "raw"
conf.driver_cache = "none"
conf.target_dev = disk_info['dev']
conf.target_bus = disk_info['bus']
conf.serial = connection_info.get('serial')
conf.target_dev = bdmi.dev
conf.target_bus = bdmi.bus
conf.serial = bdmi.connection_info.get('serial')
conf.source_type = "block"
conf.source_path = connection_info['data'].get('device_path')
conf.source_path = bdmi.connection_info['data'].get('device_path')
with mock.patch.object(drvr, '_get_volume_config',
return_value=conf):
xml_doc = etree.fromstring(initial_xml)
config = drvr._update_volume_xml(xml_doc,
volume_xml['volume'])
config = drvr._update_volume_xml(xml_doc, [bdmi])
self.assertEqual(target_xml, etree.tostring(config))
def test_update_volume_xml_no_connection_info(self):
@@ -6699,14 +6702,17 @@ class LibvirtConnTestCase(test.NoDBTestCase):
'abc.12345.opst-lun-X')
target_xml = etree.tostring(etree.fromstring(target_xml))
serial = "58a84f6d-3f0c-4e19-a0af-eb657b790657"
volume_xml = {'volume': {}}
volume_xml['volume'][serial] = {'info1': {}, 'info2': {}}
bdmi = objects.LibvirtLiveMigrateBDMInfo(serial=serial,
dev='vdb',
type='disk',
bus='scsi',
format='qcow')
bdmi.connection_info = {}
conf = vconfig.LibvirtConfigGuestDisk()
with mock.patch.object(drvr, '_get_volume_config',
return_value=conf):
xml_doc = etree.fromstring(initial_xml)
config = drvr._update_volume_xml(xml_doc,
volume_xml['volume'])
config = drvr._update_volume_xml(xml_doc, [bdmi])
self.assertEqual(target_xml, etree.tostring(config))
@mock.patch.object(fakelibvirt.virDomain, "migrateToURI2")
@@ -6735,10 +6741,11 @@ class LibvirtConnTestCase(test.NoDBTestCase):
# start test
bandwidth = CONF.libvirt.live_migration_bandwidth
migrate_data = {'pre_live_migration_result':
{'graphics_listen_addrs':
{'vnc': '10.0.0.1', 'spice': '10.0.0.2'},
'serial_listen_addr': '9.0.0.12'}}
migrate_data = objects.LibvirtLiveMigrateData(
graphics_listen_addr_vnc='10.0.0.1',
graphics_listen_addr_spice='10.0.0.2',
serial_listen_addr='9.0.0.12',
bdms=[])
dom = fakelibvirt.virDomain
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
self.assertRaises(fakelibvirt.libvirtError,
@@ -6759,12 +6766,14 @@ class LibvirtConnTestCase(test.NoDBTestCase):
CONF.set_override("enabled", True, "serial_console")
dom = fakelibvirt.virDomain
migrate_data = objects.LibvirtLiveMigrateData(
serial_listen_addr='')
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
self.assertRaises(exception.MigrationError,
drvr._live_migration_operation,
self.context, instance_ref, 'dest',
False, None, dom)
False, migrate_data, dom)
def test_live_migration_fails_with_invalid_live_migration_flag(self):
self.flags(live_migration_flag="VIR_MIGRATE_UNDEFINE_SOURCE, "
@@ -6802,9 +6811,11 @@ class LibvirtConnTestCase(test.NoDBTestCase):
fakelibvirt.libvirtError("ERR"))
# start test
migrate_data = {'pre_live_migration_result':
{'graphics_listen_addrs':
{'vnc': '0.0.0.0', 'spice': '0.0.0.0'}}}
migrate_data = objects.LibvirtLiveMigrateData(
graphics_listen_addr_vnc='0.0.0.0',
graphics_listen_addr_spice='0.0.0.0',
serial_listen_addr='127.0.0.1',
bdms=[])
self.mox.ReplayAll()
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
self.assertRaises(fakelibvirt.libvirtError,
@@ -6831,7 +6842,9 @@ class LibvirtConnTestCase(test.NoDBTestCase):
fakelibvirt.libvirtError("ERR"))
# start test
migrate_data = {}
migrate_data = objects.LibvirtLiveMigrateData(
serial_listen_addr='',
bdms=[])
self.mox.ReplayAll()
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
self.assertRaises(fakelibvirt.libvirtError,
@@ -6855,9 +6868,10 @@ class LibvirtConnTestCase(test.NoDBTestCase):
self.mox.StubOutWithMock(vdmock, "migrateToURI")
# start test
migrate_data = {'pre_live_migration_result':
{'graphics_listen_addrs':
{'vnc': '1.2.3.4', 'spice': '1.2.3.4'}}}
migrate_data = objects.LibvirtLiveMigrateData(
graphics_listen_addr_vnc='1.2.3.4',
graphics_listen_addr_spice='1.2.3.4',
serial_listen_addr='127.0.0.1')
self.mox.ReplayAll()
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
self.assertRaises(exception.MigrationError,
@@ -6897,9 +6911,11 @@ class LibvirtConnTestCase(test.NoDBTestCase):
fakelibvirt.libvirtError('ERR'))
# start test
migrate_data = {'pre_live_migration_result':
{'graphics_listen_addrs':
{'vnc': '127.0.0.1', 'spice': '127.0.0.1'}}}
migrate_data = objects.LibvirtLiveMigrateData(
graphics_listen_addr_vnc='127.0.0.1',
graphics_listen_addr_spice='127.0.0.1',
serial_listen_addr='127.0.0.1',
bdms=[])
self.mox.ReplayAll()
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
self.assertRaises(fakelibvirt.libvirtError,
@@ -6940,8 +6956,11 @@ class LibvirtConnTestCase(test.NoDBTestCase):
_bandwidth).AndRaise(test.TestingException('oops'))
graphics_listen_addrs = {'vnc': '0.0.0.0', 'spice': '127.0.0.1'}
migrate_data = {'pre_live_migration_result':
{'graphics_listen_addrs': graphics_listen_addrs}}
migrate_data = objects.LibvirtLiveMigrateData(
graphics_listen_addr_vnc='0.0.0.0',
graphics_listen_addr_spice='127.0.0.1',
serial_listen_addr='127.0.0.1',
bdms=[])
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
self.mox.StubOutWithMock(
@@ -6972,7 +6991,9 @@ class LibvirtConnTestCase(test.NoDBTestCase):
mock_get_instance_path.return_value = fake_instance_path
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
migrate_data = {'is_shared_instance_path': False}
migrate_data = objects.LibvirtLiveMigrateData(
is_shared_instance_path=False,
instance_relative_path=False)
self.assertRaises(exception.Invalid,
drvr.rollback_live_migration_at_destination,
"context", "instance", [], None, True, migrate_data)
@@ -6990,7 +7011,9 @@ class LibvirtConnTestCase(test.NoDBTestCase):
):
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
migrate_data = {'is_shared_instance_path': True}
migrate_data = objects.LibvirtLiveMigrateData(
is_shared_instance_path=True,
instance_relative_path=False)
drvr.rollback_live_migration_at_destination("context", "instance", [],
None, True, migrate_data)
mock_destroy.assert_called_once_with("context", "instance", [],
+25 -16
View File
@@ -3537,16 +3537,16 @@ class XenAPILiveMigrateTestCase(stubs.XenAPITestBaseNoDB):
self.stubs.Set(self.conn._vmops, "_make_plugin_call",
fake_make_plugin_call)
dest_check_data = {'block_migration': True,
'is_volume_backed': True,
'migrate_data': {
'destination_sr_ref': None,
'migrate_send_data': None
}}
dest_check_data = objects.XenapiLiveMigrateData(
block_migration=True,
is_volume_backed=True,
destination_sr_ref=None,
migrate_send_data=None)
result = self.conn.check_can_live_migrate_source(self.context,
{'host': 'host'},
dest_check_data)
self.assertEqual(dest_check_data, result.to_legacy_dict())
self.assertEqual(dest_check_data.to_legacy_dict(),
result.to_legacy_dict())
def test_check_can_live_migrate_source_with_block_iscsi_fails(self):
stubs.stubout_session(self.stubs, stubs.FakeSessionForVMTests)
@@ -3677,8 +3677,9 @@ class XenAPILiveMigrateTestCase(stubs.XenAPITestBaseNoDB):
post_method.called = True
# pass block_migration = True and migrate data
migrate_data = {"destination_sr_ref": "foo",
"migrate_send_data": "bar"}
migrate_data = objects.XenapiLiveMigrateData(
destination_sr_ref="foo",
migrate_send_data={"bar": "baz"})
self.conn.live_migration(self.conn, None, None, post_method, None,
True, migrate_data)
self.assertTrue(post_method.called, "post_method.called")
@@ -3703,8 +3704,9 @@ class XenAPILiveMigrateTestCase(stubs.XenAPITestBaseNoDB):
block_migration, migrate_data):
post_method.called = True
migrate_data = {"destination_sr_ref": "foo",
"migrate_send_data": "bar"}
migrate_data = objects.XenapiLiveMigrateData(
destination_sr_ref="foo",
migrate_send_data={"bar": "baz"})
self.conn.live_migration(self.conn, None, None, post_method, None,
True, migrate_data)
@@ -3737,7 +3739,9 @@ class XenAPILiveMigrateTestCase(stubs.XenAPITestBaseNoDB):
block_migration):
recover_method.called = True
# pass block_migration = True and migrate data
migrate_data = dict(destination_sr_ref='foo', migrate_send_data='bar')
migrate_data = objects.XenapiLiveMigrateData(
destination_sr_ref='foo',
migrate_send_data={'bar': 'baz'})
self.assertRaises(exception.MigrationError,
self.conn.live_migration, self.conn,
None, None, None, recover_method, True, migrate_data)
@@ -3750,7 +3754,7 @@ class XenAPILiveMigrateTestCase(stubs.XenAPITestBaseNoDB):
class Session(xenapi_fake.SessionBase):
def VM_migrate_send(self_, session, vmref, migrate_data, islive,
vdi_map, vif_map, options):
self.assertEqual('SOMEDATA', migrate_data)
self.assertEqual({'SOMEDATA': 'SOMEVAL'}, migrate_data)
self.assertEqual(fake_vdi_map, vdi_map)
stubs.stubout_session(self.stubs, Session)
@@ -3768,12 +3772,14 @@ class XenAPILiveMigrateTestCase(stubs.XenAPITestBaseNoDB):
def dummy_callback(*args, **kwargs):
pass
migrate_data = objects.XenapiLiveMigrateData(
migrate_send_data={'SOMEDATA': 'SOMEVAL'},
destination_sr_ref='TARGET_SR_OPAQUE_REF')
conn.live_migration(
self.context, instance=dict(name='ignore'), dest=None,
post_method=dummy_callback, recover_method=dummy_callback,
block_migration="SOMEDATA",
migrate_data=dict(migrate_send_data='SOMEDATA',
destination_sr_ref="TARGET_SR_OPAQUE_REF"))
migrate_data=migrate_data)
def test_live_migrate_pool_migration_xapi_call_parameters(self):
@@ -3796,10 +3802,13 @@ class XenAPILiveMigrateTestCase(stubs.XenAPITestBaseNoDB):
def dummy_callback(*args, **kwargs):
pass
migrate_data = objects.XenapiLiveMigrateData(
migrate_send_data={'foo': 'bar'},
destination_sr_ref='foo')
self.assertRaises(IOError, conn.live_migration,
self.context, instance=dict(name='ignore'), dest=None,
post_method=dummy_callback, recover_method=dummy_callback,
block_migration=False, migrate_data={})
block_migration=False, migrate_data=migrate_data)
def test_generate_vdi_map(self):
stubs.stubout_session(self.stubs, xenapi_fake.SessionBase)
+28 -33
View File
@@ -5559,11 +5559,12 @@ class LibvirtDriver(driver.ComputeDriver):
post_method, recover_method, block_migration,
migrate_data)
def _update_xml(self, xml_str, volume, listen_addrs, serial_listen_addr):
def _update_xml(self, xml_str, migrate_bdm_info, listen_addrs,
serial_listen_addr):
xml_doc = etree.fromstring(xml_str)
if volume:
xml_doc = self._update_volume_xml(xml_doc, volume)
if migrate_bdm_info:
xml_doc = self._update_volume_xml(xml_doc, migrate_bdm_info)
if listen_addrs:
xml_doc = self._update_graphics_xml(xml_doc, listen_addrs)
else:
@@ -5589,24 +5590,23 @@ class LibvirtDriver(driver.ComputeDriver):
return xml_doc
def _update_volume_xml(self, xml_doc, volume):
def _update_volume_xml(self, xml_doc, migrate_bdm_info):
"""Update XML using device information of destination host."""
# Update volume xml
parser = etree.XMLParser(remove_blank_text=True)
disk_nodes = xml_doc.findall('./devices/disk')
bdm_info_by_serial = {x.serial: x for x in migrate_bdm_info}
for pos, disk_dev in enumerate(disk_nodes):
serial_source = disk_dev.findtext('serial')
if serial_source is None or volume.get(serial_source) is None:
bdm_info = bdm_info_by_serial.get(serial_source)
if (serial_source is None or
not bdm_info or not bdm_info.connection_info or
serial_source not in bdm_info_by_serial):
continue
if ('connection_info' not in volume[serial_source] or
'disk_info' not in volume[serial_source]):
continue
conf = self._get_volume_config(
volume[serial_source]['connection_info'],
volume[serial_source]['disk_info'])
bdm_info.connection_info, bdm_info.as_disk_info())
xml_doc2 = etree.XML(conf.to_xml(), parser)
serial_dest = xml_doc2.findtext('serial')
@@ -5663,9 +5663,9 @@ class LibvirtDriver(driver.ComputeDriver):
' the local address (127.0.0.1 or ::1).')
raise exception.MigrationError(reason=msg)
if listen_addrs is not None:
dest_local_vnc = listen_addrs['vnc'] in LOCAL_ADDRS
dest_local_spice = listen_addrs['spice'] in LOCAL_ADDRS
if listen_addrs:
dest_local_vnc = listen_addrs.get('vnc') in LOCAL_ADDRS
dest_local_spice = listen_addrs.get('spice') in LOCAL_ADDRS
if ((CONF.vnc.enabled and not dest_local_vnc) or
(CONF.spice.enabled and not dest_local_spice)):
@@ -5730,18 +5730,20 @@ class LibvirtDriver(driver.ComputeDriver):
flagvals = [getflag(x.strip()) for x in flaglist]
logical_sum = six.moves.reduce(lambda x, y: x | y, flagvals)
pre_live_migrate_data = (migrate_data or {}).get(
'pre_live_migration_result', {})
listen_addrs = pre_live_migrate_data.get('graphics_listen_addrs')
volume = pre_live_migrate_data.get('volume')
serial_listen_addr = pre_live_migrate_data.get(
'serial_listen_addr')
listen_addrs = {}
if 'graphics_listen_addr_vnc' in migrate_data:
listen_addrs['vnc'] = str(
migrate_data.graphics_listen_addr_vnc)
if 'graphics_listen_addr_spice' in migrate_data:
listen_addrs['spice'] = str(
migrate_data.graphics_listen_addr_spice)
serial_listen_addr = migrate_data.serial_listen_addr
migratable_flag = getattr(libvirt, 'VIR_DOMAIN_XML_MIGRATABLE',
None)
if (migratable_flag is None or
(listen_addrs is None and not volume)):
if (migratable_flag is None or (
not listen_addrs and not migrate_data.bdms)):
# TODO(alexs-h): These checks could be moved to the
# check_can_live_migrate_destination/source phase
self._check_graphics_addresses_can_live_migrate(listen_addrs)
@@ -5753,7 +5755,7 @@ class LibvirtDriver(driver.ComputeDriver):
else:
old_xml_str = guest.get_xml_desc(dump_migratable=True)
new_xml_str = self._update_xml(old_xml_str,
volume,
migrate_data.bdms,
listen_addrs,
serial_listen_addr)
try:
@@ -6270,18 +6272,11 @@ class LibvirtDriver(driver.ComputeDriver):
# NOTE(gcb): Failed block live migration may leave instance
# directory at destination node, ensure it is always deleted.
is_shared_instance_path = True
instance_relative_path = None
if migrate_data:
is_shared_instance_path = migrate_data.get(
'is_shared_instance_path', True)
instance_relative_path = migrate_data.get(
'instance_relative_path')
mdo = objects.LibvirtLiveMigrateData()
if instance_relative_path:
mdo.instance_relative_path = instance_relative_path
is_shared_instance_path = migrate_data.is_shared_instance_path
if not is_shared_instance_path:
instance_dir = libvirt_utils.get_instance_path_at_destination(
instance, mdo)
instance, migrate_data)
if os.path.exists(instance_dir):
shutil.rmtree(instance_dir)
+7 -11
View File
@@ -2198,13 +2198,9 @@ class VMOps(object):
if ('block_migration' in dest_check_data and
dest_check_data.block_migration):
vm_ref = self._get_vm_opaque_ref(instance_ref)
migrate_data = {
'destination_sr_ref': dest_check_data.destination_sr_ref,
'migrate_send_data': dest_check_data.migrate_send_data,
}
try:
self._call_live_migrate_command(
"VM.assert_can_migrate", vm_ref, migrate_data)
"VM.assert_can_migrate", vm_ref, dest_check_data)
except self._session.XenAPI.Failure as exc:
reason = exc.details[0]
msg = _('assert_can_migrate failed because: %s') % reason
@@ -2288,8 +2284,8 @@ class VMOps(object):
def _call_live_migrate_command(self, command_name, vm_ref, migrate_data):
"""unpack xapi specific parameters, and call a live migrate command."""
destination_sr_ref = migrate_data['destination_sr_ref']
migrate_send_data = migrate_data['migrate_send_data']
destination_sr_ref = migrate_data.destination_sr_ref
migrate_send_data = migrate_data.migrate_send_data
vdi_map = self._generate_vdi_map(destination_sr_ref, vm_ref)
@@ -2331,8 +2327,8 @@ class VMOps(object):
if migrate_data is not None:
(kernel, ramdisk) = vm_utils.lookup_kernel_ramdisk(
self._session, vm_ref)
migrate_data['kernel-file'] = kernel
migrate_data['ramdisk-file'] = ramdisk
migrate_data.kernel_file = kernel
migrate_data.ramdisk_file = ramdisk
if block_migration:
if not migrate_data:
@@ -2366,8 +2362,8 @@ class VMOps(object):
def post_live_migration(self, context, instance, migrate_data=None):
if migrate_data is not None:
vm_utils.destroy_kernel_ramdisk(self._session, instance,
migrate_data.get('kernel-file'),
migrate_data.get('ramdisk-file'))
migrate_data.kernel_file,
migrate_data.ramdisk_file)
def post_live_migration_at_destination(self, context, instance,
network_info, block_migration,