)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":5756,"name":"Terry Wilson","email":"twilson@redhat.com","username":"otherwiseguy"},"change_message_id":"0167a91978122a01e95e8db608075b1864fb634b","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"2120bfa8_5a3f78da","updated":"2026-10-20 14:42:10.000000000","message":"I don\u0027t see anything I would hold the patch up over. It\u0027s a good and necessary fix. A get_lswitch() change that followed the try direct uuid lookup and on KeyError try the name lookup on a uuid-like value could be an improvement, but it doesn\u0027t have to be in this patch.","commit_id":"745d9da5895c5016f67ea37c71c9fb8c44af0e1b"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"44dc2e2108078c559971b796dbe07500f5715a16","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"4557c192_fb79168e","updated":"2026-10-19 12:59:55.000000000","message":"Legit bug and patch.\n\nWe would need to backport it up to stable/2025.2","commit_id":"745d9da5895c5016f67ea37c71c9fb8c44af0e1b"},{"author":{"_account_id":28619,"name":"Dmitriy Rabotyagov","email":"noonedeadpunk@gmail.com","username":"noonedeadpunk"},"change_message_id":"9b9659e128e0f10dfeb2a079095893de647f175f","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"fc14bbb7_9529f579","updated":"2026-10-17 10:57:23.000000000","message":"that worked for us nicely as well.\n\nthis needs to be merged and backported to 2025.2 - it creates a terrible regression for ones who upgrade","commit_id":"745d9da5895c5016f67ea37c71c9fb8c44af0e1b"},{"author":{"_account_id":28619,"name":"Dmitriy Rabotyagov","email":"noonedeadpunk@gmail.com","username":"noonedeadpunk"},"change_message_id":"bc41daad5292907166bbfc1d79840811bf789d64","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"fecbea58_b204f31b","in_reply_to":"2120bfa8_5a3f78da","updated":"2026-10-20 15:14:38.000000000","message":"It would be indeed nice if we can get the fix in, and then propose improvements as follow-ups...","commit_id":"745d9da5895c5016f67ea37c71c9fb8c44af0e1b"}],"neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/commands.py":[{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"44dc2e2108078c559971b796dbe07500f5715a16","unresolved":true,"context_lines":[{"line_number":171,"context_line":"    def run_idl(self, txn):"},{"line_number":172,"context_line":"        table \u003d self.api.tables[self.table_name]"},{"line_number":173,"context_line":"        try:"},{"line_number":174,"context_line":"            ls \u003d table.rows[self.network_uuid]"},{"line_number":175,"context_line":"        except KeyError:"},{"line_number":176,"context_line":"            # NOTE: a Logical_Switch created before persist_uuid was used has"},{"line_number":177,"context_line":"            # a random register UUID and is only found by its name. The"}],"source_content_type":"text/x-python","patch_set":2,"id":"6526ec23_7e29fd7d","line":174,"range":{"start_line":174,"start_character":11,"end_line":174,"end_character":46},"updated":"2026-10-19 12:59:55.000000000","message":"This is not needed if we use the second `idlutils.row_by_value`.\n\nI would refactor a bit the NOTE, saying that environments without OVS 3.1.0 (https://github.com/openvswitch/ovs/commit/55b9507e6824b935ffa0205fc7c7bebfe4e54279), the Logical_Swith UUID won\u0027t match the Neutron UUID. That would apply for previously created LSs too.","commit_id":"745d9da5895c5016f67ea37c71c9fb8c44af0e1b"},{"author":{"_account_id":5756,"name":"Terry Wilson","email":"twilson@redhat.com","username":"otherwiseguy"},"change_message_id":"0167a91978122a01e95e8db608075b1864fb634b","unresolved":true,"context_lines":[{"line_number":171,"context_line":"    def run_idl(self, txn):"},{"line_number":172,"context_line":"        table \u003d self.api.tables[self.table_name]"},{"line_number":173,"context_line":"        try:"},{"line_number":174,"context_line":"            ls \u003d table.rows[self.network_uuid]"},{"line_number":175,"context_line":"        except KeyError:"},{"line_number":176,"context_line":"            # NOTE: a Logical_Switch created before persist_uuid was used has"},{"line_number":177,"context_line":"            # a random register UUID and is only found by its name. The"}],"source_content_type":"text/x-python","patch_set":2,"id":"b0566ef0_9a87076e","line":174,"range":{"start_line":174,"start_character":11,"end_line":174,"end_character":46},"in_reply_to":"6526ec23_7e29fd7d","updated":"2026-10-20 14:42:10.000000000","message":"I agree that correctness-wise, we could always look up by name. But even with an indexed field, I like the O(1) dict lookup over the O(log n) indexed search.","commit_id":"745d9da5895c5016f67ea37c71c9fb8c44af0e1b"},{"author":{"_account_id":39375,"name":"To Minh Hien","display_name":"Hien","email":"tominhhien97@gmail.com","username":"hiento09"},"change_message_id":"643ffd5d5cb5ae5ca870281d4f3a77be3a3e0a91","unresolved":false,"context_lines":[{"line_number":173,"context_line":"        try:"},{"line_number":174,"context_line":"            ls \u003d table.rows[self.network_uuid]"},{"line_number":175,"context_line":"        except KeyError:"},{"line_number":176,"context_line":"            # NOTE: without OVS commit 55b9507 (3.1.0) the Logical_Switch"},{"line_number":177,"context_line":"            # UUID is not persisted and does not match the network ID; such"},{"line_number":178,"context_line":"            # register, as any register created before that, is only found"},{"line_number":179,"context_line":"            # by its name. The Logical_Switch table has no index in the"}],"source_content_type":"text/x-python","patch_set":3,"id":"5b459f0f_5b825431","line":176,"in_reply_to":"b0566ef0_9a87076e","updated":"2026-10-21 01:38:30.000000000","message":"Kept the direct UUID lookup as the fast path per Terry\u0027s comment, and reworded the NOTE to mention OVS commit 55b9507 (3.1.0) and that it applies to previously created switches as well.","commit_id":"dcadf13eba5ee5ad7585c0abd612fccee7710267"}],"neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/impl_idl_ovn.py":[{"author":{"_account_id":5756,"name":"Terry Wilson","email":"twilson@redhat.com","username":"otherwiseguy"},"change_message_id":"6b42a9d64aa54c154d5f38924f573856b0904a69","unresolved":false,"context_lines":[{"line_number":849,"context_line":""},{"line_number":850,"context_line":"    def get_lswitch(self, lswitch_name):"},{"line_number":851,"context_line":"        try:"},{"line_number":852,"context_line":"            return self.lookup(\u0027Logical_Switch\u0027, lswitch_name)"},{"line_number":853,"context_line":"        except idlutils.RowNotFound:"},{"line_number":854,"context_line":"            if not uuidutils.is_uuid_like(lswitch_name):"},{"line_number":855,"context_line":"                return None"}],"source_content_type":"text/x-python","patch_set":3,"id":"aa37bbd1_4a522b96","line":852,"updated":"2026-10-21 19:56:16.000000000","message":"Just a note for reviewers, if `lswitch_name` is an actual `UUID`, or something that can be passed to `UUID` (e.g. a uuid string), `lookup()` will try to do a direct dictionary access on `table.rows`.","commit_id":"dcadf13eba5ee5ad7585c0abd612fccee7710267"}],"neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/maintenance.py":[{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"44dc2e2108078c559971b796dbe07500f5715a16","unresolved":true,"context_lines":[{"line_number":485,"context_line":"                              {\u0027res_uuid\u0027: row.resource_uuid,"},{"line_number":486,"context_line":"                               \u0027res_type\u0027: row.resource_type})"},{"line_number":487,"context_line":""},{"line_number":488,"context_line":"    def _get_lswitch(self, net_id):"},{"line_number":489,"context_line":"        # NOTE: ``get_lswitch`` requires the Logical_Switch name, not the"},{"line_number":490,"context_line":"        # Neutron network ID. A Logical_Switch created before persist_uuid"},{"line_number":491,"context_line":"        # was used has a random register UUID that does not match the"},{"line_number":492,"context_line":"        # network ID; such register is only found by its name."},{"line_number":493,"context_line":"        return self._nb_idl.get_lswitch(utils.ovn_name(net_id))"},{"line_number":494,"context_line":""},{"line_number":495,"context_line":"    def _create_lrouter_port(self, context, port):"},{"line_number":496,"context_line":"        router_id \u003d port[\u0027device_id\u0027]"}],"source_content_type":"text/x-python","patch_set":2,"id":"543b2e23_9bf92749","line":493,"range":{"start_line":488,"start_character":9,"end_line":493,"end_character":63},"updated":"2026-10-19 12:59:55.000000000","message":"Instead of this, you can partially revert https://review.opendev.org/c/openstack/neutron/+/963666/2/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/impl_idl_ovn.py, explaining that this method can be called from the maintenance class, using only the resource UUID, not the name.","commit_id":"745d9da5895c5016f67ea37c71c9fb8c44af0e1b"},{"author":{"_account_id":5756,"name":"Terry Wilson","email":"twilson@redhat.com","username":"otherwiseguy"},"change_message_id":"0167a91978122a01e95e8db608075b1864fb634b","unresolved":true,"context_lines":[{"line_number":485,"context_line":"                              {\u0027res_uuid\u0027: row.resource_uuid,"},{"line_number":486,"context_line":"                               \u0027res_type\u0027: row.resource_type})"},{"line_number":487,"context_line":""},{"line_number":488,"context_line":"    def _get_lswitch(self, net_id):"},{"line_number":489,"context_line":"        # NOTE: ``get_lswitch`` requires the Logical_Switch name, not the"},{"line_number":490,"context_line":"        # Neutron network ID. A Logical_Switch created before persist_uuid"},{"line_number":491,"context_line":"        # was used has a random register UUID that does not match the"},{"line_number":492,"context_line":"        # network ID; such register is only found by its name."},{"line_number":493,"context_line":"        return self._nb_idl.get_lswitch(utils.ovn_name(net_id))"},{"line_number":494,"context_line":""},{"line_number":495,"context_line":"    def _create_lrouter_port(self, context, port):"},{"line_number":496,"context_line":"        router_id \u003d port[\u0027device_id\u0027]"}],"source_content_type":"text/x-python","patch_set":2,"id":"fb446967_678622c3","line":493,"range":{"start_line":488,"start_character":9,"end_line":493,"end_character":63},"in_reply_to":"543b2e23_9bf92749","updated":"2026-10-20 14:42:10.000000000","message":"If we wanted to preserve the O(1) lookup when we can do it, get_lswitch() could try the O(1) lookup and on failure retry using the ovn_name() version.","commit_id":"745d9da5895c5016f67ea37c71c9fb8c44af0e1b"},{"author":{"_account_id":39375,"name":"To Minh Hien","display_name":"Hien","email":"tominhhien97@gmail.com","username":"hiento09"},"change_message_id":"d07076880e73cb7fb1153f7fffcdab435b0a739d","unresolved":false,"context_lines":[{"line_number":490,"context_line":"        # Neutron network ID. A Logical_Switch created before persist_uuid"},{"line_number":491,"context_line":"        # was used has a random register UUID that does not match the"},{"line_number":492,"context_line":"        # network ID; such register is only found by its name."},{"line_number":493,"context_line":"        return self._nb_idl.get_lswitch(utils.ovn_name(net_id))"},{"line_number":494,"context_line":""},{"line_number":495,"context_line":"    def _create_lrouter_port(self, context, port):"},{"line_number":496,"context_line":"        router_id \u003d port[\u0027device_id\u0027]"}],"source_content_type":"text/x-python","patch_set":2,"id":"a018f06d_1197ef80","line":493,"in_reply_to":"fb446967_678622c3","updated":"2026-10-21 01:38:33.000000000","message":"Done. Dropped the wrapper; get_lswitch() now retries with ovn_name() on RowNotFound when given a UUID-like value, so the direct lookup stays O(1) when the UUID was persisted.","commit_id":"745d9da5895c5016f67ea37c71c9fb8c44af0e1b"}],"neutron/tests/unit/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_impl_idl_ovn.py":[{"author":{"_account_id":5756,"name":"Terry Wilson","email":"twilson@redhat.com","username":"otherwiseguy"},"change_message_id":"6b42a9d64aa54c154d5f38924f573856b0904a69","unresolved":true,"context_lines":[{"line_number":957,"context_line":"            utils.ovn_name(\u0027lr-id-f\u0027))"},{"line_number":958,"context_line":"        self.assertEqual([gw1_row], gw_ports)"},{"line_number":959,"context_line":""},{"line_number":960,"context_line":"    def test_get_lswitch(self):"},{"line_number":961,"context_line":"        ls_row \u003d mock.Mock()"},{"line_number":962,"context_line":"        with mock.patch.object(self.nb_ovn_idl, \u0027lookup\u0027,"},{"line_number":963,"context_line":"                               return_value\u003dls_row) as lookup:"},{"line_number":964,"context_line":"            self.assertEqual(ls_row,"},{"line_number":965,"context_line":"                             self.nb_ovn_idl.get_lswitch(\u0027neutron-ls-id\u0027))"},{"line_number":966,"context_line":"        lookup.assert_called_once_with(\u0027Logical_Switch\u0027, \u0027neutron-ls-id\u0027)"},{"line_number":967,"context_line":""},{"line_number":968,"context_line":"    def test_get_lswitch_not_found(self):"},{"line_number":969,"context_line":"        with mock.patch.object(self.nb_ovn_idl, \u0027lookup\u0027,"},{"line_number":970,"context_line":"                               side_effect\u003didlutils.RowNotFound) as lookup:"},{"line_number":971,"context_line":"            self.assertIsNone(self.nb_ovn_idl.get_lswitch(\u0027neutron-ls-id\u0027))"},{"line_number":972,"context_line":"        lookup.assert_called_once_with(\u0027Logical_Switch\u0027, \u0027neutron-ls-id\u0027)"},{"line_number":973,"context_line":""},{"line_number":974,"context_line":"    def test_get_lswitch_legacy_uuid(self):"},{"line_number":975,"context_line":"        # A Logical_Switch whose UUID was not persisted is only found by"},{"line_number":976,"context_line":"        # name when the caller passes the Neutron network ID."},{"line_number":977,"context_line":"        net_id \u003d uuidutils.generate_uuid()"},{"line_number":978,"context_line":"        ls_row \u003d mock.Mock()"},{"line_number":979,"context_line":"        with mock.patch.object(self.nb_ovn_idl, \u0027lookup\u0027,"},{"line_number":980,"context_line":"                               side_effect\u003d[idlutils.RowNotFound,"},{"line_number":981,"context_line":"                                            ls_row]) as lookup:"},{"line_number":982,"context_line":"            self.assertEqual(ls_row, self.nb_ovn_idl.get_lswitch(net_id))"},{"line_number":983,"context_line":"        lookup.assert_has_calls(["},{"line_number":984,"context_line":"            mock.call(\u0027Logical_Switch\u0027, net_id),"},{"line_number":985,"context_line":"            mock.call(\u0027Logical_Switch\u0027, utils.ovn_name(net_id))])"},{"line_number":986,"context_line":""},{"line_number":987,"context_line":"    def test_get_lswitch_legacy_uuid_not_found(self):"},{"line_number":988,"context_line":"        net_id \u003d uuidutils.generate_uuid()"},{"line_number":989,"context_line":"        with mock.patch.object(self.nb_ovn_idl, \u0027lookup\u0027,"},{"line_number":990,"context_line":"                               side_effect\u003didlutils.RowNotFound) as lookup:"},{"line_number":991,"context_line":"            self.assertIsNone(self.nb_ovn_idl.get_lswitch(net_id))"},{"line_number":992,"context_line":"        self.assertEqual(2, lookup.call_count)"},{"line_number":993,"context_line":""},{"line_number":994,"context_line":"    def test_get_lrouter_by_lrouter_port(self):"},{"line_number":995,"context_line":"        self.assertIsNone("}],"source_content_type":"text/x-python","patch_set":3,"id":"cb321166_29a6025f","line":992,"range":{"start_line":960,"start_character":0,"end_line":992,"end_character":46},"updated":"2026-10-21 19:56:16.000000000","message":"In my opinion, these should be dropped. They provide little value and are tied very directly to implementation details we don\u0027t ultimately care about. Functional tests are almost always a better fit for ovsdb-related operations that don\u0027t require simulating server error conditions that are impossible to reproduce. (I would happily delete this whole file 😃)","commit_id":"dcadf13eba5ee5ad7585c0abd612fccee7710267"},{"author":{"_account_id":39375,"name":"To Minh Hien","display_name":"Hien","email":"tominhhien97@gmail.com","username":"hiento09"},"change_message_id":"03556ca05cf507895469fde71c527be18d9b90b0","unresolved":false,"context_lines":[{"line_number":989,"context_line":"        with mock.patch.object(self.nb_ovn_idl, \u0027lookup\u0027,"},{"line_number":990,"context_line":"                               side_effect\u003didlutils.RowNotFound) as lookup:"},{"line_number":991,"context_line":"            self.assertIsNone(self.nb_ovn_idl.get_lswitch(net_id))"},{"line_number":992,"context_line":"        self.assertEqual(2, lookup.call_count)"},{"line_number":993,"context_line":""},{"line_number":994,"context_line":"    def test_get_lrouter_by_lrouter_port(self):"},{"line_number":995,"context_line":"        self.assertIsNone("}],"source_content_type":"text/x-python","patch_set":3,"id":"10a167fe_aa051f35","line":992,"in_reply_to":"cb321166_29a6025f","updated":"2026-10-22 00:19:59.000000000","message":"Agreed, dropped in PS4. The functional test test_old_network_no_duplicated_lswitch now asserts get_lswitch(network_id), get_lswitch(ls_name) and get_lswitch(\u003cunknown uuid\u003e) against the real NB database instead.","commit_id":"dcadf13eba5ee5ad7585c0abd612fccee7710267"}]}
