)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":5756,"name":"Terry Wilson","email":"twilson@redhat.com","username":"otherwiseguy"},"change_message_id":"a02116081fa356a8bbe44f85fc1ecf7f2cb138be","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"dfe1633e_2f795ee8","updated":"2021-11-23 19:47:51.000000000","message":"The flaky agent_change test I think is because even though I\u0027m using a WaitEvent in the test to wait for the Chassis_Private creation...it can be run *before* the other event that waits for the event that creates the db object. Yay threads. Just doing a wait_until() on get_agent returning is probably the only real course of action.","commit_id":"3aecdaee8003fb2c4122709051ae031e9e505f6f"},{"author":{"_account_id":5756,"name":"Terry Wilson","email":"twilson@redhat.com","username":"otherwiseguy"},"change_message_id":"aba88bd5939e2db950a016ea83faedebc9341422","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"80647c73_56e8b5cd","updated":"2021-11-23 16:23:23.000000000","message":"note: the agent_change test failure here: https://storage.bhs.cloud.ovh.net/v1/AUTH_dcaab5e32b234d56b626f72581e3644c/zuul_opendev_logs_53d/818850/1/check/neutron-functional-with-uwsgi/53dc8c1/testr_results.html\n\nis the one I get that is flaky. Haven\u0027t seen it with the other agent tests.","commit_id":"3aecdaee8003fb2c4122709051ae031e9e505f6f"},{"author":{"_account_id":5756,"name":"Terry Wilson","email":"twilson@redhat.com","username":"otherwiseguy"},"change_message_id":"509a44bf2c1cb5905c29c2219733f87b8a459fa7","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":11,"id":"e6c2a682_24af6b07","updated":"2022-01-06 20:13:24.000000000","message":"recheck","commit_id":"d0c5eb0b28fd7b54e9b7072b2bfb8ca1197f78dd"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"c2501ad363a55116c64e351f771a5e82cfd68f7e","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":14,"id":"cb6ed36e_c7368cac","updated":"2022-01-28 10:33:26.000000000","message":"I\u0027ve rebased this patch because zuul was not checking it.","commit_id":"87521dc70bf295ff0f9e31dca97b241c615a69e6"},{"author":{"_account_id":5756,"name":"Terry Wilson","email":"twilson@redhat.com","username":"otherwiseguy"},"change_message_id":"464fce00f6f756bda4eca8627d6a83b125313966","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":23,"id":"68c389c6_d12d5616","updated":"2026-07-21 01:50:08.000000000","message":"recheck","commit_id":"cb254c3af47354db2fdd71eba603e13d5ec8b1db"}],"neutron/plugins/ml2/drivers/ovn/agent/neutron_agent.py":[{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"d3931ce576cc306ebc1b74666634276636542098","unresolved":true,"context_lines":[{"line_number":45,"context_line":"    def chassis(self):"},{"line_number":46,"context_line":"        return self._get_chassis(self.chassis_private)"},{"line_number":47,"context_line":""},{"line_number":48,"context_line":"    def agent_state(self):"},{"line_number":49,"context_line":"        \"\"\"Build the agent_state dict for create_or_update_agent().\"\"\""},{"line_number":50,"context_line":"        return {"},{"line_number":51,"context_line":"            \u0027binary\u0027: self.binary,"}],"source_content_type":"text/x-python","patch_set":24,"id":"7fbbb982_1d083737","line":48,"range":{"start_line":48,"start_character":8,"end_line":48,"end_character":19},"updated":"2026-07-30 14:56:03.000000000","message":"supernit: `state` should be enough and `agent.state()` would read better in the code than `agent.agent_state()`.","commit_id":"c90d31969e3c2103d6732e6dbec9aceec6c6f9cc"},{"author":{"_account_id":5756,"name":"Terry Wilson","email":"twilson@redhat.com","username":"otherwiseguy"},"change_message_id":"fefd925c360b84a836e94670b80ca0fc003775b4","unresolved":true,"context_lines":[{"line_number":45,"context_line":"    def chassis(self):"},{"line_number":46,"context_line":"        return self._get_chassis(self.chassis_private)"},{"line_number":47,"context_line":""},{"line_number":48,"context_line":"    def agent_state(self):"},{"line_number":49,"context_line":"        \"\"\"Build the agent_state dict for create_or_update_agent().\"\"\""},{"line_number":50,"context_line":"        return {"},{"line_number":51,"context_line":"            \u0027binary\u0027: self.binary,"}],"source_content_type":"text/x-python","patch_set":24,"id":"ecab08ec_c5de3bd5","line":48,"range":{"start_line":48,"start_character":8,"end_line":48,"end_character":19},"in_reply_to":"7fbbb982_1d083737","updated":"2026-08-03 17:24:11.000000000","message":"I don\u0027t necessarily disagree, but I will note that metadata agent uses self.agent_state, as does sriov_nic_agent, l3_agent, dhcp_agent, and metering agent.","commit_id":"c90d31969e3c2103d6732e6dbec9aceec6c6f9cc"}],"neutron/plugins/ml2/drivers/ovn/mech_driver/mech_driver.py":[{"author":{"_account_id":11975,"name":"Slawek Kaplonski","email":"skaplons@redhat.com","username":"slaweq"},"change_message_id":"6f1bb48ab849ec9a78f97989ca529140d6191085","unresolved":true,"context_lines":[{"line_number":392,"context_line":""},{"line_number":393,"context_line":"    def _report_state(self):"},{"line_number":394,"context_line":"        # write nb_cfg if we haven\u0027t updated in a while"},{"line_number":395,"context_line":"        self.ping_all_chassis()"},{"line_number":396,"context_line":""},{"line_number":397,"context_line":"    def _create_security_group_precommit(self, resource, event, trigger,"},{"line_number":398,"context_line":"                                         payload):"}],"source_content_type":"text/x-python","patch_set":13,"id":"53549748_b7b56091","line":395,"updated":"2022-01-26 10:57:30.000000000","message":"sorry for maybe dummy question, but it periodically will ping all chassis from the neutron-server and where result of that will be stored?\nAlso, IIUC this will be done from all neutron-server workers, right? Is that really needed?","commit_id":"cad952553ca28c39022bfde12fb2b6b33ce31177"},{"author":{"_account_id":5756,"name":"Terry Wilson","email":"twilson@redhat.com","username":"otherwiseguy"},"change_message_id":"c929af9abd5de82e6ef68e1398e8c2c3b68002d1","unresolved":false,"context_lines":[{"line_number":392,"context_line":""},{"line_number":393,"context_line":"    def _report_state(self):"},{"line_number":394,"context_line":"        # write nb_cfg if we haven\u0027t updated in a while"},{"line_number":395,"context_line":"        self.ping_all_chassis()"},{"line_number":396,"context_line":""},{"line_number":397,"context_line":"    def _create_security_group_precommit(self, resource, event, trigger,"},{"line_number":398,"context_line":"                                         payload):"}],"source_content_type":"text/x-python","patch_set":13,"id":"26800d84_23b800e4","line":395,"in_reply_to":"53549748_b7b56091","updated":"2022-06-23 21:25:02.000000000","message":"It\u0027ll periodically call ping_all_chassis() which will only do things if there hasn\u0027t been if enough time passed (agent_down_time / 2).\n\nIt is under the check for:\n\n    if worker_class \u003d worker.MaintenanceWorker:\n    \nso it should only happen on that one worker (which IIRC has an ovsdb lock so it only does things on one worker on one server--but I should double check that).\n\nThere is some other stuff that I need to move to monitoring only on the MaintenanceWorker though.","commit_id":"cad952553ca28c39022bfde12fb2b6b33ce31177"}],"neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/impl_idl_ovn.py":[{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"d3931ce576cc306ebc1b74666634276636542098","unresolved":true,"context_lines":[{"line_number":1066,"context_line":"                                        constants.DEVICE_OWNER_DISTRIBUTED}))"},{"line_number":1067,"context_line":"        return next(iter(cmd.execute(check_error\u003dTrue)), None)"},{"line_number":1068,"context_line":""},{"line_number":1069,"context_line":"    def set_chassis_neutron_description(self, chassis, description,"},{"line_number":1070,"context_line":"                                        agent_type):"},{"line_number":1071,"context_line":"        desc_key \u003d (ovn_const.OVN_AGENT_METADATA_DESC_KEY"},{"line_number":1072,"context_line":"                    if agent_type \u003d\u003d ovn_const.OVN_METADATA_AGENT else"}],"source_content_type":"text/x-python","patch_set":24,"id":"3963ec58_2ce78cf8","line":1069,"updated":"2026-07-30 14:56:03.000000000","message":"my AI agent thinks this is a dead code and I think it is correct :)","commit_id":"c90d31969e3c2103d6732e6dbec9aceec6c6f9cc"},{"author":{"_account_id":5756,"name":"Terry Wilson","email":"twilson@redhat.com","username":"otherwiseguy"},"change_message_id":"9515ed4d0ec4e5a3263ba92a2be6ed1cd8334513","unresolved":false,"context_lines":[{"line_number":1066,"context_line":"                                        constants.DEVICE_OWNER_DISTRIBUTED}))"},{"line_number":1067,"context_line":"        return next(iter(cmd.execute(check_error\u003dTrue)), None)"},{"line_number":1068,"context_line":""},{"line_number":1069,"context_line":"    def set_chassis_neutron_description(self, chassis, description,"},{"line_number":1070,"context_line":"                                        agent_type):"},{"line_number":1071,"context_line":"        desc_key \u003d (ovn_const.OVN_AGENT_METADATA_DESC_KEY"},{"line_number":1072,"context_line":"                    if agent_type \u003d\u003d ovn_const.OVN_METADATA_AGENT else"}],"source_content_type":"text/x-python","patch_set":24,"id":"cb180f2c_4cf8f558","line":1069,"in_reply_to":"3963ec58_2ce78cf8","updated":"2026-08-05 13:15:15.000000000","message":"Done","commit_id":"c90d31969e3c2103d6732e6dbec9aceec6c6f9cc"}],"neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/ovsdb_monitor.py":[{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"d3931ce576cc306ebc1b74666634276636542098","unresolved":true,"context_lines":[{"line_number":327,"context_line":"    def match_fn(self, event, row, old\u003dNone):"},{"line_number":328,"context_line":"        if event \u003d\u003d self.ROW_DELETE:"},{"line_number":329,"context_line":"            return True"},{"line_number":330,"context_line":"        # ROW_UPDATE: only match when chassis reference was cleared."},{"line_number":331,"context_line":"        # NOTE: we cannot rely on ``old.chassis`` still containing the"},{"line_number":332,"context_line":"        # previous Chassis UUID, because when the Chassis row is deleted"},{"line_number":333,"context_line":"        # the weak reference in Chassis_Private.chassis is cleared at the"},{"line_number":334,"context_line":"        # same time the Chassis row is removed from the IDL cache. When"},{"line_number":335,"context_line":"        # ``old.chassis`` is resolved through ``Datum.to_python()``, any"},{"line_number":336,"context_line":"        # UUID that no longer points to an existing row is dropped from"},{"line_number":337,"context_line":"        # the returned list, so ``old.chassis`` ends up empty. Instead,"},{"line_number":338,"context_line":"        # detect the clearing by checking that the ``chassis`` column was"},{"line_number":339,"context_line":"        # part of the update (``hasattr(old, \u0027chassis\u0027)``) and that the"},{"line_number":340,"context_line":"        # new value is empty."},{"line_number":341,"context_line":"        return hasattr(old, \u0027chassis\u0027) and not row.chassis"},{"line_number":342,"context_line":""},{"line_number":343,"context_line":""}],"source_content_type":"text/x-python","patch_set":24,"id":"d390fa1f_b34b5c0d","side":"PARENT","line":340,"range":{"start_line":330,"start_character":0,"end_line":340,"end_character":29},"updated":"2026-07-30 14:56:03.000000000","message":"This seems to be still relevant, or isn\u0027t it? Not related to this patch but I do not understand when we lose Chassis and not Chassis_Private.","commit_id":"372525e7aa558a777aaca5c872c99ad9dba2412c"},{"author":{"_account_id":5756,"name":"Terry Wilson","email":"twilson@redhat.com","username":"otherwiseguy"},"change_message_id":"025b5db36a4a61f78691bb73399bd31fbf1c9a7a","unresolved":false,"context_lines":[{"line_number":327,"context_line":"    def match_fn(self, event, row, old\u003dNone):"},{"line_number":328,"context_line":"        if event \u003d\u003d self.ROW_DELETE:"},{"line_number":329,"context_line":"            return True"},{"line_number":330,"context_line":"        # ROW_UPDATE: only match when chassis reference was cleared."},{"line_number":331,"context_line":"        # NOTE: we cannot rely on ``old.chassis`` still containing the"},{"line_number":332,"context_line":"        # previous Chassis UUID, because when the Chassis row is deleted"},{"line_number":333,"context_line":"        # the weak reference in Chassis_Private.chassis is cleared at the"},{"line_number":334,"context_line":"        # same time the Chassis row is removed from the IDL cache. When"},{"line_number":335,"context_line":"        # ``old.chassis`` is resolved through ``Datum.to_python()``, any"},{"line_number":336,"context_line":"        # UUID that no longer points to an existing row is dropped from"},{"line_number":337,"context_line":"        # the returned list, so ``old.chassis`` ends up empty. Instead,"},{"line_number":338,"context_line":"        # detect the clearing by checking that the ``chassis`` column was"},{"line_number":339,"context_line":"        # part of the update (``hasattr(old, \u0027chassis\u0027)``) and that the"},{"line_number":340,"context_line":"        # new value is empty."},{"line_number":341,"context_line":"        return hasattr(old, \u0027chassis\u0027) and not row.chassis"},{"line_number":342,"context_line":""},{"line_number":343,"context_line":""}],"source_content_type":"text/x-python","patch_set":24,"id":"130f10a4_febbf68e","side":"PARENT","line":340,"range":{"start_line":330,"start_character":0,"end_line":340,"end_character":29},"in_reply_to":"d390fa1f_b34b5c0d","updated":"2026-08-03 17:54:04.000000000","message":"Done\n\nThis particular case is if Chassis is manually deleted via ovsdb (e.g. `ovn-sbctl destroy Chassis ...`). Chassis_Private.chassis is cleared, and the row remains. (This would need to be done while ovn-controller was down after being killed. It is an edge case of an edge case.)","commit_id":"372525e7aa558a777aaca5c872c99ad9dba2412c"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"d3931ce576cc306ebc1b74666634276636542098","unresolved":true,"context_lines":[{"line_number":317,"context_line":"    def run(self, event, row, old):"},{"line_number":318,"context_line":"        self.driver._plugin.update_agent("},{"line_number":319,"context_line":"            neutron_context.get_admin_context(), row.name,"},{"line_number":320,"context_line":"            {\u0027agent\u0027: {\u0027heartbeat_timestamp\u0027: datetime.datetime.min}})"},{"line_number":321,"context_line":""},{"line_number":322,"context_line":""},{"line_number":323,"context_line":"class ChassisAgentWriteEvent(ChassisAgentEvent):"}],"source_content_type":"text/x-python","patch_set":24,"id":"1163068e_cea57099","line":320,"updated":"2026-07-30 14:56:03.000000000","message":"Wouldn\u0027t this cause problems with a scale in? If we delete a node, we\u0027ll remain with a stale dead agent.","commit_id":"c90d31969e3c2103d6732e6dbec9aceec6c6f9cc"},{"author":{"_account_id":5756,"name":"Terry Wilson","email":"twilson@redhat.com","username":"otherwiseguy"},"change_message_id":"204f096175e1894a9d17f8a9333c109bdd251ce6","unresolved":true,"context_lines":[{"line_number":317,"context_line":"    def run(self, event, row, old):"},{"line_number":318,"context_line":"        self.driver._plugin.update_agent("},{"line_number":319,"context_line":"            neutron_context.get_admin_context(), row.name,"},{"line_number":320,"context_line":"            {\u0027agent\u0027: {\u0027heartbeat_timestamp\u0027: datetime.datetime.min}})"},{"line_number":321,"context_line":""},{"line_number":322,"context_line":""},{"line_number":323,"context_line":"class ChassisAgentWriteEvent(ChassisAgentEvent):"}],"source_content_type":"text/x-python","patch_set":24,"id":"616a0914_b38e164d","line":320,"in_reply_to":"1163068e_cea57099","updated":"2026-08-03 16:28:16.000000000","message":"This is just how Agent API works. An agent, by definition of the Agent API, stays around until \"agent delete\" is called. The old code also did not delete agents unless \"agent delete\" was called on them, writing the \"delete_agent\" external_id when it was called.","commit_id":"c90d31969e3c2103d6732e6dbec9aceec6c6f9cc"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"2132f190fc2fbf023d3f944ec153bf4e148fcfa8","unresolved":true,"context_lines":[{"line_number":317,"context_line":"    def run(self, event, row, old):"},{"line_number":318,"context_line":"        self.driver._plugin.update_agent("},{"line_number":319,"context_line":"            neutron_context.get_admin_context(), row.name,"},{"line_number":320,"context_line":"            {\u0027agent\u0027: {\u0027heartbeat_timestamp\u0027: datetime.datetime.min}})"},{"line_number":321,"context_line":""},{"line_number":322,"context_line":""},{"line_number":323,"context_line":"class ChassisAgentWriteEvent(ChassisAgentEvent):"}],"source_content_type":"text/x-python","patch_set":24,"id":"914342ef_c2f0d8ed","line":320,"in_reply_to":"616a0914_b38e164d","updated":"2026-08-03 16:59:05.000000000","message":"With current implementation the agent stays until we delete it or restart neutron-api service and lose the cache. This will make the agent persistent across restarts (which seems a better since the API response is different based whether restarted service replied).","commit_id":"c90d31969e3c2103d6732e6dbec9aceec6c6f9cc"},{"author":{"_account_id":5756,"name":"Terry Wilson","email":"twilson@redhat.com","username":"otherwiseguy"},"change_message_id":"fefd925c360b84a836e94670b80ca0fc003775b4","unresolved":true,"context_lines":[{"line_number":317,"context_line":"    def run(self, event, row, old):"},{"line_number":318,"context_line":"        self.driver._plugin.update_agent("},{"line_number":319,"context_line":"            neutron_context.get_admin_context(), row.name,"},{"line_number":320,"context_line":"            {\u0027agent\u0027: {\u0027heartbeat_timestamp\u0027: datetime.datetime.min}})"},{"line_number":321,"context_line":""},{"line_number":322,"context_line":""},{"line_number":323,"context_line":"class ChassisAgentWriteEvent(ChassisAgentEvent):"}],"source_content_type":"text/x-python","patch_set":24,"id":"77a65dfa_dc5e77c2","line":320,"in_reply_to":"914342ef_c2f0d8ed","updated":"2026-08-03 17:24:11.000000000","message":"Yeah, the AgentCache was a terrible hack for the hash ring breaking agent api. I should have just switched to agent db then immediately. 😃)","commit_id":"c90d31969e3c2103d6732e6dbec9aceec6c6f9cc"}],"neutron/tests/functional/base.py":[{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"d3931ce576cc306ebc1b74666634276636542098","unresolved":true,"context_lines":[{"line_number":479,"context_line":"        ).execute(check_error\u003dTrue)"},{"line_number":480,"context_line":"        if wait_for_agent:"},{"line_number":481,"context_line":"            n_utils.wait_until_true("},{"line_number":482,"context_line":"                lambda: bool(directory.get_plugin().get_agents("},{"line_number":483,"context_line":"                    n_context.get_admin_context(),"},{"line_number":484,"context_line":"                    filters\u003d{\u0027host\u0027: [host], \u0027alive\u0027: [True]})),"},{"line_number":485,"context_line":"                timeout\u003d5)"}],"source_content_type":"text/x-python","patch_set":24,"id":"e8c8927b_29775606","line":482,"range":{"start_line":482,"start_character":29,"end_line":482,"end_character":51},"updated":"2026-07-30 14:56:03.000000000","message":"nit: we can get the plugin outside of the loop","commit_id":"c90d31969e3c2103d6732e6dbec9aceec6c6f9cc"},{"author":{"_account_id":5756,"name":"Terry Wilson","email":"twilson@redhat.com","username":"otherwiseguy"},"change_message_id":"025b5db36a4a61f78691bb73399bd31fbf1c9a7a","unresolved":false,"context_lines":[{"line_number":479,"context_line":"        ).execute(check_error\u003dTrue)"},{"line_number":480,"context_line":"        if wait_for_agent:"},{"line_number":481,"context_line":"            n_utils.wait_until_true("},{"line_number":482,"context_line":"                lambda: bool(directory.get_plugin().get_agents("},{"line_number":483,"context_line":"                    n_context.get_admin_context(),"},{"line_number":484,"context_line":"                    filters\u003d{\u0027host\u0027: [host], \u0027alive\u0027: [True]})),"},{"line_number":485,"context_line":"                timeout\u003d5)"}],"source_content_type":"text/x-python","patch_set":24,"id":"6a137771_faff9871","line":482,"range":{"start_line":482,"start_character":29,"end_line":482,"end_character":51},"in_reply_to":"e8c8927b_29775606","updated":"2026-08-03 17:54:04.000000000","message":"Done","commit_id":"c90d31969e3c2103d6732e6dbec9aceec6c6f9cc"}],"neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovsdb_monitor.py":[{"author":{"_account_id":5756,"name":"Terry Wilson","email":"twilson@redhat.com","username":"otherwiseguy"},"change_message_id":"8c2f9da31896b9be6e5e53359e851d43b00a6053","unresolved":false,"context_lines":[{"line_number":306,"context_line":"        self.chassis_name \u003d self.add_fake_chassis(self.FAKE_CHASSIS_HOST,"},{"line_number":307,"context_line":"                external_ids\u003d{\u0027ovn-cms-options\u0027: \u0027enable-chassis-as-gw\u0027},"},{"line_number":308,"context_line":"                name\u003dname)"},{"line_number":309,"context_line":"        #import time;time.sleep(0.1)"},{"line_number":310,"context_line":"        n_utils.wait_until_true(self._get_agent, timeout\u003d3, sleep\u003d1)"},{"line_number":311,"context_line":""},{"line_number":312,"context_line":"    def _get_agent(self):"}],"source_content_type":"text/x-python","patch_set":5,"id":"5a461195_5629b2d9","line":309,"in_reply_to":"15b1c315_83278aa9","updated":"2021-11-24 14:32:52.000000000","message":"\u003e pep8: E265 block comment should start with \u0027# \u0027\nDone","commit_id":"73d58350945d751cece9eeedda785230d496c764"}]}
