)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":1131,"name":"Brian Haley","email":"haleyb.dev@gmail.com","username":"brian-haley"},"change_message_id":"0c17ab9faa7bf5107f2a19502793eb8b5ff1fb7f","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"f8299dd9_41417387","updated":"2025-12-01 20:59:36.000000000","message":"Thanks for the patch, seems like it addresses the issue, just had a few comments.\n\nCan you also add a test for this? Thanks","commit_id":"d7a40a597d1d188df42185c074c375b9e9f27fa8"},{"author":{"_account_id":16137,"name":"Tobias Urdin","email":"tobias.urdin@binero.com","username":"tobasco"},"change_message_id":"00cc62178bafbc9fa0152e787c5dbd3de2192674","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"9b843082_bf4cb35d","in_reply_to":"f8299dd9_41417387","updated":"2025-12-02 08:03:20.000000000","message":"Thanks for the feedback. I\u0027ve updated it, let\u0027s see what it says.","commit_id":"d7a40a597d1d188df42185c074c375b9e9f27fa8"},{"author":{"_account_id":16137,"name":"Tobias Urdin","email":"tobias.urdin@binero.com","username":"tobasco"},"change_message_id":"2a6c5701c2735be5fa130145e0b97d424f2362af","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"d637e076_3becb3a0","updated":"2025-12-02 11:04:21.000000000","message":"Confirmed in functional test logs:\n\n2025-12-02 08:14:45.116 76663 INFO neutron.agent.linux.dhcp [-] Cleaning stale devices for network foo_id\n2025-12-02 08:14:45.145 76663 WARNING neutron.agent.linux.dhcp [-] Found stale port foo_id5 for network foo_id bound to wrong that is not us foo-host, deleting\n2025-12-02 08:14:45.150 76663 DEBUG ovsdbapp.backend.ovs_idl.transaction [-] Running txn n\u003d1 command(idx\u003d0): DelPortCommand(_result\u003dNone, port\u003dtapfoo_id5, bridge\u003dtest-br08fafa24, if_exists\u003dTrue) do_commit /home/zuul/src/opendev.org/openstack/neutron/.tox/dsvm-functional-g\nate/lib/python3.12/site-packages/ovsdbapp/backend/ovs_idl/transaction.py:89","commit_id":"a14ce2524b61ff94dd0e32ffcf6f39e732f6efd5"},{"author":{"_account_id":16137,"name":"Tobias Urdin","email":"tobias.urdin@binero.com","username":"tobasco"},"change_message_id":"6c8e74fd423eb01a1ac2372c2655631914eb4d14","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"af92f238_60f671bc","updated":"2025-12-02 20:40:44.000000000","message":"I will push an update tomorrow first thing.","commit_id":"a14ce2524b61ff94dd0e32ffcf6f39e732f6efd5"},{"author":{"_account_id":1131,"name":"Brian Haley","email":"haleyb.dev@gmail.com","username":"brian-haley"},"change_message_id":"f1912a4fcf1eceb128b9e765eba080335fd62d4d","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"fb9abac8_da643fad","updated":"2025-12-04 19:09:42.000000000","message":"Just setting -1 so questions are answered","commit_id":"16594c4e246fc61e422211bc6a327f57d755417d"},{"author":{"_account_id":1131,"name":"Brian Haley","email":"haleyb.dev@gmail.com","username":"brian-haley"},"change_message_id":"84acd03516f958ba80ee06ae2220b475a483248c","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"90b36c25_f171793c","updated":"2025-12-03 21:56:56.000000000","message":"So does this still only partially fix the bug? Just want to make sure that is correct.","commit_id":"16594c4e246fc61e422211bc6a327f57d755417d"},{"author":{"_account_id":16137,"name":"Tobias Urdin","email":"tobias.urdin@binero.com","username":"tobasco"},"change_message_id":"d5f08f0043f72802c10057f65a09cb3424250bfa","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"27c399df_41d83972","in_reply_to":"90b36c25_f171793c","updated":"2025-12-05 08:17:28.000000000","message":"It is not clear to me why the bug happened in the first place and I\u0027ve no way to reproduce it, when trying to trace when it happened it was several months back (6+ months) which somewhat corresponds to when we upgraded last time.\n\nI was however able to verify, when the issue was present, that restarting the dhcp agent did not heal the situation, so this adds the fix so that the dhcp agent can self heal the situation (at least on dhcp agent restart) so that one does not have to add/remove dhcp agent for a network (\"reprovision\" in a sense) to have it recreate qdhcp namespace with correct interfaces.","commit_id":"16594c4e246fc61e422211bc6a327f57d755417d"},{"author":{"_account_id":37598,"name":"Ivan Anfimov","display_name":"Ivan Anfimov","email":"lazekteam@gmail.com","username":"anfimovir"},"change_message_id":"426d64d969512280449f4ddbf54b1409ee277c5d","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"1fd2598d_1d626273","updated":"2026-01-09 11:18:08.000000000","message":"recheck","commit_id":"479718d362c9077a57eeb9263e93b274ea10f677"},{"author":{"_account_id":16137,"name":"Tobias Urdin","email":"tobias.urdin@binero.com","username":"tobasco"},"change_message_id":"25c2ad1e3b01e29d4473e262d6758bc26148969f","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"1e72efdb_483c8f1e","updated":"2025-12-05 13:37:24.000000000","message":"recheck post_failure","commit_id":"479718d362c9077a57eeb9263e93b274ea10f677"},{"author":{"_account_id":8313,"name":"Lajos Katona","display_name":"lajoskatona","email":"katonalala@gmail.com","username":"elajkat","status":"Ericsson Software Technology"},"change_message_id":"21a9f3ae274c78b7c0b4c02483be66866d0102b2","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"f8d73d39_60c413dd","updated":"2026-01-09 08:02:26.000000000","message":"thanks","commit_id":"479718d362c9077a57eeb9263e93b274ea10f677"}],"neutron/agent/linux/dhcp.py":[{"author":{"_account_id":1131,"name":"Brian Haley","email":"haleyb.dev@gmail.com","username":"brian-haley"},"change_message_id":"0c17ab9faa7bf5107f2a19502793eb8b5ff1fb7f","unresolved":true,"context_lines":[{"line_number":1777,"context_line":"        hw_ports \u003d {d.name for d in ns_ip.get_devices()}"},{"line_number":1778,"context_line":""},{"line_number":1779,"context_line":"        for port in network.ports:"},{"line_number":1780,"context_line":"            host_id \u003d port.get(\u0027binding:host_id\u0027, None)"},{"line_number":1781,"context_line":"            if host_id is None:"},{"line_number":1782,"context_line":"                continue"},{"line_number":1783,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"e053aeda_bcb73d8b","line":1780,"updated":"2025-12-01 20:59:36.000000000","message":"nit: should use the definition from neutron-lib:\n\nfrom neutron_lib.api.definitions import portbindings\n\nhost_id \u003d port.get(portbindings.HOST_ID, None)","commit_id":"d7a40a597d1d188df42185c074c375b9e9f27fa8"},{"author":{"_account_id":16137,"name":"Tobias Urdin","email":"tobias.urdin@binero.com","username":"tobasco"},"change_message_id":"00cc62178bafbc9fa0152e787c5dbd3de2192674","unresolved":false,"context_lines":[{"line_number":1777,"context_line":"        hw_ports \u003d {d.name for d in ns_ip.get_devices()}"},{"line_number":1778,"context_line":""},{"line_number":1779,"context_line":"        for port in network.ports:"},{"line_number":1780,"context_line":"            host_id \u003d port.get(\u0027binding:host_id\u0027, None)"},{"line_number":1781,"context_line":"            if host_id is None:"},{"line_number":1782,"context_line":"                continue"},{"line_number":1783,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"26213243_d68574da","line":1780,"in_reply_to":"e053aeda_bcb73d8b","updated":"2025-12-02 08:03:20.000000000","message":"Done","commit_id":"d7a40a597d1d188df42185c074c375b9e9f27fa8"},{"author":{"_account_id":1131,"name":"Brian Haley","email":"haleyb.dev@gmail.com","username":"brian-haley"},"change_message_id":"0c17ab9faa7bf5107f2a19502793eb8b5ff1fb7f","unresolved":true,"context_lines":[{"line_number":1786,"context_line":"                continue"},{"line_number":1787,"context_line":""},{"line_number":1788,"context_line":"            if host_id and host_id !\u003d self.conf.host:"},{"line_number":1789,"context_line":"                LOG.info(f\"Found stale port {port.id} for network \""},{"line_number":1790,"context_line":"                         f\"{network.id} bound to {host_id} that is \""},{"line_number":1791,"context_line":"                         f\"not us {self.conf.host}\")"},{"line_number":1792,"context_line":"                try:"}],"source_content_type":"text/x-python","patch_set":1,"id":"feb2801b_5b674032","line":1789,"range":{"start_line":1789,"start_character":20,"end_line":1789,"end_character":24},"updated":"2025-12-01 20:59:36.000000000","message":"Not sure if this should be warning level like below.","commit_id":"d7a40a597d1d188df42185c074c375b9e9f27fa8"},{"author":{"_account_id":16137,"name":"Tobias Urdin","email":"tobias.urdin@binero.com","username":"tobasco"},"change_message_id":"00cc62178bafbc9fa0152e787c5dbd3de2192674","unresolved":false,"context_lines":[{"line_number":1786,"context_line":"                continue"},{"line_number":1787,"context_line":""},{"line_number":1788,"context_line":"            if host_id and host_id !\u003d self.conf.host:"},{"line_number":1789,"context_line":"                LOG.info(f\"Found stale port {port.id} for network \""},{"line_number":1790,"context_line":"                         f\"{network.id} bound to {host_id} that is \""},{"line_number":1791,"context_line":"                         f\"not us {self.conf.host}\")"},{"line_number":1792,"context_line":"                try:"}],"source_content_type":"text/x-python","patch_set":1,"id":"76bacdad_22003b35","line":1789,"range":{"start_line":1789,"start_character":20,"end_line":1789,"end_character":24},"in_reply_to":"feb2801b_5b674032","updated":"2025-12-02 08:03:20.000000000","message":"Done","commit_id":"d7a40a597d1d188df42185c074c375b9e9f27fa8"},{"author":{"_account_id":1131,"name":"Brian Haley","email":"haleyb.dev@gmail.com","username":"brian-haley"},"change_message_id":"0c17ab9faa7bf5107f2a19502793eb8b5ff1fb7f","unresolved":true,"context_lines":[{"line_number":1788,"context_line":"            if host_id and host_id !\u003d self.conf.host:"},{"line_number":1789,"context_line":"                LOG.info(f\"Found stale port {port.id} for network \""},{"line_number":1790,"context_line":"                         f\"{network.id} bound to {host_id} that is \""},{"line_number":1791,"context_line":"                         f\"not us {self.conf.host}\")"},{"line_number":1792,"context_line":"                try:"},{"line_number":1793,"context_line":"                    self.unplug(dev_name, network)"},{"line_number":1794,"context_line":"                except Exception:"}],"source_content_type":"text/x-python","patch_set":1,"id":"6f5d320e_c8d3c3be","line":1791,"updated":"2025-12-01 20:59:36.000000000","message":"nit: can you just make this like below with a \", deleting\" at the end?","commit_id":"d7a40a597d1d188df42185c074c375b9e9f27fa8"},{"author":{"_account_id":16137,"name":"Tobias Urdin","email":"tobias.urdin@binero.com","username":"tobasco"},"change_message_id":"00cc62178bafbc9fa0152e787c5dbd3de2192674","unresolved":false,"context_lines":[{"line_number":1788,"context_line":"            if host_id and host_id !\u003d self.conf.host:"},{"line_number":1789,"context_line":"                LOG.info(f\"Found stale port {port.id} for network \""},{"line_number":1790,"context_line":"                         f\"{network.id} bound to {host_id} that is \""},{"line_number":1791,"context_line":"                         f\"not us {self.conf.host}\")"},{"line_number":1792,"context_line":"                try:"},{"line_number":1793,"context_line":"                    self.unplug(dev_name, network)"},{"line_number":1794,"context_line":"                except Exception:"}],"source_content_type":"text/x-python","patch_set":1,"id":"65ad9c98_cbd01d9a","line":1791,"in_reply_to":"6f5d320e_c8d3c3be","updated":"2025-12-02 08:03:20.000000000","message":"Done","commit_id":"d7a40a597d1d188df42185c074c375b9e9f27fa8"},{"author":{"_account_id":1131,"name":"Brian Haley","email":"haleyb.dev@gmail.com","username":"brian-haley"},"change_message_id":"cabfd7575bb27a3d460c954b35405a2b838be58d","unresolved":true,"context_lines":[{"line_number":1779,"context_line":""},{"line_number":1780,"context_line":"        for port in network.ports:"},{"line_number":1781,"context_line":"            host_id \u003d port.get(portbindings.HOST_ID, None)"},{"line_number":1782,"context_line":"            if host_id is None:"},{"line_number":1783,"context_line":"                continue"},{"line_number":1784,"context_line":""},{"line_number":1785,"context_line":"            dev_name \u003d self.driver.get_device_name(port)"}],"source_content_type":"text/x-python","patch_set":2,"id":"98fe4be8_7e5a2fa6","line":1782,"updated":"2025-12-02 19:08:39.000000000","message":"Looking at this again I had one more comment. From looking at other code it seems the value here will be \u0027\u0027 if not bound. Maybe the easiest thing to do is reverse the checks here?\n\n            dev_name \u003d self.driver.get_device_name(port)\n            if dev_name not in hw_ports:\n                continue\n\n            host_id \u003d port.get(portbindings.HOST_ID)\n            if host_id and host_id !\u003d self.conf.host:\n\nPlease check my logic though, could be completely wrong.","commit_id":"a14ce2524b61ff94dd0e32ffcf6f39e732f6efd5"},{"author":{"_account_id":16137,"name":"Tobias Urdin","email":"tobias.urdin@binero.com","username":"tobasco"},"change_message_id":"fe164c4f1fc8424d5ec6e62753b1e02b4fd8a977","unresolved":true,"context_lines":[{"line_number":1779,"context_line":""},{"line_number":1780,"context_line":"        for port in network.ports:"},{"line_number":1781,"context_line":"            host_id \u003d port.get(portbindings.HOST_ID, None)"},{"line_number":1782,"context_line":"            if host_id is None:"},{"line_number":1783,"context_line":"                continue"},{"line_number":1784,"context_line":""},{"line_number":1785,"context_line":"            dev_name \u003d self.driver.get_device_name(port)"}],"source_content_type":"text/x-python","patch_set":2,"id":"62c8a2c2_17cc8d59","line":1782,"in_reply_to":"98fe4be8_7e5a2fa6","updated":"2025-12-02 20:40:28.000000000","message":"I can rearrange it that way instead if it\u0027s more preferable, shouldn\u0027t be an issue.","commit_id":"a14ce2524b61ff94dd0e32ffcf6f39e732f6efd5"},{"author":{"_account_id":1131,"name":"Brian Haley","email":"haleyb.dev@gmail.com","username":"brian-haley"},"change_message_id":"84acd03516f958ba80ee06ae2220b475a483248c","unresolved":true,"context_lines":[{"line_number":1782,"context_line":"            if dev_name not in hw_ports:"},{"line_number":1783,"context_line":"                continue"},{"line_number":1784,"context_line":""},{"line_number":1785,"context_line":"            host_id \u003d port.get(portbindings.HOST_ID, None)"},{"line_number":1786,"context_line":"            if host_id and host_id !\u003d self.conf.host:"},{"line_number":1787,"context_line":"                LOG.warning(f\"Found stale port {port.id} for network \""},{"line_number":1788,"context_line":"                            f\"{network.id} bound to {host_id} that is \""}],"source_content_type":"text/x-python","patch_set":3,"id":"e9e35e46_b474baa1","line":1785,"range":{"start_line":1785,"start_character":52,"end_line":1785,"end_character":57},"updated":"2025-12-03 21:56:56.000000000","message":"I don\u0027t think you need the None here","commit_id":"16594c4e246fc61e422211bc6a327f57d755417d"},{"author":{"_account_id":16137,"name":"Tobias Urdin","email":"tobias.urdin@binero.com","username":"tobasco"},"change_message_id":"5e9a7f1a1d405fbee7f6e11526a83b9f5a0aaf37","unresolved":false,"context_lines":[{"line_number":1782,"context_line":"            if dev_name not in hw_ports:"},{"line_number":1783,"context_line":"                continue"},{"line_number":1784,"context_line":""},{"line_number":1785,"context_line":"            host_id \u003d port.get(portbindings.HOST_ID, None)"},{"line_number":1786,"context_line":"            if host_id and host_id !\u003d self.conf.host:"},{"line_number":1787,"context_line":"                LOG.warning(f\"Found stale port {port.id} for network \""},{"line_number":1788,"context_line":"                            f\"{network.id} bound to {host_id} that is \""}],"source_content_type":"text/x-python","patch_set":3,"id":"2c48b96b_3c6adc87","line":1785,"range":{"start_line":1785,"start_character":52,"end_line":1785,"end_character":57},"in_reply_to":"e9e35e46_b474baa1","updated":"2025-12-05 08:13:40.000000000","message":"Done","commit_id":"16594c4e246fc61e422211bc6a327f57d755417d"}],"neutron/tests/functional/agent/linux/test_dhcp.py":[{"author":{"_account_id":1131,"name":"Brian Haley","email":"haleyb.dev@gmail.com","username":"brian-haley"},"change_message_id":"cabfd7575bb27a3d460c954b35405a2b838be58d","unresolved":true,"context_lines":[{"line_number":59,"context_line":"            \u0027binding:host_id\u0027: \u0027wrong\u0027,"},{"line_number":60,"context_line":"            \u0027mac_address\u0027: \u002710:22:33:44:55:71\u0027,"},{"line_number":61,"context_line":"            \u0027fixed_ips\u0027: [tests_base.AttributeDict("},{"line_number":62,"context_line":"                {\u0027subnet_id\u0027: \u0027subnet_foo_id\u0027, \u0027ip_address\u0027: \u002710.0.0.7\u0027})]"},{"line_number":63,"context_line":"        })"},{"line_number":64,"context_line":"        network \u003d {"},{"line_number":65,"context_line":"            \u0027id\u0027: \u0027foo_id\u0027,"}],"source_content_type":"text/x-python","patch_set":2,"id":"e7db79b9_34c0169c","line":62,"range":{"start_line":62,"start_character":31,"end_line":62,"end_character":44},"updated":"2025-12-02 19:08:39.000000000","message":"Is this supposed to be subnet_foo_id4 ? It might not matter either way.","commit_id":"a14ce2524b61ff94dd0e32ffcf6f39e732f6efd5"},{"author":{"_account_id":16137,"name":"Tobias Urdin","email":"tobias.urdin@binero.com","username":"tobasco"},"change_message_id":"fe164c4f1fc8424d5ec6e62753b1e02b4fd8a977","unresolved":true,"context_lines":[{"line_number":59,"context_line":"            \u0027binding:host_id\u0027: \u0027wrong\u0027,"},{"line_number":60,"context_line":"            \u0027mac_address\u0027: \u002710:22:33:44:55:71\u0027,"},{"line_number":61,"context_line":"            \u0027fixed_ips\u0027: [tests_base.AttributeDict("},{"line_number":62,"context_line":"                {\u0027subnet_id\u0027: \u0027subnet_foo_id\u0027, \u0027ip_address\u0027: \u002710.0.0.7\u0027})]"},{"line_number":63,"context_line":"        })"},{"line_number":64,"context_line":"        network \u003d {"},{"line_number":65,"context_line":"            \u0027id\u0027: \u0027foo_id\u0027,"}],"source_content_type":"text/x-python","patch_set":2,"id":"fc55ce59_deb8794b","line":62,"range":{"start_line":62,"start_character":31,"end_line":62,"end_character":44},"in_reply_to":"e7db79b9_34c0169c","updated":"2025-12-02 20:40:28.000000000","message":"You\u0027re right, it should be to be correct but it doesn\u0027t have any impact on the testing.","commit_id":"a14ce2524b61ff94dd0e32ffcf6f39e732f6efd5"}]}
