diff --git a/neutron/services/trunk/drivers/ovn/trunk_driver.py b/neutron/services/trunk/drivers/ovn/trunk_driver.py index bd6323d86e1..3059356da54 100644 --- a/neutron/services/trunk/drivers/ovn/trunk_driver.py +++ b/neutron/services/trunk/drivers/ovn/trunk_driver.py @@ -45,10 +45,13 @@ class OVNTrunkHandler(object): def _set_sub_ports(self, parent_port, subports): txn = self.plugin_driver._nb_ovn.transaction context = n_context.get_admin_context() + db_parent_port = port_obj.Port.get_object(context, id=parent_port) + parent_port_status = db_parent_port.status for port in subports: with db_api.CONTEXT_WRITER.using(context), ( txn(check_error=True)) as ovn_txn: - self._set_binding_profile(context, port, parent_port, ovn_txn) + self._set_binding_profile(context, port, parent_port, + parent_port_status, ovn_txn) def _unset_sub_ports(self, subports): txn = self.plugin_driver._nb_ovn.transaction @@ -58,7 +61,8 @@ class OVNTrunkHandler(object): txn(check_error=True)) as ovn_txn: self._unset_binding_profile(context, port, ovn_txn) - def _set_binding_profile(self, context, subport, parent_port, ovn_txn): + def _set_binding_profile(self, context, subport, parent_port, + parent_port_status, ovn_txn): LOG.debug("Setting parent %s for subport %s", parent_port, subport.port_id) db_port = port_obj.Port.get_object(context, id=subport.port_id) @@ -71,6 +75,10 @@ class OVNTrunkHandler(object): # NOTE(flaviof): We expect binding's host to be set. Otherwise, # sub-port will not transition from DOWN to ACTIVE. db_port.device_owner = trunk_consts.TRUNK_SUBPORT_OWNER + # NOTE(ksambor): When sub-port was created and event was process + # without binding profile this port will end forever in DOWN + # status so we need to switch it here to the parent port status + db_port.status = parent_port_status for binding in db_port.bindings: binding.profile['parent_name'] = parent_port binding.profile['tag'] = subport.segmentation_id diff --git a/neutron/tests/unit/services/trunk/drivers/ovn/test_trunk_driver.py b/neutron/tests/unit/services/trunk/drivers/ovn/test_trunk_driver.py index 30afad8d048..ebe7db239e6 100644 --- a/neutron/tests/unit/services/trunk/drivers/ovn/test_trunk_driver.py +++ b/neutron/tests/unit/services/trunk/drivers/ovn/test_trunk_driver.py @@ -41,6 +41,8 @@ class TestTrunkHandler(base.BaseTestCase): self.handler = trunk_driver.OVNTrunkHandler(self.plugin_driver) self.trunk_1 = mock.Mock() self.trunk_1.port_id = "trunk-1" + self.trunk_1_obj = self._get_fake_port_obj( + port_id='trunk-1') self.trunk_2 = mock.Mock() self.trunk_2.port_id = "trunk-2" @@ -77,7 +79,8 @@ class TestTrunkHandler(base.BaseTestCase): "neutron.objects.ports.Port.get_object").start() self.mock_get_port.side_effect = lambda ctxt, id: ( self.sub_port_1_obj if id == 'sub_port_1' else ( - self.sub_port_2_obj if id == 'sub_port_2' else None)) + self.sub_port_2_obj if id == 'sub_port_2' else + self.trunk_1_obj if id == 'trunk-1' else None)) self.mock_port_update = mock.patch( "neutron.objects.ports.Port.update").start() self.mock_update_pb = mock.patch( @@ -91,6 +94,7 @@ class TestTrunkHandler(base.BaseTestCase): port = Port() port.id = port_id port.bindings = [PortBinding(profile={}, host='foo.com')] + port.status = 'ACTIVE' return port def _assert_calls(self, mock, expected_calls):