diff --git a/nova/compute/manager.py b/nova/compute/manager.py index f43aa0096d..82051ecb4e 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -1486,10 +1486,8 @@ class ComputeManager(manager.SchedulerDependentManager): self.network_api.setup_networks_on_host(context, instance, teardown=True) - if migration_ref['dest_compute'] != \ - migration_ref['source_compute']: - self.network_api.migrate_instance_start(context, instance, - migration_ref['dest_compute']) + self.network_api.migrate_instance_start(context, instance, + migration_ref) network_info = self._get_instance_nw_info(context, instance) block_device_info = self._get_instance_volume_block_device_info( @@ -1548,11 +1546,6 @@ class ComputeManager(manager.SchedulerDependentManager): self._legacy_nw_info(network_info), block_device_info) - if migration_ref['dest_compute'] != \ - migration_ref['source_compute']: - self.network_api.migrate_instance_finish(context, instance, - migration_ref['source_compute']) - # Just roll back the record. There's no need to resize down since # the 'old' VM already has the preferred attributes self._instance_update(context, @@ -1563,11 +1556,16 @@ class ComputeManager(manager.SchedulerDependentManager): ephemeral_gb=instance_type['ephemeral_gb'], instance_type_id=instance_type['id'], launched_at=timeutils.utcnow(), - vm_state=vm_states.ACTIVE, - task_state=None, expected_task_state=task_states. RESIZE_REVERTING) + self.network_api.migrate_instance_finish(context, instance, + migration_ref) + + self._instance_update(context, instance['uuid'], + vm_state=vm_states.ACTIVE, + task_state=None) + self.db.migration_update(elevated, migration_id, {'status': 'reverted'}) @@ -1673,9 +1671,8 @@ class ComputeManager(manager.SchedulerDependentManager): self._terminate_volume_connections(context, instance) - if migration['dest_compute'] != migration['source_compute']: - self.network_api.migrate_instance_start(context, instance, - self.host) + self.network_api.migrate_instance_start(context, instance, + migration) migration = self.db.migration_update(elevated, migration['id'], @@ -1725,9 +1722,8 @@ class ComputeManager(manager.SchedulerDependentManager): self.network_api.setup_networks_on_host(context, instance, migration['dest_compute']) - if migration['dest_compute'] != migration['source_compute']: - self.network_api.migrate_instance_finish(context, instance, - migration['dest_compute']) + self.network_api.migrate_instance_finish(context, instance, + migration) network_info = self._get_instance_nw_info(context, instance) diff --git a/nova/network/api.py b/nova/network/api.py index 5f2c2ff8b3..bb05a0c2a4 100644 --- a/nova/network/api.py +++ b/nova/network/api.py @@ -21,6 +21,7 @@ import functools import inspect from nova.db import base +from nova import exception from nova import flags from nova.network import model as network_model from nova.network import rpcapi as network_rpcapi @@ -324,8 +325,11 @@ class API(base.Base): self.network_rpcapi.setup_networks_on_host(context, **args) def _is_multi_host(self, context, instance): - fixed_ips = self.db.fixed_ip_get_by_instance(context, instance['uuid']) - + try: + fixed_ips = self.db.fixed_ip_get_by_instance(context, + instance['uuid']) + except exception.FixedIpNotFoundForInstance: + return False network = self.db.network_get(context, fixed_ips[0]['network_id'], project_only=True) return network['multi_host'] @@ -335,22 +339,36 @@ class API(base.Base): instance['uuid']) return [floating_ip['address'] for floating_ip in floating_ips] - def migrate_instance_start(self, context, instance, host): + def migrate_instance_start(self, context, instance, migration): """Start to migrate the network of an instance""" - if self._is_multi_host(context, instance): - addresses = self._get_floating_ip_addresses(context, instance) - if addresses: - self.network_rpcapi.migrate_instance_start(context, - instance['uuid'], - addresses, - host) + args = dict( + instance_uuid=instance['uuid'], + rxtx_factor=instance['instance_type']['rxtx_factor'], + project_id=instance['project_id'], + source_compute=migration['source_compute'], + dest_compute=migration['dest_compute'], + floating_addresses=None, + ) - def migrate_instance_finish(self, context, instance, dest): - """Finish migrating the network of an instance""" if self._is_multi_host(context, instance): - addresses = self._get_floating_ip_addresses(context, instance) - if addresses: - self.network_rpcapi.migrate_instance_finish(context, - instance['uuid'], - addresses, - dest) + args['floating_addresses'] = \ + self._get_floating_ip_addresses(context, instance) + + self.network_rpcapi.migrate_instance_start(context, **args) + + def migrate_instance_finish(self, context, instance, migration): + """Finish migrating the network of an instance""" + args = dict( + instance_uuid=instance['uuid'], + rxtx_factor=instance['instance_type']['rxtx_factor'], + project_id=instance['project_id'], + source_compute=migration['source_compute'], + dest_compute=migration['dest_compute'], + floating_addresses=None, + ) + + if self._is_multi_host(context, instance): + args['floating_addresses'] = \ + self._get_floating_ip_addresses(context, instance) + + self.network_rpcapi.migrate_instance_finish(context, **args) diff --git a/nova/network/manager.py b/nova/network/manager.py index 39eed6e7e0..a944ebd40e 100644 --- a/nova/network/manager.py +++ b/nova/network/manager.py @@ -663,8 +663,13 @@ class FloatingIP(object): return False if floating_ip.get('fixed_ip_id') else True @wrap_check_policy - def migrate_instance_start(self, context, instance_uuid, - floating_addresses): + def migrate_instance_start(self, context, instance_uuid, rxtx_factor, + project_id, source, dest, floating_addresses): + # We only care if floating_addresses are provided and we're + # switching hosts + if not floating_addresses or source == dest: + return + LOG.info(_("Starting migration network for instance" " %(instance_uuid)s"), locals()) for address in floating_addresses: @@ -691,8 +696,13 @@ class FloatingIP(object): {'host': None}) @wrap_check_policy - def migrate_instance_finish(self, context, instance_uuid, - floating_addresses, host): + def migrate_instance_finish(self, context, instance_uuid, rxtx_factor, + project_id, source, dest, floating_addresses): + # We only care if floating_addresses are provided and we're + # switching hosts + if not floating_addresses or source == dest: + return + LOG.info(_("Finishing migration network for instance" " %(instance_uuid)s"), locals()) @@ -708,7 +718,7 @@ class FloatingIP(object): self.db.floating_ip_update(context, floating_ip['address'], - {'host': host}) + {'host': dest}) interface = FLAGS.public_interface or floating_ip['interface'] fixed_ip = self.db.fixed_ip_get(context, @@ -1944,6 +1954,14 @@ class FlatManager(NetworkManager): """Returns the floating IPs associated with a fixed_address""" return [] + def migrate_instance_start(self, context, instance_uuid, rxtx_factor, + project_id, source, dest, floating_addresses): + pass + + def migrate_instance_finish(self, context, instance_uuid, rxtx_factor, + project_id, source, dest, floating_addresses): + pass + class FlatDHCPManager(RPCAllocateFixedIP, FloatingIP, NetworkManager): """Flat networking with dhcp. diff --git a/nova/network/quantumv2/api.py b/nova/network/quantumv2/api.py index 594d7b2f2b..241bb1a2d9 100644 --- a/nova/network/quantumv2/api.py +++ b/nova/network/quantumv2/api.py @@ -508,13 +508,15 @@ class API(base.Base): fip = self._get_floating_ip_by_address(client, address) client.update_floatingip(fip['id'], {'floatingip': {'port_id': None}}) - def migrate_instance_start(self, context, instance, host): + def migrate_instance_start(self, context, instance_uuid, rxtx_factor, + project_id, source, dest, floating_addresses): """Start to migrate the network of an instance""" # NOTE(wenjianhn): just pass to make migrate instance doesn't # raise for now. pass - def migrate_instance_finish(self, context, instance, dest): + def migrate_instance_finish(self, context, instance_uuid, rxtx_factor, + project_id, source, dest, floating_addresses): """Finish migrating the network of an instance""" # NOTE(wenjianhn): just pass to make migrate instance doesn't # raise for now. diff --git a/nova/network/rpcapi.py b/nova/network/rpcapi.py index ffeddf3160..6f31e140b9 100644 --- a/nova/network/rpcapi.py +++ b/nova/network/rpcapi.py @@ -34,6 +34,7 @@ class NetworkAPI(rpc_proxy.RpcProxy): 1.0 - Initial version. 1.1 - Adds migrate_instance_[start|finish] + 1.2 - Make migrate_instance_[start|finish] a little more flexible ''' # @@ -264,19 +265,32 @@ class NetworkAPI(rpc_proxy.RpcProxy): self.cast(ctxt, self.make_msg('release_fixed_ip', address=address), topic=rpc.queue_get_for(ctxt, self.topic, host)) - def migrate_instance_start(self, ctxt, instance_uuid, - floating_addresses, host): - return self.call(ctxt, self.make_msg('migrate_instance_start', - instance_uuid=instance_uuid, - floating_addresses=floating_addresses), - topic=rpc.queue_get_for(ctxt, self.topic, host), - version='1.1') + def migrate_instance_start(self, ctxt, instance_uuid, rxtx_factor, + project_id, source_compute, dest_compute, + floating_addresses): + return self.call(ctxt, self.make_msg( + 'migrate_instance_start', + instance_uuid=instance_uuid, + rxtx_factor=rxtx_factor, + project_id=project_id, + source=source_compute, + dest=dest_compute, + floating_addresses=floating_addresses), + topic=rpc.queue_get_for(ctxt, self.topic, + dest_compute), + version='1.2') - def migrate_instance_finish(self, ctxt, instance_uuid, - floating_addresses, dest): - return self.call(ctxt, self.make_msg('migrate_instance_finish', - instance_uuid=instance_uuid, - floating_addresses=floating_addresses, - host=dest), - topic=rpc.queue_get_for(ctxt, self.topic, dest), - version='1.1') + def migrate_instance_finish(self, ctxt, instance_uuid, rxtx_factor, + project_id, source_compute, dest_compute, + floating_addresses): + return self.call(ctxt, self.make_msg( + 'migrate_instance_finish', + instance_uuid=instance_uuid, + rxtx_factor=rxtx_factor, + project_id=project_id, + source=source_compute, + dest=dest_compute, + floating_addresses=floating_addresses), + topic=rpc.queue_get_for(ctxt, self.topic, + dest_compute), + version='1.2') diff --git a/nova/tests/network/test_manager.py b/nova/tests/network/test_manager.py index 952f1ba334..77fccd9046 100644 --- a/nova/tests/network/test_manager.py +++ b/nova/tests/network/test_manager.py @@ -1667,7 +1667,9 @@ class FloatingIPTestCase(test.TestCase): self.mox.ReplayAll() floating_ip_addresses = ['172.24.4.23', '172.24.4.24', '172.24.4.25'] self.network.migrate_instance_start(self.context, FAKEUUID, - floating_ip_addresses) + 3, self.project_id, + 'fake_source', 'fake_dest', + floating_ip_addresses) self.assertEqual(called['count'], 2) @@ -1703,8 +1705,9 @@ class FloatingIPTestCase(test.TestCase): self.mox.ReplayAll() floating_ip_addresses = ['172.24.4.23', '172.24.4.24', '172.24.4.25'] self.network.migrate_instance_finish(self.context, FAKEUUID, - floating_ip_addresses, - 'fake_dest') + 3, self.project_id, + 'fake_source', 'fake_dest', + floating_ip_addresses) self.assertEqual(called['count'], 2)