Fix migrate data object error in live migrate

Nova conductor live-migrate task utilize nova.objects.migrate_data
objects to maintain parameters through the whole live migration
process. The lagacy dict type of migrate data is no longer
supported.

Fix the un-supported migrate data error in this change.

Change-Id: If04287726aec4be11432db7410b71b13c6291783
This commit is contained in:
Huang Rui 2016-12-11 15:21:56 +08:00
parent b2b6be9eff
commit 6c7c6a379b
3 changed files with 29 additions and 162 deletions

View File

@ -986,107 +986,22 @@ class ZVMDriverTestCases(ZVMTestCase):
def test_live_migration_same_mn(self):
dest = 'fhost2'
migrate_data = {'dest_host': dest,
'pre_live_migration_result':
{'same_xcat_mn': True,
'dest_diff_mn_key': None}}
info = ["os000001: VMRELOCATE action=move against OS000001... Done\n"]
self._set_fake_xcat_responses([self._generate_xcat_resp(info)])
self._set_fake_xcat_responses([self._generate_xcat_resp(info),
self._generate_xcat_resp(info)])
self.driver.live_migration(self.context, self.instance, dest,
self._fake_fun(), self._fake_fun(), None,
migrate_data)
self.mox.VerifyAll()
def test_live_migration_diff_mn(self):
dest = 'fhost2'
migrate_data = {'dest_host': dest,
'pre_live_migration_result':
{'same_xcat_mn': False,
'dest_diff_mn_key': 'sshkey'}}
info = ["os000001: VMRELOCATE action=move against OS000001... Done\n"]
self.stubs.Set(zvmutils, "xdsh", self._fake_fun())
self.stubs.Set(self.driver._networkop, 'clean_mac_switch_host',
self._fake_fun())
self.stubs.Set(instance.ZVMInstance, 'delete_xcat_node',
self._fake_fun())
self._set_fake_xcat_resp([("PUT", None, None,
self._gen_resp(info=info))])
self.driver.live_migration(self.context, self.instance, dest,
self._fake_fun(), self._fake_fun(), None,
migrate_data)
None)
self.mox.VerifyAll()
def test_live_migration_failed(self):
dest = 'fhost2'
migrate_data = {'dest_host': dest,
'pre_live_migration_result':
{'same_xcat_mn': True,
'dest_diff_mn_key': None}}
info = ["os000001: VMRELOCATE MOVE error\n"]
self._set_fake_xcat_responses([self._gen_resp(info=info,
error=['error'])])
self.stubs.Set(zvmutils, "xdsh", self._fake_fun())
self.assertRaises(nova_exception.MigrationError,
self.driver.live_migration, self.context, self.instance, dest,
self._fake_fun(), self._fake_fun(), None, migrate_data)
self.mox.VerifyAll()
def test_check_can_live_migrate_destination(self):
dest = 'fhost2'
dest_info = {'hypervisor_hostname': dest}
res_dict = self.driver.check_can_live_migrate_destination(self.context,
self.instance, {}, dest_info, {}, {})
exp_dict = {'dest_host': dest,
'is_shared_storage': True}
self.assertEqual(res_dict.get('migrate_data', None), exp_dict)
def test_check_can_live_migrate_source(self):
dest = 'fhost2'
migrate_data = {'dest_host': dest,
'is_shared_storage': True}
dest_check_data = {'migrate_data': migrate_data}
info = ["os000001: VMRELOCATE action=test against OS000001... Done\n"]
self._set_fake_xcat_resp([
("GET", None, None, self._gen_resp(info=["userid=os000001"])),
("PUT", None, None, self._gen_resp(info=info))])
res_dict = self.driver.check_can_live_migrate_source(
self.context, self.instance, dest_check_data)
self.assertNotEqual(res_dict.get('dest_host', None), None)
self.mox.ReplayAll()
def test_check_can_live_migrate_source_failed(self):
dest = 'fhost2'
migrate_data = {'dest_host': dest}
dest_check_data = {'migrate_data': migrate_data}
error = ["VMRELOCATE move failed"]
self.mox.StubOutWithMock(zvmutils, "get_userid")
self.mox.StubOutWithMock(self.driver, "_vmrelocate")
zvmutils.get_userid('os000001').AndReturn("os000001")
self.driver._vmrelocate('fhost2', 'os000001', 'test').AndRaise(
nova_exception.MigrationError(reason=error))
self.mox.ReplayAll()
self.assertRaises(nova_exception.MigrationError,
self.driver.check_can_live_migrate_source, self.context,
self.instance, dest_check_data)
self.mox.VerifyAll()
def test_check_can_live_migrate_source_force(self):
self.flags(zvm_vmrelocate_force='domain')
dest = 'fhost2'
migrate_data = {'dest_host': dest}
dest_check_data = {'migrate_data': migrate_data}
self.mox.StubOutWithMock(zvmutils, "get_userid")
self.mox.StubOutWithMock(self.driver, "_vmrelocate")
zvmutils.get_userid('os000001').AndReturn("os000001")
self.driver._vmrelocate('fhost2', 'os000001', 'test').AndRaise(
nova_exception.MigrationError(reason="1944"))
self.mox.ReplayAll()
self.driver.check_can_live_migrate_source(self.context, self.instance,
dest_check_data)
self._fake_fun(), self._fake_fun(), None, None)
self.mox.VerifyAll()
def test_migrate_disk_and_power_off(self):

