From 9dd553e12a07a6f5a8616f188f543be3d788cd01 Mon Sep 17 00:00:00 2001 From: Gary Kotton Date: Sun, 13 Jan 2013 12:10:23 +0000 Subject: [PATCH] OVS: update status according to admin_state_up Fixes bug 1099099 In addition to this the code does the following: 1. validates if the port exists on the OVS when a port update event takes place 2. when a port is created the initial state is set as 'DOWN'. this is later updated by the agent when it is detected as up Change-Id: I917d4b5aa8df7395fcaa841d77083546478739d2 --- .../openvswitch/agent/ovs_quantum_agent.py | 13 ++++++++- .../plugins/openvswitch/ovs_quantum_plugin.py | 27 ++++++++++++++++--- .../tests/unit/cisco/test_network_plugin.py | 1 + .../openvswitch/test_openvswitch_plugin.py | 6 +++++ .../tests/unit/openvswitch/test_ovs_rpcapi.py | 7 +++++ 5 files changed, 49 insertions(+), 5 deletions(-) diff --git a/quantum/plugins/openvswitch/agent/ovs_quantum_agent.py b/quantum/plugins/openvswitch/agent/ovs_quantum_agent.py index 042aac5b4..a814895b7 100755 --- a/quantum/plugins/openvswitch/agent/ovs_quantum_agent.py +++ b/quantum/plugins/openvswitch/agent/ovs_quantum_agent.py @@ -199,13 +199,24 @@ class OVSQuantumAgent(object): def port_update(self, context, **kwargs): LOG.debug(_("port_update received")) port = kwargs.get('port') + # Validate that port is on OVS + vif_port = self.int_br.get_vif_port_by_id(port['id']) + if not vif_port: + return network_type = kwargs.get('network_type') segmentation_id = kwargs.get('segmentation_id') physical_network = kwargs.get('physical_network') - vif_port = self.int_br.get_vif_port_by_id(port['id']) self.treat_vif_port(vif_port, port['id'], port['network_id'], network_type, physical_network, segmentation_id, port['admin_state_up']) + if port['admin_state_up']: + # update plugin about port status + self.plugin_rpc.update_device_up(self.context, port['id'], + self.agent_id) + else: + # update plugin about port status + self.agent.plugin_rpc.update_device_down(self.context, port['id'], + self.agent.agent_id) def tunnel_update(self, context, **kwargs): LOG.debug(_("tunnel_update received")) diff --git a/quantum/plugins/openvswitch/ovs_quantum_plugin.py b/quantum/plugins/openvswitch/ovs_quantum_plugin.py index 23b3a4cbc..9045f7bbd 100644 --- a/quantum/plugins/openvswitch/ovs_quantum_plugin.py +++ b/quantum/plugins/openvswitch/ovs_quantum_plugin.py @@ -81,8 +81,10 @@ class OVSRpcCallbacks(dhcp_rpc_base.DhcpRpcCallbackMixin, 'network_type': binding.network_type, 'segmentation_id': binding.segmentation_id, 'physical_network': binding.physical_network} - # Set the port status to UP - ovs_db_v2.set_port_status(port['id'], q_const.PORT_STATUS_ACTIVE) + new_status = (q_const.PORT_STATUS_ACTIVE if port['admin_state_up'] + else q_const.PORT_STATUS_DOWN) + if port['status'] != new_status: + ovs_db_v2.set_port_status(port['id'], new_status) else: entry = {'device': device} LOG.debug(_("%s can not be found in database"), device) @@ -99,14 +101,29 @@ class OVSRpcCallbacks(dhcp_rpc_base.DhcpRpcCallbackMixin, if port: entry = {'device': device, 'exists': True} - # Set port status to DOWN - ovs_db_v2.set_port_status(port['id'], q_const.PORT_STATUS_DOWN) + if port['status'] != q_const.PORT_STATUS_DOWN: + # Set port status to DOWN + ovs_db_v2.set_port_status(port['id'], q_const.PORT_STATUS_DOWN) else: entry = {'device': device, 'exists': False} LOG.debug(_("%s can not be found in database"), device) return entry + def update_device_up(self, rpc_context, **kwargs): + """Device is up on agent""" + agent_id = kwargs.get('agent_id') + device = kwargs.get('device') + LOG.debug(_("Device %(device)s up on %(agent_id)s"), + locals()) + port = ovs_db_v2.get_port(device) + if port: + if port['status'] != q_const.PORT_STATUS_ACTIVE: + ovs_db_v2.set_port_status(port['id'], + q_const.PORT_STATUS_ACTIVE) + else: + LOG.debug(_("%s can not be found in database"), device) + def tunnel_sync(self, rpc_context, **kwargs): """Update new tunnel. @@ -502,6 +519,8 @@ class OVSQuantumPluginV2(db_base_plugin_v2.QuantumDbPluginV2, return port def create_port(self, context, port): + # Set port status as 'DOWN'. This will be updated by agent + port['port']['status'] = q_const.PORT_STATUS_DOWN port = super(OVSQuantumPluginV2, self).create_port(context, port) return self._extend_port_dict_binding(context, port) diff --git a/quantum/tests/unit/cisco/test_network_plugin.py b/quantum/tests/unit/cisco/test_network_plugin.py index 44416f0a3..d670bea98 100644 --- a/quantum/tests/unit/cisco/test_network_plugin.py +++ b/quantum/tests/unit/cisco/test_network_plugin.py @@ -38,6 +38,7 @@ class CiscoNetworkPluginV2TestCase(test_db_plugin.QuantumDbPluginV2TestCase): with mock.patch.object(network_db_v2, 'initialize', new=new_init): super(CiscoNetworkPluginV2TestCase, self).setUp(self._plugin_name) + self.port_create_status = 'DOWN' def _get_plugin_ref(self): plugin_obj = QuantumManager.get_plugin() diff --git a/quantum/tests/unit/openvswitch/test_openvswitch_plugin.py b/quantum/tests/unit/openvswitch/test_openvswitch_plugin.py index d7244b53f..9ce64e0ed 100644 --- a/quantum/tests/unit/openvswitch/test_openvswitch_plugin.py +++ b/quantum/tests/unit/openvswitch/test_openvswitch_plugin.py @@ -25,6 +25,7 @@ class OpenvswitchPluginV2TestCase(test_plugin.QuantumDbPluginV2TestCase): def setUp(self): super(OpenvswitchPluginV2TestCase, self).setUp(self._plugin_name) + self.port_create_status = 'DOWN' class TestOpenvswitchBasicGet(test_plugin.TestBasicGet, @@ -44,6 +45,11 @@ class TestOpenvswitchPortsV2(test_plugin.TestPortsV2, VIF_TYPE = portbindings.VIF_TYPE_OVS HAS_PORT_FILTER = False + def test_update_port_status_build(self): + with self.port() as port: + self.assertEqual(port['port']['status'], 'DOWN') + self.assertEqual(self.port_create_status, 'DOWN') + class TestOpenvswitchNetworksV2(test_plugin.TestNetworksV2, OpenvswitchPluginV2TestCase): diff --git a/quantum/tests/unit/openvswitch/test_ovs_rpcapi.py b/quantum/tests/unit/openvswitch/test_ovs_rpcapi.py index cc0f48a48..fdb181ba5 100644 --- a/quantum/tests/unit/openvswitch/test_ovs_rpcapi.py +++ b/quantum/tests/unit/openvswitch/test_ovs_rpcapi.py @@ -108,3 +108,10 @@ class rpcApiTestCase(unittest2.TestCase): self._test_ovs_api(rpcapi, topics.PLUGIN, 'tunnel_sync', rpc_method='call', tunnel_ip='fake_tunnel_ip') + + def test_update_device_up(self): + rpcapi = agent_rpc.PluginApi(topics.PLUGIN) + self._test_ovs_api(rpcapi, topics.PLUGIN, + 'update_device_up', rpc_method='call', + device='fake_device', + agent_id='fake_agent_id') -- 2.45.2