Merge "Send a full instance in pre_live_migration."
This commit is contained in:
@@ -295,7 +295,7 @@ def _get_additional_capabilities():
|
||||
class ComputeManager(manager.SchedulerDependentManager):
|
||||
"""Manages the running instances from creation to destruction."""
|
||||
|
||||
RPC_API_VERSION = '1.22'
|
||||
RPC_API_VERSION = '1.23'
|
||||
|
||||
def __init__(self, compute_driver=None, *args, **kwargs):
|
||||
"""Load configuration options and connect to the hypervisor."""
|
||||
@@ -2159,7 +2159,7 @@ class ComputeManager(manager.SchedulerDependentManager):
|
||||
self.driver.check_can_live_migrate_source(ctxt, instance,
|
||||
dest_check_data)
|
||||
|
||||
def pre_live_migration(self, context, instance_id,
|
||||
def pre_live_migration(self, context, instance=None, instance_id=None,
|
||||
block_migration=False, disk=None):
|
||||
"""Preparations for live migration at dest host.
|
||||
|
||||
@@ -2168,16 +2168,17 @@ class ComputeManager(manager.SchedulerDependentManager):
|
||||
:param block_migration: if true, prepare for block migration
|
||||
|
||||
"""
|
||||
# Getting instance info
|
||||
instance_ref = self.db.instance_get(context, instance_id)
|
||||
if not instance:
|
||||
# Getting instance info
|
||||
instance = self.db.instance_get(context, instance_id)
|
||||
|
||||
# If any volume is mounted, prepare here.
|
||||
block_device_info = self._get_instance_volume_block_device_info(
|
||||
context, instance_ref['uuid'])
|
||||
context, instance['uuid'])
|
||||
if not block_device_info['block_device_mapping']:
|
||||
LOG.info(_('Instance has no volume.'), instance=instance_ref)
|
||||
LOG.info(_('Instance has no volume.'), instance=instance)
|
||||
|
||||
network_info = self._get_instance_nw_info(context, instance_ref)
|
||||
network_info = self._get_instance_nw_info(context, instance)
|
||||
|
||||
# TODO(tr3buchet): figure out how on the earth this is necessary
|
||||
fixed_ips = network_info.fixed_ips()
|
||||
@@ -2185,12 +2186,12 @@ class ComputeManager(manager.SchedulerDependentManager):
|
||||
raise exception.FixedIpNotFoundForInstance(
|
||||
instance_id=instance_id)
|
||||
|
||||
self.driver.pre_live_migration(context, instance_ref,
|
||||
self.driver.pre_live_migration(context, instance,
|
||||
block_device_info,
|
||||
self._legacy_nw_info(network_info))
|
||||
|
||||
# NOTE(tr3buchet): setup networks on destination host
|
||||
self.network_api.setup_networks_on_host(context, instance_ref,
|
||||
self.network_api.setup_networks_on_host(context, instance,
|
||||
self.host)
|
||||
|
||||
# Creating filters to hypervisors and firewalls.
|
||||
@@ -2199,14 +2200,12 @@ class ComputeManager(manager.SchedulerDependentManager):
|
||||
# This nwfilter is necessary on the destination host.
|
||||
# In addition, this method is creating filtering rule
|
||||
# onto destination host.
|
||||
self.driver.ensure_filtering_rules_for_instance(instance_ref,
|
||||
self.driver.ensure_filtering_rules_for_instance(instance,
|
||||
self._legacy_nw_info(network_info))
|
||||
|
||||
# Preparation for block migration
|
||||
if block_migration:
|
||||
self.driver.pre_block_migration(context,
|
||||
instance_ref,
|
||||
disk)
|
||||
self.driver.pre_block_migration(context, instance, disk)
|
||||
|
||||
def live_migration(self, context, instance_id,
|
||||
dest, block_migration=False):
|
||||
|
||||
@@ -88,6 +88,8 @@ class ComputeAPI(nova.openstack.common.rpc.proxy.RpcProxy):
|
||||
power_off_instance() and stop_instance()
|
||||
1.22 - Remove instance_uuid, add instance argument to
|
||||
power_on_instance() and start_instance()
|
||||
1.23 - Remove instance_id, add instance argument to
|
||||
pre_live_migration()
|
||||
'''
|
||||
|
||||
BASE_RPC_API_VERSION = '1.0'
|
||||
@@ -270,9 +272,11 @@ class ComputeAPI(nova.openstack.common.rpc.proxy.RpcProxy):
|
||||
|
||||
def pre_live_migration(self, ctxt, instance, block_migration, disk,
|
||||
host):
|
||||
instance_p = jsonutils.to_primitive(instance)
|
||||
return self.call(ctxt, self.make_msg('pre_live_migration',
|
||||
instance_id=instance['id'], block_migration=block_migration,
|
||||
disk=disk), _compute_topic(self.topic, ctxt, host, None))
|
||||
instance=instance_p, block_migration=block_migration,
|
||||
disk=disk), _compute_topic(self.topic, ctxt, host, None),
|
||||
version='1.23')
|
||||
|
||||
def reboot_instance(self, ctxt, instance, reboot_type):
|
||||
instance_p = jsonutils.to_primitive(instance)
|
||||
|
||||
@@ -1532,12 +1532,13 @@ class ComputeTestCase(BaseTestCase):
|
||||
"""Confirm raising exception if instance doesn't have fixed_ip."""
|
||||
# creating instance testdata
|
||||
context = self.context.elevated()
|
||||
inst_ref = self._create_fake_instance()
|
||||
inst_id = inst_ref["id"]
|
||||
instance = jsonutils.to_primitive(self._create_fake_instance())
|
||||
inst_id = instance["id"]
|
||||
|
||||
self.mox.ReplayAll()
|
||||
self.assertRaises(exception.FixedIpNotFoundForInstance,
|
||||
self.compute.pre_live_migration, context, inst_id)
|
||||
self.compute.pre_live_migration, context,
|
||||
instance=instance)
|
||||
|
||||
def test_pre_live_migration_works_correctly(self):
|
||||
"""Confirm setup_compute_volume is called when volume is mounted."""
|
||||
@@ -1548,38 +1549,40 @@ class ComputeTestCase(BaseTestCase):
|
||||
'_get_instance_nw_info', stupid)
|
||||
|
||||
# creating instance testdata
|
||||
inst_ref = self._create_fake_instance({'host': 'dummy'})
|
||||
inst_id = inst_ref['id']
|
||||
instance = jsonutils.to_primitive(self._create_fake_instance(
|
||||
{'host': 'dummy'}))
|
||||
inst_id = instance['id']
|
||||
c = context.get_admin_context()
|
||||
nw_info = fake_network.fake_get_instance_nw_info(self.stubs)
|
||||
|
||||
# creating mocks
|
||||
self.mox.StubOutWithMock(self.compute.driver, 'pre_live_migration')
|
||||
self.compute.driver.pre_live_migration(mox.IsA(c), mox.IsA(inst_ref),
|
||||
self.compute.driver.pre_live_migration(mox.IsA(c), mox.IsA(instance),
|
||||
{'block_device_mapping': []},
|
||||
mox.IgnoreArg())
|
||||
self.mox.StubOutWithMock(self.compute.driver,
|
||||
'ensure_filtering_rules_for_instance')
|
||||
self.compute.driver.ensure_filtering_rules_for_instance(
|
||||
mox.IsA(inst_ref), nw_info)
|
||||
mox.IsA(instance), nw_info)
|
||||
|
||||
# start test
|
||||
self.mox.ReplayAll()
|
||||
ret = self.compute.pre_live_migration(c, inst_id)
|
||||
ret = self.compute.pre_live_migration(c, instance=instance)
|
||||
self.assertEqual(ret, None)
|
||||
|
||||
# cleanup
|
||||
db.instance_destroy(c, inst_ref['uuid'])
|
||||
db.instance_destroy(c, instance['uuid'])
|
||||
|
||||
def test_live_migration_dest_raises_exception(self):
|
||||
"""Confirm exception when pre_live_migration fails."""
|
||||
# creating instance testdata
|
||||
inst_ref = self._create_fake_instance({'host': 'dummy'})
|
||||
inst_uuid = inst_ref['uuid']
|
||||
inst_id = inst_ref['id']
|
||||
instance_ref = self._create_fake_instance({'host': 'dummy'})
|
||||
instance = jsonutils.to_primitive(instance_ref)
|
||||
inst_uuid = instance['uuid']
|
||||
inst_id = instance['id']
|
||||
|
||||
c = context.get_admin_context()
|
||||
topic = rpc.queue_get_for(c, FLAGS.compute_topic, inst_ref['host'])
|
||||
topic = rpc.queue_get_for(c, FLAGS.compute_topic, instance['host'])
|
||||
|
||||
# creating volume testdata
|
||||
volume_id = db.volume_create(c, {'size': 1})['id']
|
||||
@@ -1595,12 +1598,12 @@ class ComputeTestCase(BaseTestCase):
|
||||
|
||||
self.mox.StubOutWithMock(self.compute.driver,
|
||||
'get_instance_disk_info')
|
||||
self.compute.driver.get_instance_disk_info(inst_ref.name)
|
||||
self.compute.driver.get_instance_disk_info(instance['name'])
|
||||
|
||||
self.mox.StubOutWithMock(self.compute.compute_rpcapi,
|
||||
'pre_live_migration')
|
||||
self.compute.compute_rpcapi.pre_live_migration(c, mox.IsA(inst_ref),
|
||||
True, None, inst_ref['host']).AndRaise(
|
||||
self.compute.compute_rpcapi.pre_live_migration(c,
|
||||
mox.IsA(instance_ref), True, None, instance['host']).AndRaise(
|
||||
rpc.common.RemoteError('', '', ''))
|
||||
|
||||
# mocks for rollback
|
||||
@@ -1622,7 +1625,7 @@ class ComputeTestCase(BaseTestCase):
|
||||
self.mox.ReplayAll()
|
||||
self.assertRaises(rpc_common.RemoteError,
|
||||
self.compute.live_migration,
|
||||
c, inst_id, inst_ref['host'], True)
|
||||
c, inst_id, instance['host'], True)
|
||||
|
||||
# cleanup
|
||||
for bdms in db.block_device_mapping_get_all_by_instance(
|
||||
@@ -1635,24 +1638,26 @@ class ComputeTestCase(BaseTestCase):
|
||||
"""Confirm live_migration() works as expected correctly."""
|
||||
# creating instance testdata
|
||||
c = context.get_admin_context()
|
||||
inst_ref = self._create_fake_instance({'host': 'dummy'})
|
||||
inst_uuid = inst_ref['uuid']
|
||||
inst_id = inst_ref['id']
|
||||
instance_ref = self._create_fake_instance({'host': 'dummy'})
|
||||
inst_uuid = instance_ref['uuid']
|
||||
inst_id = instance_ref['id']
|
||||
|
||||
instance = jsonutils.to_primitive(db.instance_get(c, inst_id))
|
||||
|
||||
# create
|
||||
self.mox.StubOutWithMock(rpc, 'call')
|
||||
topic = rpc.queue_get_for(c, FLAGS.compute_topic, inst_ref['host'])
|
||||
topic = rpc.queue_get_for(c, FLAGS.compute_topic, instance['host'])
|
||||
rpc.call(c, topic,
|
||||
{"method": "pre_live_migration",
|
||||
"args": {'instance_id': inst_id,
|
||||
"args": {'instance': instance,
|
||||
'block_migration': False,
|
||||
'disk': None},
|
||||
"version": compute_rpcapi.ComputeAPI.BASE_RPC_API_VERSION},
|
||||
"version": '1.23'},
|
||||
None)
|
||||
|
||||
# start test
|
||||
self.mox.ReplayAll()
|
||||
ret = self.compute.live_migration(c, inst_id, inst_ref['host'])
|
||||
ret = self.compute.live_migration(c, inst_id, instance['host'])
|
||||
self.assertEqual(ret, None)
|
||||
|
||||
# cleanup
|
||||
|
||||
@@ -56,8 +56,9 @@ class ComputeRpcAPITestCase(test.TestCase):
|
||||
'get_console_output', 'get_diagnostics', 'get_vnc_console',
|
||||
'inject_file', 'inject_network_info', 'pause_instance',
|
||||
'post_live_migration_at_destination', 'power_off_instance',
|
||||
'power_on_instance', 'reboot_instance', 'start_instance',
|
||||
'stop_instance', 'suspend_instance', 'unpause_instance'
|
||||
'power_on_instance', 'pre_live_migration', 'reboot_instance',
|
||||
'start_instance', 'stop_instance', 'suspend_instance',
|
||||
'unpause_instance'
|
||||
]
|
||||
|
||||
if 'rpcapi_class' in kwargs:
|
||||
@@ -83,7 +84,7 @@ class ComputeRpcAPITestCase(test.TestCase):
|
||||
instance = expected_msg['args']['instance']
|
||||
del expected_msg['args']['instance']
|
||||
if method in ['rollback_live_migration_at_destination',
|
||||
'pre_live_migration', 'remove_volume_connection']:
|
||||
'remove_volume_connection']:
|
||||
expected_msg['args']['instance_id'] = instance['id']
|
||||
else:
|
||||
expected_msg['args']['instance_uuid'] = instance['uuid']
|
||||
@@ -224,7 +225,7 @@ class ComputeRpcAPITestCase(test.TestCase):
|
||||
def test_pre_live_migration(self):
|
||||
self._test_compute_api('pre_live_migration', 'call',
|
||||
instance=self.fake_instance, block_migration='block_migration',
|
||||
disk='disk', host='host')
|
||||
disk='disk', host='host', version='1.23')
|
||||
|
||||
def test_reboot_instance(self):
|
||||
self._test_compute_api('reboot_instance', 'cast',
|
||||
|
||||
Reference in New Issue
Block a user