View File

@ -39,6 +39,7 @@ from nova import exception as nova_exception
from nova.i18n import _, _LI, _LW
from nova.image import api as image_api
from nova.image import glance
from nova.objects import migrate_data as migrate_data_obj
from nova import utils
from nova.virt import configdrive
from nova.virt import driver
@ -992,14 +993,7 @@ class ZVMDriver(driver.ComputeDriver):
:param block_migration: if true, prepare for block migration
:param disk_over_commit: if true, allow disk over commit
"""
# For z/VM, all live migration check will be done in
# check_can_live_migration_source, so just return a dst_compute_info.
# And we only support shared storage live migration.
migrate_data = {'dest_host': dst_compute_info['hypervisor_hostname'],
'is_shared_storage': True}
dest_check_data = {'migrate_data': migrate_data}
return dest_check_data
return migrate_data_obj.LibvirtLiveMigrateData()
def check_can_live_migrate_source(self, ctxt, instance_ref,
dest_check_data, block_device_info=None):
@ -1013,43 +1007,10 @@ class ZVMDriver(driver.ComputeDriver):
:param dest_check_data: result of check_can_live_migrate_destination
"""
LOG.info(_LI("Checking source host for live-migration for %s") %
instance_ref['name'], instance=instance_ref)
return migrate_data_obj.LibvirtLiveMigrateData()
migrate_data = dest_check_data.get('migrate_data', {})
dest_host = migrate_data.get('dest_host', None)
userid = zvmutils.get_userid(instance_ref['name'])
migrate_data.update({'source_xcat_mn': CONF.zvm_xcat_server,
'zvm_userid': userid})
if dest_host is not None:
try:
self._vmrelocate(dest_host, instance_ref['name'], 'test')
except nova_exception.MigrationError as err:
emsg = err.format_message()
if isinstance(CONF.zvm_vmrelocate_force, str):
force = CONF.zvm_vmrelocate_force.lower()
if ('domain' in force) or ('architecture' in force):
if '1944' in emsg:
# force domain/architecture in effect, ignore
return migrate_data
LOG.error(_("Live-migrating check failed: %s") % emsg,
instance=instance_ref)
raise nova_exception.MigrationPreCheckError(reason=emsg)
return migrate_data
else:
reason = _("Invalid migration data")
raise nova_exception.MigrationPreCheckError(reason=reason)
def check_can_live_migrate_destination_cleanup(self, ctxt,
def cleanup_live_migration_destination_check(self, ctxt,
dest_check_data):
"""Do required cleanup on dest host after check_can_live_migrate calls
:param ctxt: security context
:param dest_check_data: result of check_can_live_migrate_destination
"""
# For z/VM, nothing needed to be cleanup
return
@ -1070,16 +1031,6 @@ class ZVMDriver(driver.ComputeDriver):
raise nova_exception.MigrationError(reason=msg)
zvm_inst = ZVMInstance(self, instance_ref)
source_xcat_mn = migrate_data.get('source_xcat_mn', '')
userid = migrate_data.get('zvm_userid')
hcp = self._get_hcp_info()['hostname']
same_xcat_mn = source_xcat_mn == CONF.zvm_xcat_server
dest_diff_mn_key = None
if not same_xcat_mn:
# The two z/VM system managed by two different xCAT MN
zvm_inst.create_xcat_node(hcp, userid)
dest_diff_mn_key = zvmutils.get_mn_pub_key()
if network_info is not None:
network = network_info[0]['network']
ip_addr = network['subnets'][0]['ips'][0]['address']
@ -1087,8 +1038,7 @@ class ZVMDriver(driver.ComputeDriver):
zvm_inst._name)
self._networkop.makehosts()
return {'same_xcat_mn': same_xcat_mn,
'dest_diff_mn_key': dest_diff_mn_key}
return
def pre_block_migration(self, ctxt, instance_ref, disk_info):
"""Prepare a block device for migration
@ -1122,21 +1072,28 @@ class ZVMDriver(driver.ComputeDriver):
"""
inst_name = instance_ref['name']
dest_host = migrate_data['dest_host']
# Test can live migrate or not
force = CONF.zvm_vmrelocate_force
try:
self._vmrelocate(dest, inst_name, 'test')
except nova_exception.MigrationError as err:
emsg = err.format_message()
if (force and ('domain' in force.lower() or
'architecture' in force.lower()) and ('1944' in emsg)):
LOG.debug("Ignore VMRELOCATE 1944 error")
else:
LOG.error(_("Live-migrating check failed: %s") % emsg,
instance=instance_ref)
with excutils.save_and_reraise_exception():
recover_method(ctxt, instance_ref, dest,
block_migration, migrate_data)
LOG.info(_LI("Live-migrating %(inst)s to %(dest)s") %
{'inst': inst_name, 'dest': dest_host}, instance=instance_ref)
same_mn = migrate_data['pre_live_migration_result']['same_xcat_mn']
dest_diff_mn_key = migrate_data['pre_live_migration_result'].get(
'dest_diff_mn_key', None)
if not same_mn and dest_diff_mn_key:
auth_command = ('echo "%s" >> /root/.ssh/authorized_keys' %
dest_diff_mn_key)
zvmutils.xdsh(inst_name, auth_command)
{'inst': inst_name, 'dest': dest}, instance=instance_ref)
try:
self._vmrelocate(dest_host, inst_name, 'move')
self._vmrelocate(dest, inst_name, 'move')
except nova_exception.MigrationError as err:
LOG.error(_("Live-migration failed: %s") % err.format_message(),
instance=instance_ref)
@ -1144,12 +1101,6 @@ class ZVMDriver(driver.ComputeDriver):
recover_method(ctxt, instance_ref, dest,
block_migration, migrate_data)
if not same_mn:
# Delete node definition at source xCAT MN
zvm_inst = ZVMInstance(self, instance_ref)
self._networkop.clean_mac_switch_host(zvm_inst._name)
zvm_inst.delete_xcat_node()
post_method(ctxt, instance_ref, dest,
block_migration, migrate_data)

View File

@ -14,3 +14,4 @@ testscenarios>=0.4
testtools>=1.4.0
mock>=1.2
mox>=0.5.3
vine