)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":38972,"name":"Esther Domfeh","display_name":"edomfeh","email":"estherdomfeh88@gmail.com","username":"edomfeh"},"change_message_id":"bcf68646dcc63b95cc69570b158287d814d1c2b8","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":4,"id":"a660ec3e_cb7acc09","updated":"2026-06-23 07:47:46.000000000","message":"recheck","commit_id":"1c016c411d8e5f21491b4311a630d1122373327e"},{"author":{"_account_id":38972,"name":"Esther Domfeh","display_name":"edomfeh","email":"estherdomfeh88@gmail.com","username":"edomfeh"},"change_message_id":"b676bff9397aac1c7b1a3170709308f4c03892d8","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"91cf6453_974c9e47","in_reply_to":"a660ec3e_cb7acc09","updated":"2026-07-08 09:56:41.000000000","message":"Done","commit_id":"1c016c411d8e5f21491b4311a630d1122373327e"}],"ironic/conductor/utils.py":[{"author":{"_account_id":24245,"name":"Harald Jensås","email":"hjensas@redhat.com","username":"harald.jensas"},"change_message_id":"643b63d3e87bfdf1a2d79cf03b0cc1aee1177e4c","unresolved":true,"context_lines":[{"line_number":1930,"context_line":"        # Use provision_updated_at as the timestamp when the node entered"},{"line_number":1931,"context_line":"        # its current state"},{"line_number":1932,"context_line":"        duration \u003d None"},{"line_number":1933,"context_line":"        provision_updated_at \u003d getattr(node, \u0027provision_updated_at\u0027, None)"},{"line_number":1934,"context_line":"        if provision_updated_at:"},{"line_number":1935,"context_line":"            try:"},{"line_number":1936,"context_line":"                now \u003d timeutils.utcnow()"}],"source_content_type":"text/x-python","patch_set":2,"id":"e5cca153_616ac93d","line":1933,"range":{"start_line":1933,"start_character":8,"end_line":1933,"end_character":74},"updated":"2026-06-18 12:20:31.000000000","message":"I don\u0027t think we need this variable? Just do `if node.provision_updated_at is not None` - nodes will always have the attribute.","commit_id":"106df54b93f9969c3f162da37526138b7009ec99"},{"author":{"_account_id":38972,"name":"Esther Domfeh","display_name":"edomfeh","email":"estherdomfeh88@gmail.com","username":"edomfeh"},"change_message_id":"e2b123884e7951445ad1b7b196adb2efc83608b3","unresolved":false,"context_lines":[{"line_number":1930,"context_line":"        # Use provision_updated_at as the timestamp when the node entered"},{"line_number":1931,"context_line":"        # its current state"},{"line_number":1932,"context_line":"        duration \u003d None"},{"line_number":1933,"context_line":"        provision_updated_at \u003d getattr(node, \u0027provision_updated_at\u0027, None)"},{"line_number":1934,"context_line":"        if provision_updated_at:"},{"line_number":1935,"context_line":"            try:"},{"line_number":1936,"context_line":"                now \u003d timeutils.utcnow()"}],"source_content_type":"text/x-python","patch_set":2,"id":"ce4d1929_1ea1fdc6","line":1933,"range":{"start_line":1933,"start_character":8,"end_line":1933,"end_character":74},"in_reply_to":"e5cca153_616ac93d","updated":"2026-06-18 17:12:57.000000000","message":"Done","commit_id":"106df54b93f9969c3f162da37526138b7009ec99"},{"author":{"_account_id":24245,"name":"Harald Jensås","email":"hjensas@redhat.com","username":"harald.jensas"},"change_message_id":"643b63d3e87bfdf1a2d79cf03b0cc1aee1177e4c","unresolved":true,"context_lines":[{"line_number":1932,"context_line":"        duration \u003d None"},{"line_number":1933,"context_line":"        provision_updated_at \u003d getattr(node, \u0027provision_updated_at\u0027, None)"},{"line_number":1934,"context_line":"        if provision_updated_at:"},{"line_number":1935,"context_line":"            try:"},{"line_number":1936,"context_line":"                now \u003d timeutils.utcnow()"},{"line_number":1937,"context_line":"                time_spent \u003d now - node.provision_updated_at"},{"line_number":1938,"context_line":"                duration \u003d int(time_spent.total_seconds())"}],"source_content_type":"text/x-python","patch_set":2,"id":"b8437eb3_f29f456f","line":1935,"range":{"start_line":1935,"start_character":0,"end_line":1935,"end_character":2},"updated":"2026-06-18 12:20:31.000000000","message":"I think this is simple enough to not have a try except block. If we want to keep it for defense, change it to catch TypeError only.","commit_id":"106df54b93f9969c3f162da37526138b7009ec99"},{"author":{"_account_id":38972,"name":"Esther Domfeh","display_name":"edomfeh","email":"estherdomfeh88@gmail.com","username":"edomfeh"},"change_message_id":"e2b123884e7951445ad1b7b196adb2efc83608b3","unresolved":false,"context_lines":[{"line_number":1932,"context_line":"        duration \u003d None"},{"line_number":1933,"context_line":"        provision_updated_at \u003d getattr(node, \u0027provision_updated_at\u0027, None)"},{"line_number":1934,"context_line":"        if provision_updated_at:"},{"line_number":1935,"context_line":"            try:"},{"line_number":1936,"context_line":"                now \u003d timeutils.utcnow()"},{"line_number":1937,"context_line":"                time_spent \u003d now - node.provision_updated_at"},{"line_number":1938,"context_line":"                duration \u003d int(time_spent.total_seconds())"}],"source_content_type":"text/x-python","patch_set":2,"id":"a8d6905c_ad7c51ac","line":1935,"range":{"start_line":1935,"start_character":0,"end_line":1935,"end_character":2},"in_reply_to":"b8437eb3_f29f456f","updated":"2026-06-18 17:12:57.000000000","message":"Done","commit_id":"106df54b93f9969c3f162da37526138b7009ec99"},{"author":{"_account_id":24245,"name":"Harald Jensås","email":"hjensas@redhat.com","username":"harald.jensas"},"change_message_id":"643b63d3e87bfdf1a2d79cf03b0cc1aee1177e4c","unresolved":true,"context_lines":[{"line_number":1933,"context_line":"        provision_updated_at \u003d getattr(node, \u0027provision_updated_at\u0027, None)"},{"line_number":1934,"context_line":"        if provision_updated_at:"},{"line_number":1935,"context_line":"            try:"},{"line_number":1936,"context_line":"                now \u003d timeutils.utcnow()"},{"line_number":1937,"context_line":"                time_spent \u003d now - node.provision_updated_at"},{"line_number":1938,"context_line":"                duration \u003d int(time_spent.total_seconds())"},{"line_number":1939,"context_line":"            except Exception:"},{"line_number":1940,"context_line":"                # If something goes wrong with the calculation, we just log it"}],"source_content_type":"text/x-python","patch_set":2,"id":"6d4706cf_67b8c588","line":1937,"range":{"start_line":1936,"start_character":16,"end_line":1937,"end_character":60},"updated":"2026-06-18 12:20:31.000000000","message":"If you look at the CI logs, this always fails:\nJun 16 10:29:12.522579 np7a560a5530f74 ironic-conductor[90617]: DEBUG ironic.conductor.utils [None req-90db3e75-4dfa-460e-b94b-337762584bb8 None None] Failed to calculate duration for node c716c0fc-a98b-466b-b432-66b3f4f2f2bc {{(pid\u003d90617) node_history_record /opt/stack/ironic/ironic/conductor/utils.py:1942}}\n\nRef: https://ca32b7770d8fc21859b8-0343763e072aec8a44b36b196f4e6ba5.ssl.cf1.rackcdn.com/openstack/ff73fd07de134b5f9b92d26d3f864c45/controller/logs/screen-ir-cond.txt\n\nMost likely the time calculation raises TypeError because node.provision_updated_at is tzinfo aware.\n\n```\n    now \u003d timeutils.utcnow(with_timezone\u003dTrue)\n    time_spent \u003d now - node.provision_updated_at\n```\n\nor\n\n```\nupdated_at \u003d timeutils.normalize_time(node.provision_updated_at)\nnow \u003d timeutils.utcnow()\ntime_spent \u003d now - updated_at\n```","commit_id":"106df54b93f9969c3f162da37526138b7009ec99"},{"author":{"_account_id":38972,"name":"Esther Domfeh","display_name":"edomfeh","email":"estherdomfeh88@gmail.com","username":"edomfeh"},"change_message_id":"e2b123884e7951445ad1b7b196adb2efc83608b3","unresolved":false,"context_lines":[{"line_number":1933,"context_line":"        provision_updated_at \u003d getattr(node, \u0027provision_updated_at\u0027, None)"},{"line_number":1934,"context_line":"        if provision_updated_at:"},{"line_number":1935,"context_line":"            try:"},{"line_number":1936,"context_line":"                now \u003d timeutils.utcnow()"},{"line_number":1937,"context_line":"                time_spent \u003d now - node.provision_updated_at"},{"line_number":1938,"context_line":"                duration \u003d int(time_spent.total_seconds())"},{"line_number":1939,"context_line":"            except Exception:"},{"line_number":1940,"context_line":"                # If something goes wrong with the calculation, we just log it"}],"source_content_type":"text/x-python","patch_set":2,"id":"3dd7af11_cb2ffed6","line":1937,"range":{"start_line":1936,"start_character":16,"end_line":1937,"end_character":60},"in_reply_to":"6d4706cf_67b8c588","updated":"2026-06-18 17:12:57.000000000","message":"Thank you for the feedback, Harald. I narrowed the scope down to catch TypeError only,keeping the logic strictly defensive as you suggested.","commit_id":"106df54b93f9969c3f162da37526138b7009ec99"},{"author":{"_account_id":24245,"name":"Harald Jensås","email":"hjensas@redhat.com","username":"harald.jensas"},"change_message_id":"643b63d3e87bfdf1a2d79cf03b0cc1aee1177e4c","unresolved":true,"context_lines":[{"line_number":1953,"context_line":"            severity\u003derror and \"ERROR\" or \"INFO\","},{"line_number":1954,"context_line":"            event\u003devent,"},{"line_number":1955,"context_line":"            event_type\u003devent_type or \"UNKNOWN\","},{"line_number":1956,"context_line":"            # Track the node\u0027s provision state when this event happened"},{"line_number":1957,"context_line":"            state\u003dnode.provision_state,"},{"line_number":1958,"context_line":"            # Track what state we were trying to get to"},{"line_number":1959,"context_line":"            target_provision_state\u003dnode.target_provision_state,"},{"line_number":1960,"context_line":"            # How many seconds we spent in the previous state"},{"line_number":1961,"context_line":"            # (if we could calculate it)"},{"line_number":1962,"context_line":"            duration_seconds\u003dduration"},{"line_number":1963,"context_line":"            ).create()"},{"line_number":1964,"context_line":""},{"line_number":1965,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"7d733360_fc42ca6f","line":1962,"range":{"start_line":1956,"start_character":0,"end_line":1962,"end_character":37},"updated":"2026-06-18 12:20:31.000000000","message":"nit, I think we could reduce the comments a bit - the code is quite clear with good variable names.","commit_id":"106df54b93f9969c3f162da37526138b7009ec99"},{"author":{"_account_id":38972,"name":"Esther Domfeh","display_name":"edomfeh","email":"estherdomfeh88@gmail.com","username":"edomfeh"},"change_message_id":"e2b123884e7951445ad1b7b196adb2efc83608b3","unresolved":false,"context_lines":[{"line_number":1953,"context_line":"            severity\u003derror and \"ERROR\" or \"INFO\","},{"line_number":1954,"context_line":"            event\u003devent,"},{"line_number":1955,"context_line":"            event_type\u003devent_type or \"UNKNOWN\","},{"line_number":1956,"context_line":"            # Track the node\u0027s provision state when this event happened"},{"line_number":1957,"context_line":"            state\u003dnode.provision_state,"},{"line_number":1958,"context_line":"            # Track what state we were trying to get to"},{"line_number":1959,"context_line":"            target_provision_state\u003dnode.target_provision_state,"},{"line_number":1960,"context_line":"            # How many seconds we spent in the previous state"},{"line_number":1961,"context_line":"            # (if we could calculate it)"},{"line_number":1962,"context_line":"            duration_seconds\u003dduration"},{"line_number":1963,"context_line":"            ).create()"},{"line_number":1964,"context_line":""},{"line_number":1965,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"34624f79_2fa8a33c","line":1962,"range":{"start_line":1956,"start_character":0,"end_line":1962,"end_character":37},"in_reply_to":"7d733360_fc42ca6f","updated":"2026-06-18 17:12:57.000000000","message":"Done","commit_id":"106df54b93f9969c3f162da37526138b7009ec99"}]}
