)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"c06fe2038940497a9356e55389fa8ddc2ca4fa68","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"9d75c426_0f14d569","updated":"2026-09-24 19:00:43.000000000","message":"recheck functional test bug 2168215","commit_id":"6245fb8648d5b7c11664265e993dde663e81dcd0"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"2792fa4d9f0488047f6ef9dcca0fba49dd002c6d","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"3be3d6a5_ad6bb605","updated":"2026-10-09 17:25:34.000000000","message":"A functional test related to this patch failed","commit_id":"c15ef1814c766af1362791d0e8a6a8e64bc6e1e4"},{"author":{"_account_id":34271,"name":"Miro Tomaska","display_name":"Miro Tomaska","email":"mtomaska@redhat.com","username":"mtomaska"},"change_message_id":"87be362e703acb6ec9699dda2b91bc987e5f57ce","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"47e25449_b8b67f10","updated":"2026-10-14 19:00:15.000000000","message":"Just minor questions, after that LGTM","commit_id":"eec33f18b5699b42b6e6fb70d25aa9ae95917b86"}],"neutron/db/evpn_db.py":[{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"97778872d538e1abebf8bb27672d146c5e91a8a4","unresolved":false,"context_lines":[{"line_number":214,"context_line":"        rows \u003d ("},{"line_number":215,"context_line":"            context.session.query("},{"line_number":216,"context_line":"                evpn_models.EVPNL3Instance,"},{"line_number":217,"context_line":"                l3_attrs.RouterExtraAttributes.availability_zone_hints,"},{"line_number":218,"context_line":"            ).outerjoin("},{"line_number":219,"context_line":"                l3_attrs.RouterExtraAttributes,"},{"line_number":220,"context_line":"                evpn_models.EVPNL3Instance.router_id \u003d\u003d"}],"source_content_type":"text/x-python","patch_set":5,"id":"c689bc53_b9dd2132","line":217,"range":{"start_line":217,"start_character":16,"end_line":217,"end_character":71},"updated":"2026-10-20 07:51:58.000000000","message":"nice!","commit_id":"3b5eb83148f9b7db0d7f23eb61f2dc19745ff965"}],"neutron/services/evpn/db_sync.py":[{"author":{"_account_id":34271,"name":"Miro Tomaska","display_name":"Miro Tomaska","email":"mtomaska@redhat.com","username":"mtomaska"},"change_message_id":"ce7a9723e43009ce82575a47048ad3e4f79e4185","unresolved":true,"context_lines":[{"line_number":83,"context_line":"        super()._sync_topology(router_id, inst)"},{"line_number":84,"context_line":"        LOG.warning(\"Repairing EVPN topology for router %s\","},{"line_number":85,"context_line":"                    router_id)"},{"line_number":86,"context_line":"        candidates \u003d self.ovn_sb_api.get_gateway_chassis_with_az_filter("},{"line_number":87,"context_line":"            az_hints\u003dinst.get(\u0027availability_zone_hints\u0027, []))"},{"line_number":88,"context_line":"        ordered_chassis \u003d self._scheduler.select(candidates\u003dcandidates[1])"},{"line_number":89,"context_line":"        self._txn.add(evpn_commands.CreateEVPNRouterCommand("},{"line_number":90,"context_line":"            self.ovn_nb_api, router_id,"},{"line_number":91,"context_line":"            inst[\u0027vni\u0027], inst[\u0027vlan\u0027], ordered_chassis))"}],"source_content_type":"text/x-python","patch_set":1,"id":"883be2ef_6dc46b2e","line":88,"range":{"start_line":86,"start_character":0,"end_line":88,"end_character":74},"updated":"2026-09-24 15:24:32.000000000","message":"Huh? Am I am looking at this correctly? The `get_gateway_chassis_with_az_filter` returns tuple `gw_chassis, candidates`[1]\nAnd then how are are you accessing `candidates[1]` which is a set? \n[1]\nhttps://review.opendev.org/c/openstack/neutron/+/1006348/5/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/impl_idl_ovn.py","commit_id":"7bea007ff4295aa1a7b9cc05ae18e508cc45191c"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"150fd1c0d52b43f1c166f58216d4e00f7b1e6b9c","unresolved":false,"context_lines":[{"line_number":83,"context_line":"        super()._sync_topology(router_id, inst)"},{"line_number":84,"context_line":"        LOG.warning(\"Repairing EVPN topology for router %s\","},{"line_number":85,"context_line":"                    router_id)"},{"line_number":86,"context_line":"        candidates \u003d self.ovn_sb_api.get_gateway_chassis_with_az_filter("},{"line_number":87,"context_line":"            az_hints\u003dinst.get(\u0027availability_zone_hints\u0027, []))"},{"line_number":88,"context_line":"        ordered_chassis \u003d self._scheduler.select(candidates\u003dcandidates[1])"},{"line_number":89,"context_line":"        self._txn.add(evpn_commands.CreateEVPNRouterCommand("},{"line_number":90,"context_line":"            self.ovn_nb_api, router_id,"},{"line_number":91,"context_line":"            inst[\u0027vni\u0027], inst[\u0027vlan\u0027], ordered_chassis))"}],"source_content_type":"text/x-python","patch_set":1,"id":"6c896fc8_8a69faa3","line":88,"range":{"start_line":86,"start_character":0,"end_line":88,"end_character":74},"in_reply_to":"57d855a4_2a0ccc64","updated":"2026-09-24 16:55:43.000000000","message":"Done","commit_id":"7bea007ff4295aa1a7b9cc05ae18e508cc45191c"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"ee386a8f15e58b929b8b4d00a483ca5c80455b6e","unresolved":true,"context_lines":[{"line_number":83,"context_line":"        super()._sync_topology(router_id, inst)"},{"line_number":84,"context_line":"        LOG.warning(\"Repairing EVPN topology for router %s\","},{"line_number":85,"context_line":"                    router_id)"},{"line_number":86,"context_line":"        candidates \u003d self.ovn_sb_api.get_gateway_chassis_with_az_filter("},{"line_number":87,"context_line":"            az_hints\u003dinst.get(\u0027availability_zone_hints\u0027, []))"},{"line_number":88,"context_line":"        ordered_chassis \u003d self._scheduler.select(candidates\u003dcandidates[1])"},{"line_number":89,"context_line":"        self._txn.add(evpn_commands.CreateEVPNRouterCommand("},{"line_number":90,"context_line":"            self.ovn_nb_api, router_id,"},{"line_number":91,"context_line":"            inst[\u0027vni\u0027], inst[\u0027vlan\u0027], ordered_chassis))"}],"source_content_type":"text/x-python","patch_set":1,"id":"db085bd9_20fafab6","line":88,"range":{"start_line":86,"start_character":0,"end_line":88,"end_character":74},"in_reply_to":"883be2ef_6dc46b2e","updated":"2026-09-24 15:28:50.000000000","message":"You\u0027re not, the `get_gateway_chassis_with_az_filter` method returns a tuple `gw_chassis, candidates` but I\u0027m interested only in the `candidates`. as the `gw_chassis` are irrelevant here. Hence the `candidates[1]` returns the calculated `candidates`. If it\u0027s not readable then I can make the variable name more explicit.","commit_id":"7bea007ff4295aa1a7b9cc05ae18e508cc45191c"},{"author":{"_account_id":34271,"name":"Miro Tomaska","display_name":"Miro Tomaska","email":"mtomaska@redhat.com","username":"mtomaska"},"change_message_id":"6fc5f98883e2d787d186bc4c8aee6ae012235047","unresolved":true,"context_lines":[{"line_number":83,"context_line":"        super()._sync_topology(router_id, inst)"},{"line_number":84,"context_line":"        LOG.warning(\"Repairing EVPN topology for router %s\","},{"line_number":85,"context_line":"                    router_id)"},{"line_number":86,"context_line":"        candidates \u003d self.ovn_sb_api.get_gateway_chassis_with_az_filter("},{"line_number":87,"context_line":"            az_hints\u003dinst.get(\u0027availability_zone_hints\u0027, []))"},{"line_number":88,"context_line":"        ordered_chassis \u003d self._scheduler.select(candidates\u003dcandidates[1])"},{"line_number":89,"context_line":"        self._txn.add(evpn_commands.CreateEVPNRouterCommand("},{"line_number":90,"context_line":"            self.ovn_nb_api, router_id,"},{"line_number":91,"context_line":"            inst[\u0027vni\u0027], inst[\u0027vlan\u0027], ordered_chassis))"}],"source_content_type":"text/x-python","patch_set":1,"id":"57d855a4_2a0ccc64","line":88,"range":{"start_line":86,"start_character":0,"end_line":88,"end_character":74},"in_reply_to":"db085bd9_20fafab6","updated":"2026-09-24 15:59:46.000000000","message":"Ok I see what confused me. `candidates` is a tuple,and `candidates[1]` gets you the `candidates` set.\nI know we dont like `_` in neutron, because of localization. I would prefer\n`_, candidates \u003d get_gateway_chassis_with_az_filter...`\nbut if `_` is nono then\n`gw_chassis_with_candidates \u003d get_gateway_chassis_with_az_filter...; candidates\u003dgw_chassis_with_candidates[1]` is more explicit to me","commit_id":"7bea007ff4295aa1a7b9cc05ae18e508cc45191c"},{"author":{"_account_id":34271,"name":"Miro Tomaska","display_name":"Miro Tomaska","email":"mtomaska@redhat.com","username":"mtomaska"},"change_message_id":"87be362e703acb6ec9699dda2b91bc987e5f57ce","unresolved":true,"context_lines":[{"line_number":87,"context_line":"            self.ovn_sb_api.get_gateway_chassis_with_az_filter("},{"line_number":88,"context_line":"                az_hints\u003dinst.get(\u0027availability_zone_hints\u0027, [])))"},{"line_number":89,"context_line":"        ordered_chassis \u003d self._scheduler.select("},{"line_number":90,"context_line":"            candidates\u003dgw_ch_candidates_tuple[1])"},{"line_number":91,"context_line":"        self._txn.add(evpn_commands.CreateEVPNRouterCommand("},{"line_number":92,"context_line":"            self.ovn_nb_api, router_id,"},{"line_number":93,"context_line":"            inst[\u0027vni\u0027], inst[\u0027vlan\u0027], ordered_chassis))"}],"source_content_type":"text/x-python","patch_set":4,"id":"d7a44c35_dc47e9b3","line":90,"updated":"2026-10-14 19:00:15.000000000","message":"plugin.py also sets `max_chassis\u003dovn_const.MAX_GW_CHASSIS`. Thinking out loud, will there be ever a case where during create we have `MAX_GW_CHASSIS` but then when repair happens (something crashed) we would have more than MAX_GW_CHASSIS?","commit_id":"eec33f18b5699b42b6e6fb70d25aa9ae95917b86"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"8698df92bb5c560a946730d15ab8b651af5586c0","unresolved":false,"context_lines":[{"line_number":87,"context_line":"            self.ovn_sb_api.get_gateway_chassis_with_az_filter("},{"line_number":88,"context_line":"                az_hints\u003dinst.get(\u0027availability_zone_hints\u0027, [])))"},{"line_number":89,"context_line":"        ordered_chassis \u003d self._scheduler.select("},{"line_number":90,"context_line":"            candidates\u003dgw_ch_candidates_tuple[1])"},{"line_number":91,"context_line":"        self._txn.add(evpn_commands.CreateEVPNRouterCommand("},{"line_number":92,"context_line":"            self.ovn_nb_api, router_id,"},{"line_number":93,"context_line":"            inst[\u0027vni\u0027], inst[\u0027vlan\u0027], ordered_chassis))"}],"source_content_type":"text/x-python","patch_set":4,"id":"c0b97b3b_3c674739","line":90,"in_reply_to":"64b64d40_bf24eb8c","updated":"2026-10-21 22:05:08.000000000","message":"Done","commit_id":"eec33f18b5699b42b6e6fb70d25aa9ae95917b86"},{"author":{"_account_id":34271,"name":"Miro Tomaska","display_name":"Miro Tomaska","email":"mtomaska@redhat.com","username":"mtomaska"},"change_message_id":"3e10784a7e5b60a4ba72f8c5b7929229e2a2cbbf","unresolved":false,"context_lines":[{"line_number":87,"context_line":"            self.ovn_sb_api.get_gateway_chassis_with_az_filter("},{"line_number":88,"context_line":"                az_hints\u003dinst.get(\u0027availability_zone_hints\u0027, [])))"},{"line_number":89,"context_line":"        ordered_chassis \u003d self._scheduler.select("},{"line_number":90,"context_line":"            candidates\u003dgw_ch_candidates_tuple[1])"},{"line_number":91,"context_line":"        self._txn.add(evpn_commands.CreateEVPNRouterCommand("},{"line_number":92,"context_line":"            self.ovn_nb_api, router_id,"},{"line_number":93,"context_line":"            inst[\u0027vni\u0027], inst[\u0027vlan\u0027], ordered_chassis))"}],"source_content_type":"text/x-python","patch_set":4,"id":"d95bc66f_a46e6922","line":90,"in_reply_to":"d7a44c35_dc47e9b3","updated":"2026-10-14 19:11:45.000000000","message":"actually never mind. I am looking at `select` again it its fine. It will not trim the list.","commit_id":"eec33f18b5699b42b6e6fb70d25aa9ae95917b86"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"32969c5d0714d2976ff5f3bb152848a6b2c6ae46","unresolved":true,"context_lines":[{"line_number":87,"context_line":"            self.ovn_sb_api.get_gateway_chassis_with_az_filter("},{"line_number":88,"context_line":"                az_hints\u003dinst.get(\u0027availability_zone_hints\u0027, [])))"},{"line_number":89,"context_line":"        ordered_chassis \u003d self._scheduler.select("},{"line_number":90,"context_line":"            candidates\u003dgw_ch_candidates_tuple[1])"},{"line_number":91,"context_line":"        self._txn.add(evpn_commands.CreateEVPNRouterCommand("},{"line_number":92,"context_line":"            self.ovn_nb_api, router_id,"},{"line_number":93,"context_line":"            inst[\u0027vni\u0027], inst[\u0027vlan\u0027], ordered_chassis))"}],"source_content_type":"text/x-python","patch_set":4,"id":"64b64d40_bf24eb8c","line":90,"in_reply_to":"d7a44c35_dc47e9b3","updated":"2026-10-14 19:15:06.000000000","message":"yes, the MAX_GW_CHASSIS should be here consider as well. I added it as the last plugin patchset while this has been already here without it. Good catch, thanks!","commit_id":"eec33f18b5699b42b6e6fb70d25aa9ae95917b86"}],"neutron/services/evpn/scheduler.py":[{"author":{"_account_id":8313,"name":"Lajos Katona","display_name":"lajoskatona","email":"katonalala@gmail.com","username":"elajkat","status":"Ericsson Software Technology"},"change_message_id":"26ebc6a820e7181debc6b110c106094e629d4421","unresolved":false,"context_lines":[{"line_number":71,"context_line":"    def _order(self, candidates):"},{"line_number":72,"context_line":"        ordered \u003d list(candidates)"},{"line_number":73,"context_line":"        random.shuffle(ordered)"},{"line_number":74,"context_line":"        return ordered"}],"source_content_type":"text/x-python","patch_set":2,"id":"28d7c381_61f82609","line":74,"range":{"start_line":74,"start_character":15,"end_line":74,"end_character":22},"updated":"2026-09-29 09:18:57.000000000","message":"nit: at this point it is not ordered, but I see the naming problem here :-)","commit_id":"6245fb8648d5b7c11664265e993dde663e81dcd0"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"e076539c670bd5fc8839b54eeb348a273579d5e3","unresolved":false,"context_lines":[{"line_number":71,"context_line":"    def _order(self, candidates):"},{"line_number":72,"context_line":"        ordered \u003d list(candidates)"},{"line_number":73,"context_line":"        random.shuffle(ordered)"},{"line_number":74,"context_line":"        return ordered"}],"source_content_type":"text/x-python","patch_set":2,"id":"39eb250a_96c30584","line":74,"range":{"start_line":74,"start_character":15,"end_line":74,"end_character":22},"in_reply_to":"28d7c381_61f82609","updated":"2026-10-04 17:02:37.000000000","message":"it is ordered randomly :)","commit_id":"6245fb8648d5b7c11664265e993dde663e81dcd0"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"97778872d538e1abebf8bb27672d146c5e91a8a4","unresolved":true,"context_lines":[{"line_number":73,"context_line":"    call the least-used eligible chassis is placed first, with ties"},{"line_number":74,"context_line":"    broken randomly."},{"line_number":75,"context_line":""},{"line_number":76,"context_line":"    Intended for batch operations (e.g. DB-sync repair) where all"},{"line_number":77,"context_line":"    scheduling decisions are collected into a single OVSDB transaction"},{"line_number":78,"context_line":"    and committed load information is therefore stale."},{"line_number":79,"context_line":"    \"\"\""},{"line_number":80,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"4a7eab31_6c1d95d9","line":77,"range":{"start_line":76,"start_character":4,"end_line":77,"end_character":70},"updated":"2026-10-20 07:51:58.000000000","message":"I would make this more clear (at least for me), explicitly saying that this scheduler will be used by one single worker, as long as the load information (`_internal_load`) is stored locally.\n\nI want to avoid using this scheduler, in a future, as an alternative of `LeastLoadedChassisScheduler`.","commit_id":"3b5eb83148f9b7db0d7f23eb61f2dc19745ff965"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"aa8c65fef917c27ab3eaaac42c0585b602598eec","unresolved":false,"context_lines":[{"line_number":73,"context_line":"    call the least-used eligible chassis is placed first, with ties"},{"line_number":74,"context_line":"    broken randomly."},{"line_number":75,"context_line":""},{"line_number":76,"context_line":"    Intended for batch operations (e.g. DB-sync repair) where all"},{"line_number":77,"context_line":"    scheduling decisions are collected into a single OVSDB transaction"},{"line_number":78,"context_line":"    and committed load information is therefore stale."},{"line_number":79,"context_line":"    \"\"\""},{"line_number":80,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"787c67f6_705dde56","line":77,"range":{"start_line":76,"start_character":4,"end_line":77,"end_character":70},"in_reply_to":"4a7eab31_6c1d95d9","updated":"2026-10-21 22:04:25.000000000","message":"Done","commit_id":"3b5eb83148f9b7db0d7f23eb61f2dc19745ff965"}],"neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovn_db_sync.py":[{"author":{"_account_id":34271,"name":"Miro Tomaska","display_name":"Miro Tomaska","email":"mtomaska@redhat.com","username":"mtomaska"},"change_message_id":"87be362e703acb6ec9699dda2b91bc987e5f57ce","unresolved":true,"context_lines":[{"line_number":2626,"context_line":""},{"line_number":2627,"context_line":"        self.assertEqual(n_chassis, len(primaries))"},{"line_number":2628,"context_line":""},{"line_number":2629,"context_line":"    def test_evpn_sync_repair_respects_az_hints(self):"},{"line_number":2630,"context_line":"        \"\"\"Verify that sync repair filters chassis by router AZ hints.\"\"\""},{"line_number":2631,"context_line":"        ch1 \u003d self.add_fake_chassis("},{"line_number":2632,"context_line":"            \u0027host1\u0027, azs\u003d[\u0027az-1\u0027], enable_chassis_as_gw\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":4,"id":"2da53007_92d0b3a6","line":2629,"range":{"start_line":2629,"start_character":8,"end_line":2629,"end_character":48},"updated":"2026-10-14 19:00:15.000000000","message":"maybe one more test `test_evpn_sync_repair_with_no_canditates` to make sure nothing goes wrong if there is no AZ or Gw candidate.","commit_id":"eec33f18b5699b42b6e6fb70d25aa9ae95917b86"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"32969c5d0714d2976ff5f3bb152848a6b2c6ae46","unresolved":false,"context_lines":[{"line_number":2626,"context_line":""},{"line_number":2627,"context_line":"        self.assertEqual(n_chassis, len(primaries))"},{"line_number":2628,"context_line":""},{"line_number":2629,"context_line":"    def test_evpn_sync_repair_respects_az_hints(self):"},{"line_number":2630,"context_line":"        \"\"\"Verify that sync repair filters chassis by router AZ hints.\"\"\""},{"line_number":2631,"context_line":"        ch1 \u003d self.add_fake_chassis("},{"line_number":2632,"context_line":"            \u0027host1\u0027, azs\u003d[\u0027az-1\u0027], enable_chassis_as_gw\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":4,"id":"9a1ddea6_ab25371e","line":2629,"range":{"start_line":2629,"start_character":8,"end_line":2629,"end_character":48},"in_reply_to":"2da53007_92d0b3a6","updated":"2026-10-14 19:15:06.000000000","message":"Done","commit_id":"eec33f18b5699b42b6e6fb70d25aa9ae95917b86"}]}
