From 45fd6be08a04bc49dbc5c7fd67cdc7defb889284 Mon Sep 17 00:00:00 2001 From: Aaron Rosen Date: Mon, 15 Jul 2013 17:32:43 -0700 Subject: [PATCH] Fix nic order not correct after reboot Previously if an instance was rebooted or migrated the original nic order would not be maintained. This patch retrieves the correct nic order from info_cache so that the order is mantained. Fixes bug 1187092 Change-Id: I3f5488cc14c692fde7d5bd3376389e2f2f5550ff (cherry picked from commit bcd12a776e8cde8c4b64e7c1a21a7387ece55b31) --- nova/network/quantumv2/api.py | 9 +++++++- nova/tests/network/test_quantumv2.py | 32 +++++++++++++++++++++++++++- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/nova/network/quantumv2/api.py b/nova/network/quantumv2/api.py index cdc892eba60..506c3b32bb5 100644 --- a/nova/network/quantumv2/api.py +++ b/nova/network/quantumv2/api.py @@ -31,6 +31,7 @@ from nova.network import quantumv2 from nova.network.security_group import openstack_driver from nova.openstack.common import excutils +from nova.openstack.common import jsonutils from nova.openstack.common import log as logging from nova.openstack.common import uuidutils @@ -792,12 +793,18 @@ def _build_network_info_model(self, context, instance, networks=None): data = client.list_ports(**search_opts) ports = data.get('ports', []) if networks is None: + # retrieve networks from info_cache to get correct nic order + network_cache = self.conductor_api.instance_get_by_uuid( + context, instance['uuid'])['info_cache']['network_info'] + network_cache = jsonutils.loads(network_cache) + net_ids = [iface['network']['id'] for iface in network_cache] networks = self._get_available_networks(context, instance['project_id']) # ensure ports are in preferred network order, and filter out # those not attached to one of the provided list of networks - net_ids = [n['id'] for n in networks] + else: + net_ids = [n['id'] for n in networks] ports = [port for port in ports if port['network_id'] in net_ids] _ensure_requested_network_ordering(lambda x: x['network_id'], ports, net_ids) diff --git a/nova/tests/network/test_quantumv2.py b/nova/tests/network/test_quantumv2.py index c0773e8ae67..57ccfd80944 100644 --- a/nova/tests/network/test_quantumv2.py +++ b/nova/tests/network/test_quantumv2.py @@ -23,11 +23,13 @@ from quantumclient.v2_0 import client from nova.compute import instance_types +from nova.conductor import api as conductor_api from nova import context from nova import exception from nova.network import model from nova.network import quantumv2 from nova.network.quantumv2 import api as quantumapi +from nova.openstack.common import jsonutils from nova import test from nova import utils @@ -269,6 +271,15 @@ def _get_instance_nw_info(self, number): self.instance['uuid'], mox.IgnoreArg()) port_data = number == 1 and self.port_data1 or self.port_data2 + self.mox.StubOutWithMock(conductor_api.API, + 'instance_get_by_uuid') + net_info_cache = [] + for port in port_data: + net_info_cache.append({"network": {"id": port['network_id']}}) + info_cache = {'info_cache': {'network_info': + jsonutils.dumps(net_info_cache)}} + api.conductor_api.instance_get_by_uuid( + mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(info_cache) self.moxed_client.list_ports( tenant_id=self.instance['project_id'], device_id=self.instance['uuid']).AndReturn( @@ -368,6 +379,16 @@ def test_get_instance_nw_info_without_subnet(self): quantumv2.get_client(mox.IgnoreArg(), admin=True).MultipleTimes().AndReturn( self.moxed_client) + self.mox.StubOutWithMock(conductor_api.API, + 'instance_get_by_uuid') + net_info_cache = [] + for port in self.port_data3: + net_info_cache.append({"network": {"id": port['network_id']}}) + info_cache = {'info_cache': {'network_info': + jsonutils.dumps(net_info_cache)}} + + api.conductor_api.instance_get_by_uuid( + mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(info_cache) self.mox.ReplayAll() nw_inf = api.get_instance_nw_info(self.context, @@ -730,7 +751,17 @@ def test_deallocate_for_instance_2(self): def _test_deallocate_port_for_instance(self, number): port_data = number == 1 and self.port_data1 or self.port_data2 self.moxed_client.delete_port(port_data[0]['id']) + self.mox.StubOutWithMock(conductor_api.API, + 'instance_get_by_uuid') + net_info_cache = [] + for port in port_data: + net_info_cache.append({"network": {"id": port['network_id']}}) + info_cache = {'info_cache': {'network_info': + jsonutils.dumps(net_info_cache)}} + api = quantumapi.API() + api.conductor_api.instance_get_by_uuid( + mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(info_cache) nets = [port_data[0]['network_id']] quantumv2.get_client(mox.IgnoreArg(), admin=True).AndReturn( self.moxed_client) @@ -758,7 +789,6 @@ def _test_deallocate_port_for_instance(self, number): self.mox.ReplayAll() - api = quantumapi.API() nwinfo = api.deallocate_port_for_instance(self.context, self.instance, port_data[0]['id']) self.assertEqual(len(nwinfo), len(port_data[1:]))