)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":32177,"name":"Jacob Anders","email":"jacob-anders-dev@proton.me","username":"janders"},"change_message_id":"361048a5fc38d46a997b9fc448568fc1d8c2ad35","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"35ce587d_bb1ac09d","updated":"2025-07-14 04:35:57.000000000","message":"Thank you for your review and invaluable pointers. Uploading next revision for discussion. Hopefully in few more iterations we\u0027ll be able to pin it down.","commit_id":"43968fe8fee9ec691e6b72ac34cfab71d867e134"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"acb84cfdc7794c74810f2f4e567274c782701980","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"e37141ce_49275a0f","updated":"2025-07-16 16:04:12.000000000","message":"Great progress! A few notes inline.","commit_id":"2824eb75f0f42d0edc2b7241458d494ed0b167b1"},{"author":{"_account_id":32177,"name":"Jacob Anders","email":"jacob-anders-dev@proton.me","username":"janders"},"change_message_id":"5018274f5b8b671e6b555e695ad059644ad74325","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"40b60472_497aab33","updated":"2025-07-18 01:36:21.000000000","message":"Thank you for your review, Dmitry, uploading revised version including most of your feedback (some questions outstanding).","commit_id":"2824eb75f0f42d0edc2b7241458d494ed0b167b1"},{"author":{"_account_id":32177,"name":"Jacob Anders","email":"jacob-anders-dev@proton.me","username":"janders"},"change_message_id":"5018274f5b8b671e6b555e695ad059644ad74325","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"493b7017_104f72b0","in_reply_to":"e37141ce_49275a0f","updated":"2025-07-18 01:36:21.000000000","message":"Thank you for your feedback and invaluable guidance, Dmitry, much appreciated","commit_id":"2824eb75f0f42d0edc2b7241458d494ed0b167b1"},{"author":{"_account_id":32177,"name":"Jacob Anders","email":"jacob-anders-dev@proton.me","username":"janders"},"change_message_id":"2586587065bdaa3ca938487fdf42aaf255caf8d8","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"a1048145_3b5bb3d4","updated":"2025-07-18 01:38:16.000000000","message":"likely more corrections needed and unit tests certainly need attention so setting W-1","commit_id":"ad0e0fb4a42aedf11b7ae92258aaacda93655584"},{"author":{"_account_id":32177,"name":"Jacob Anders","email":"jacob-anders-dev@proton.me","username":"janders"},"change_message_id":"67eb8ae64ef1f2c484d1e7ab397c331c5501947e","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":6,"id":"ced1377b_91a85a02","updated":"2025-07-21 22:21:46.000000000","message":"(CI timeout)","commit_id":"33ffdb4eeaaad15676ea47d1551ddc50f460d034"},{"author":{"_account_id":32177,"name":"Jacob Anders","email":"jacob-anders-dev@proton.me","username":"janders"},"change_message_id":"2cb446fd9837a3b92864dbc0bd6569b0b6aa4570","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":6,"id":"7aa8ee67_41ca628f","updated":"2025-07-22 02:44:48.000000000","message":"Thank you for your review Iury, couple comments in-line.","commit_id":"33ffdb4eeaaad15676ea47d1551ddc50f460d034"},{"author":{"_account_id":32177,"name":"Jacob Anders","email":"jacob-anders-dev@proton.me","username":"janders"},"change_message_id":"b4cee3400a55bbca3c00fc2a13d03c9415134c36","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":6,"id":"cb91da97_6f21501d","updated":"2025-07-21 22:21:36.000000000","message":"recheck","commit_id":"33ffdb4eeaaad15676ea47d1551ddc50f460d034"},{"author":{"_account_id":32177,"name":"Jacob Anders","email":"jacob-anders-dev@proton.me","username":"janders"},"change_message_id":"87f732c034434eafcaccf000424582a60a4bdbac","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":7,"id":"24e38194_6972e8c9","updated":"2025-07-23 13:06:56.000000000","message":"Thank you for another review, Dmitry. Uploading a revised patchset, please let me know what you think","commit_id":"948a43c5b65b96792e98828b920a45bfeac62945"},{"author":{"_account_id":32177,"name":"Jacob Anders","email":"jacob-anders-dev@proton.me","username":"janders"},"change_message_id":"046cc38202551da420d958e28b085f52bed27409","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":8,"id":"65ab70a7_346e26f8","updated":"2025-07-24 13:13:12.000000000","message":"Thank you for another review Dmitry. Comments inline, pushing new revision.","commit_id":"d8ee0e37b1ca9e0193213ce709aa089e977ff24c"},{"author":{"_account_id":32177,"name":"Jacob Anders","email":"jacob-anders-dev@proton.me","username":"janders"},"change_message_id":"f9ea11d2c31194c3513c48f85f353afca6c94ff5","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":8,"id":"2a99cb04_0885966d","updated":"2025-07-24 04:54:54.000000000","message":"recheck","commit_id":"d8ee0e37b1ca9e0193213ce709aa089e977ff24c"},{"author":{"_account_id":32177,"name":"Jacob Anders","email":"jacob-anders-dev@proton.me","username":"janders"},"change_message_id":"8d47f32c56bf01df3cf2a0dab5a85d13c163bcb8","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":8,"id":"4075318f_1bdda77c","updated":"2025-07-24 04:55:07.000000000","message":"tests passing locally, seems like an intermittent CI issue","commit_id":"d8ee0e37b1ca9e0193213ce709aa089e977ff24c"},{"author":{"_account_id":15519,"name":"Iury Gregory Melo Ferreira","display_name":"Iury Gregory","email":"iurygregory@gmail.com","username":"iurygregory"},"change_message_id":"05b27034836b7123d933d6fc26eed85502a2e934","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":9,"id":"946bcc42_632f0087","updated":"2025-07-25 01:00:30.000000000","message":"CI is a bit unhappy in the snmp job (since yesterday all runs are failing)","commit_id":"1b2c01185c7907a1d17c4d90cf3bcd73fe345658"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"f2dd0cd1238c1b38f18b41e11ddb2830f30ddee9","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":9,"id":"c1705a3a_be5145b6","updated":"2025-07-24 16:25:35.000000000","message":"LGTM, please consider follow-up with a unit test update (see inline).","commit_id":"1b2c01185c7907a1d17c4d90cf3bcd73fe345658"},{"author":{"_account_id":32177,"name":"Jacob Anders","email":"jacob-anders-dev@proton.me","username":"janders"},"change_message_id":"3fdd757f58c477e63d47ef3d82e4e0bf34d6e808","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":9,"id":"2a38e5ab_dbcca2f2","updated":"2025-07-25 05:16:18.000000000","message":"recheck","commit_id":"1b2c01185c7907a1d17c4d90cf3bcd73fe345658"},{"author":{"_account_id":23851,"name":"Riccardo Pittau","email":"elfosardo@gmail.com","username":"elfosardo"},"change_message_id":"0df87fc982629de1d1d2c3e1e558d6f1ebc330e1","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":9,"id":"ed9e8330_ba21390f","updated":"2025-07-28 11:25:47.000000000","message":"recheck","commit_id":"1b2c01185c7907a1d17c4d90cf3bcd73fe345658"},{"author":{"_account_id":15519,"name":"Iury Gregory Melo Ferreira","display_name":"Iury Gregory","email":"iurygregory@gmail.com","username":"iurygregory"},"change_message_id":"358702e5671cd7854c66563bb7c68d3ab09910dc","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":9,"id":"32aa78c6_5d2ec6d0","updated":"2025-07-24 23:01:30.000000000","message":"recheck  - I agree with the follow-up, let\u0027s see if CI is better now","commit_id":"1b2c01185c7907a1d17c4d90cf3bcd73fe345658"},{"author":{"_account_id":15519,"name":"Iury Gregory Melo Ferreira","display_name":"Iury Gregory","email":"iurygregory@gmail.com","username":"iurygregory"},"change_message_id":"761334901fe10b7d5be45c59b7241635d7f8b895","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":9,"id":"0159450d_e81110a7","updated":"2025-07-27 01:55:37.000000000","message":"recheck ci should be better now","commit_id":"1b2c01185c7907a1d17c4d90cf3bcd73fe345658"},{"author":{"_account_id":15519,"name":"Iury Gregory Melo Ferreira","display_name":"Iury Gregory","email":"iurygregory@gmail.com","username":"iurygregory"},"change_message_id":"e5beb3c2de2d9be104ea4ba74931626114fed6f5","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":9,"id":"661c4bf9_ca4e0ba4","updated":"2025-07-27 12:29:49.000000000","message":"recheck metal3 timed out","commit_id":"1b2c01185c7907a1d17c4d90cf3bcd73fe345658"},{"author":{"_account_id":15519,"name":"Iury Gregory Melo Ferreira","display_name":"Iury Gregory","email":"iurygregory@gmail.com","username":"iurygregory"},"change_message_id":"8fc332cc87369d6fb1ba45f53f73022625102dda","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":9,"id":"9296993e_e5d8b92d","updated":"2025-07-27 14:58:34.000000000","message":"recheck post failure","commit_id":"1b2c01185c7907a1d17c4d90cf3bcd73fe345658"}],"ironic/conductor/servicing.py":[{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"f7992c8c279a70b3355548dbda5ef26fc4cb8eba","unresolved":true,"context_lines":[{"line_number":56,"context_line":""},{"line_number":57,"context_line":"        else:"},{"line_number":58,"context_line":"            skip_reboot_to_ipa \u003d task.node.driver_internal_info.get("},{"line_number":59,"context_line":"                \u0027skip_reboot_to_ipa\u0027, False)"},{"line_number":60,"context_line":"            LOG.debug(\u0027janders-debug: _can_skip_ipa detected \u0027"},{"line_number":61,"context_line":"                      \u0027driver_internal_info.skip_reboot_to_ipa is \u0027"},{"line_number":62,"context_line":"                      \u0027%s %s\u0027, skip_reboot_to_ipa, task.node.uuid)"}],"source_content_type":"text/x-python","patch_set":1,"id":"b596b224_ff9b2ef0","line":59,"updated":"2025-07-08 12:43:24.000000000","message":"I don\u0027t see why you need this variable.","commit_id":"43968fe8fee9ec691e6b72ac34cfab71d867e134"},{"author":{"_account_id":32177,"name":"Jacob Anders","email":"jacob-anders-dev@proton.me","username":"janders"},"change_message_id":"361048a5fc38d46a997b9fc448568fc1d8c2ad35","unresolved":false,"context_lines":[{"line_number":56,"context_line":""},{"line_number":57,"context_line":"        else:"},{"line_number":58,"context_line":"            skip_reboot_to_ipa \u003d task.node.driver_internal_info.get("},{"line_number":59,"context_line":"                \u0027skip_reboot_to_ipa\u0027, False)"},{"line_number":60,"context_line":"            LOG.debug(\u0027janders-debug: _can_skip_ipa detected \u0027"},{"line_number":61,"context_line":"                      \u0027driver_internal_info.skip_reboot_to_ipa is \u0027"},{"line_number":62,"context_line":"                      \u0027%s %s\u0027, skip_reboot_to_ipa, task.node.uuid)"}],"source_content_type":"text/x-python","patch_set":1,"id":"b98dd742_9b929363","line":59,"in_reply_to":"b596b224_ff9b2ef0","updated":"2025-07-14 04:35:57.000000000","message":"with the approach we discussed, I think this entire helper function is no longer needed, removing.","commit_id":"43968fe8fee9ec691e6b72ac34cfab71d867e134"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"f7992c8c279a70b3355548dbda5ef26fc4cb8eba","unresolved":true,"context_lines":[{"line_number":95,"context_line":""},{"line_number":96,"context_line":"    # Allow the deploy driver to set up the ramdisk again (necessary for IPA)"},{"line_number":97,"context_line":"    try:"},{"line_number":98,"context_line":"        if not disable_ramdisk and not _can_skip_ipa(task, service_steps):"},{"line_number":99,"context_line":"            LOG.info(\u0027janders-debug: in-band service needed for node, \u0027"},{"line_number":100,"context_line":"                     \u0027disable_ramdisk %s node %s\u0027, disable_ramdisk, node.uuid)"},{"line_number":101,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"d75f07a2_691460c8","line":98,"updated":"2025-07-08 12:43:24.000000000","message":"These service_steps are provided by a user. They never ever have requires_ramdisk.","commit_id":"43968fe8fee9ec691e6b72ac34cfab71d867e134"},{"author":{"_account_id":32177,"name":"Jacob Anders","email":"jacob-anders-dev@proton.me","username":"janders"},"change_message_id":"361048a5fc38d46a997b9fc448568fc1d8c2ad35","unresolved":false,"context_lines":[{"line_number":95,"context_line":""},{"line_number":96,"context_line":"    # Allow the deploy driver to set up the ramdisk again (necessary for IPA)"},{"line_number":97,"context_line":"    try:"},{"line_number":98,"context_line":"        if not disable_ramdisk and not _can_skip_ipa(task, service_steps):"},{"line_number":99,"context_line":"            LOG.info(\u0027janders-debug: in-band service needed for node, \u0027"},{"line_number":100,"context_line":"                     \u0027disable_ramdisk %s node %s\u0027, disable_ramdisk, node.uuid)"},{"line_number":101,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"3e63c7db_30018d98","line":98,"in_reply_to":"d75f07a2_691460c8","updated":"2025-07-14 04:35:57.000000000","message":"Thank you for pointing this out, will check for requires_ramdisk later in the function.","commit_id":"43968fe8fee9ec691e6b72ac34cfab71d867e134"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"f7992c8c279a70b3355548dbda5ef26fc4cb8eba","unresolved":true,"context_lines":[{"line_number":119,"context_line":"        return"},{"line_number":120,"context_line":"    try:"},{"line_number":121,"context_line":"        conductor_steps.set_node_service_steps("},{"line_number":122,"context_line":"            task, disable_ramdisk\u003ddisable_ramdisk)"},{"line_number":123,"context_line":"    except Exception as e:"},{"line_number":124,"context_line":"        # Catch all exceptions and follow the error handling"},{"line_number":125,"context_line":"        # path so things are cleaned up properly."}],"source_content_type":"text/x-python","patch_set":1,"id":"9fa393c6_456a27b5","line":122,"updated":"2025-07-08 12:43:24.000000000","message":"This is where we can the final list of steps to run. It is only now that we have requires_ramdisk on them.\n\nThe catch: some steps may be only possible to satisfy after booting IPA, so this call may raise an exception without it.\n\nSo we may want to reorganize the function. First, we try to compose the list of steps by making this call. If it fails with the specific exception, prepare IPA, wait for it to boot and try again. If it does not, we can make a judgement on whether we need IPA by inspecting the finalized list of steps. If any do not have requires_ramdisk\u003dFalse, boot IPA.","commit_id":"43968fe8fee9ec691e6b72ac34cfab71d867e134"},{"author":{"_account_id":32177,"name":"Jacob Anders","email":"jacob-anders-dev@proton.me","username":"janders"},"change_message_id":"81765834acea3b3a7f54561863cdd57e8dac8084","unresolved":false,"context_lines":[{"line_number":119,"context_line":"        return"},{"line_number":120,"context_line":"    try:"},{"line_number":121,"context_line":"        conductor_steps.set_node_service_steps("},{"line_number":122,"context_line":"            task, disable_ramdisk\u003ddisable_ramdisk)"},{"line_number":123,"context_line":"    except Exception as e:"},{"line_number":124,"context_line":"        # Catch all exceptions and follow the error handling"},{"line_number":125,"context_line":"        # path so things are cleaned up properly."}],"source_content_type":"text/x-python","patch_set":1,"id":"73d16786_d9c9ef86","line":122,"in_reply_to":"8f7321ee_f1ca9de0","updated":"2025-07-18 08:49:52.000000000","message":"OK I think the current iteration addresses this (we\u0027ll confirm through tests)","commit_id":"43968fe8fee9ec691e6b72ac34cfab71d867e134"},{"author":{"_account_id":32177,"name":"Jacob Anders","email":"jacob-anders-dev@proton.me","username":"janders"},"change_message_id":"361048a5fc38d46a997b9fc448568fc1d8c2ad35","unresolved":true,"context_lines":[{"line_number":119,"context_line":"        return"},{"line_number":120,"context_line":"    try:"},{"line_number":121,"context_line":"        conductor_steps.set_node_service_steps("},{"line_number":122,"context_line":"            task, disable_ramdisk\u003ddisable_ramdisk)"},{"line_number":123,"context_line":"    except Exception as e:"},{"line_number":124,"context_line":"        # Catch all exceptions and follow the error handling"},{"line_number":125,"context_line":"        # path so things are cleaned up properly."}],"source_content_type":"text/x-python","patch_set":1,"id":"8f7321ee_f1ca9de0","line":122,"in_reply_to":"9fa393c6_456a27b5","updated":"2025-07-14 04:35:57.000000000","message":"Thank you for your comments and guidance. I have a follow-up question:\n\n \n\u003e So we may want to reorganize the function. First, we try to compose the list of steps by making this call. If it fails with the specific exception, prepare IPA, wait for it to boot and try again. \n\n^ let\u0027s call this \"scenario 1\"\n\nIf it does not, we can make a judgement on whether we need IPA by inspecting the finalized list of steps. If any do not have requires_ramdisk\u003dFalse, boot IPA.\n\n^ and let\u0027s call this \"scenario 2\"\n\nDo scenario 1 and scenario 2 share the code path or do I need to treat them differently? For now I assumed the answer is yes, but I feel that in scenario 1 I need to wait for ramdisk and call conductor_steps.set_node_service_steps() again.\n\nUploading the next iteration of the patch, let\u0027s iterate further. This way I hopefully resolve the easier parts and we can focus on the harder parts.","commit_id":"43968fe8fee9ec691e6b72ac34cfab71d867e134"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"acb84cfdc7794c74810f2f4e567274c782701980","unresolved":true,"context_lines":[{"line_number":60,"context_line":"    try:"},{"line_number":61,"context_line":"        conductor_steps.set_node_service_steps("},{"line_number":62,"context_line":"            task, disable_ramdisk\u003ddisable_ramdisk)"},{"line_number":63,"context_line":"    except exception.NodeServicingFailure:"},{"line_number":64,"context_line":"        LOG.warning(\u0027out of band service failed for node \u0027"},{"line_number":65,"context_line":"                    \u0027%s\u0027, node.uuid,"},{"line_number":66,"context_line":"                    \u0027retrying in band servicing\u0027)"}],"source_content_type":"text/x-python","patch_set":2,"id":"d887acb8_edb5b4d2","line":63,"updated":"2025-07-16 16:04:12.000000000","message":"_validate_user_steps raises InvalidParameterValue","commit_id":"2824eb75f0f42d0edc2b7241458d494ed0b167b1"},{"author":{"_account_id":32177,"name":"Jacob Anders","email":"jacob-anders-dev@proton.me","username":"janders"},"change_message_id":"5018274f5b8b671e6b555e695ad059644ad74325","unresolved":false,"context_lines":[{"line_number":60,"context_line":"    try:"},{"line_number":61,"context_line":"        conductor_steps.set_node_service_steps("},{"line_number":62,"context_line":"            task, disable_ramdisk\u003ddisable_ramdisk)"},{"line_number":63,"context_line":"    except exception.NodeServicingFailure:"},{"line_number":64,"context_line":"        LOG.warning(\u0027out of band service failed for node \u0027"},{"line_number":65,"context_line":"                    \u0027%s\u0027, node.uuid,"},{"line_number":66,"context_line":"                    \u0027retrying in band servicing\u0027)"}],"source_content_type":"text/x-python","patch_set":2,"id":"c598aa23_2571419e","line":63,"in_reply_to":"d887acb8_edb5b4d2","updated":"2025-07-18 01:36:21.000000000","message":"Done","commit_id":"2824eb75f0f42d0edc2b7241458d494ed0b167b1"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"acb84cfdc7794c74810f2f4e567274c782701980","unresolved":true,"context_lines":[{"line_number":61,"context_line":"        conductor_steps.set_node_service_steps("},{"line_number":62,"context_line":"            task, disable_ramdisk\u003ddisable_ramdisk)"},{"line_number":63,"context_line":"    except exception.NodeServicingFailure:"},{"line_number":64,"context_line":"        LOG.warning(\u0027out of band service failed for node \u0027"},{"line_number":65,"context_line":"                    \u0027%s\u0027, node.uuid,"},{"line_number":66,"context_line":"                    \u0027retrying in band servicing\u0027)"},{"line_number":67,"context_line":"        # FIXME(janders): this is to avoid duplicating code, helper"}],"source_content_type":"text/x-python","patch_set":2,"id":"19263c3e_8604bce2","line":64,"updated":"2025-07-16 16:04:12.000000000","message":"This is misleading, we haven\u0027t tried servicing itself. The message should be referring to composing the list of steps. And should have the DEBUG level for now.","commit_id":"2824eb75f0f42d0edc2b7241458d494ed0b167b1"},{"author":{"_account_id":32177,"name":"Jacob Anders","email":"jacob-anders-dev@proton.me","username":"janders"},"change_message_id":"5018274f5b8b671e6b555e695ad059644ad74325","unresolved":false,"context_lines":[{"line_number":61,"context_line":"        conductor_steps.set_node_service_steps("},{"line_number":62,"context_line":"            task, disable_ramdisk\u003ddisable_ramdisk)"},{"line_number":63,"context_line":"    except exception.NodeServicingFailure:"},{"line_number":64,"context_line":"        LOG.warning(\u0027out of band service failed for node \u0027"},{"line_number":65,"context_line":"                    \u0027%s\u0027, node.uuid,"},{"line_number":66,"context_line":"                    \u0027retrying in band servicing\u0027)"},{"line_number":67,"context_line":"        # FIXME(janders): this is to avoid duplicating code, helper"}],"source_content_type":"text/x-python","patch_set":2,"id":"e38797e3_afdfc77d","line":64,"in_reply_to":"19263c3e_8604bce2","updated":"2025-07-18 01:36:21.000000000","message":"Done","commit_id":"2824eb75f0f42d0edc2b7241458d494ed0b167b1"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"acb84cfdc7794c74810f2f4e567274c782701980","unresolved":true,"context_lines":[{"line_number":63,"context_line":"    except exception.NodeServicingFailure:"},{"line_number":64,"context_line":"        LOG.warning(\u0027out of band service failed for node \u0027"},{"line_number":65,"context_line":"                    \u0027%s\u0027, node.uuid,"},{"line_number":66,"context_line":"                    \u0027retrying in band servicing\u0027)"},{"line_number":67,"context_line":"        # FIXME(janders): this is to avoid duplicating code, helper"},{"line_number":68,"context_line":"        # may be needed instead"},{"line_number":69,"context_line":"        # FIXME(janders): ensure this will ensure retry, not just"}],"source_content_type":"text/x-python","patch_set":2,"id":"ceb956ca_16e563f8","line":66,"updated":"2025-07-16 16:04:12.000000000","message":"Incorrect formatting (the arguments are not concatenated)","commit_id":"2824eb75f0f42d0edc2b7241458d494ed0b167b1"},{"author":{"_account_id":32177,"name":"Jacob Anders","email":"jacob-anders-dev@proton.me","username":"janders"},"change_message_id":"5018274f5b8b671e6b555e695ad059644ad74325","unresolved":false,"context_lines":[{"line_number":63,"context_line":"    except exception.NodeServicingFailure:"},{"line_number":64,"context_line":"        LOG.warning(\u0027out of band service failed for node \u0027"},{"line_number":65,"context_line":"                    \u0027%s\u0027, node.uuid,"},{"line_number":66,"context_line":"                    \u0027retrying in band servicing\u0027)"},{"line_number":67,"context_line":"        # FIXME(janders): this is to avoid duplicating code, helper"},{"line_number":68,"context_line":"        # may be needed instead"},{"line_number":69,"context_line":"        # FIXME(janders): ensure this will ensure retry, not just"}],"source_content_type":"text/x-python","patch_set":2,"id":"f49ded28_630ae9a2","line":66,"in_reply_to":"ceb956ca_16e563f8","updated":"2025-07-18 01:36:21.000000000","message":"Done","commit_id":"2824eb75f0f42d0edc2b7241458d494ed0b167b1"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"acb84cfdc7794c74810f2f4e567274c782701980","unresolved":true,"context_lines":[{"line_number":67,"context_line":"        # FIXME(janders): this is to avoid duplicating code, helper"},{"line_number":68,"context_line":"        # may be needed instead"},{"line_number":69,"context_line":"        # FIXME(janders): ensure this will ensure retry, not just"},{"line_number":70,"context_line":"        # reboot into IPA (which may be happening now)"},{"line_number":71,"context_line":"        # as per Dmitry\u0027s comment"},{"line_number":72,"context_line":"        # https://review.opendev.org/c/openstack/ironic/+/954311/"},{"line_number":73,"context_line":"        # comment/9fa393c6_456a27b5/"}],"source_content_type":"text/x-python","patch_set":2,"id":"597e5cd9_2df75554","line":70,"updated":"2025-07-16 16:04:12.000000000","message":"set_node_service_steps should be and indeed is called in agent_base\u0027s _heartbeat_service_wait","commit_id":"2824eb75f0f42d0edc2b7241458d494ed0b167b1"},{"author":{"_account_id":32177,"name":"Jacob Anders","email":"jacob-anders-dev@proton.me","username":"janders"},"change_message_id":"5018274f5b8b671e6b555e695ad059644ad74325","unresolved":false,"context_lines":[{"line_number":67,"context_line":"        # FIXME(janders): this is to avoid duplicating code, helper"},{"line_number":68,"context_line":"        # may be needed instead"},{"line_number":69,"context_line":"        # FIXME(janders): ensure this will ensure retry, not just"},{"line_number":70,"context_line":"        # reboot into IPA (which may be happening now)"},{"line_number":71,"context_line":"        # as per Dmitry\u0027s comment"},{"line_number":72,"context_line":"        # https://review.opendev.org/c/openstack/ironic/+/954311/"},{"line_number":73,"context_line":"        # comment/9fa393c6_456a27b5/"}],"source_content_type":"text/x-python","patch_set":2,"id":"3cef985c_e87acdab","line":70,"in_reply_to":"597e5cd9_2df75554","updated":"2025-07-18 01:36:21.000000000","message":"OK I think this should work, because InvalidParameterValue will trigger setting ramdisk_needed and trigger prepare_service() and hence running IPA and traversing the codepath you pointed to. Will keep an eye on this during testing.","commit_id":"2824eb75f0f42d0edc2b7241458d494ed0b167b1"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"acb84cfdc7794c74810f2f4e567274c782701980","unresolved":true,"context_lines":[{"line_number":71,"context_line":"        # as per Dmitry\u0027s comment"},{"line_number":72,"context_line":"        # https://review.opendev.org/c/openstack/ironic/+/954311/"},{"line_number":73,"context_line":"        # comment/9fa393c6_456a27b5/"},{"line_number":74,"context_line":"        ramdisk_needed \u003d True"},{"line_number":75,"context_line":""},{"line_number":76,"context_line":"    except Exception as e:"},{"line_number":77,"context_line":"        msg \u003d (_(\u0027Cannot service node %(node)s: %(msg)s\u0027)"}],"source_content_type":"text/x-python","patch_set":2,"id":"6e271805_13b44623","line":74,"updated":"2025-07-16 16:04:12.000000000","message":"Re-raise here if disable_ramdisk is True: there will be no new steps.","commit_id":"2824eb75f0f42d0edc2b7241458d494ed0b167b1"},{"author":{"_account_id":32177,"name":"Jacob Anders","email":"jacob-anders-dev@proton.me","username":"janders"},"change_message_id":"5018274f5b8b671e6b555e695ad059644ad74325","unresolved":false,"context_lines":[{"line_number":71,"context_line":"        # as per Dmitry\u0027s comment"},{"line_number":72,"context_line":"        # https://review.opendev.org/c/openstack/ironic/+/954311/"},{"line_number":73,"context_line":"        # comment/9fa393c6_456a27b5/"},{"line_number":74,"context_line":"        ramdisk_needed \u003d True"},{"line_number":75,"context_line":""},{"line_number":76,"context_line":"    except Exception as e:"},{"line_number":77,"context_line":"        msg \u003d (_(\u0027Cannot service node %(node)s: %(msg)s\u0027)"}],"source_content_type":"text/x-python","patch_set":2,"id":"84257e46_0a997194","line":74,"in_reply_to":"6e271805_13b44623","updated":"2025-07-18 01:36:21.000000000","message":"Done","commit_id":"2824eb75f0f42d0edc2b7241458d494ed0b167b1"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"acb84cfdc7794c74810f2f4e567274c782701980","unresolved":true,"context_lines":[{"line_number":79,"context_line":"        return utils.servicing_error_handler(task, msg)"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":"    steps \u003d node.driver_internal_info.get(\u0027service_steps\u0027, [])"},{"line_number":82,"context_line":"    step_index \u003d 0 if steps else None"},{"line_number":83,"context_line":"    for step in steps:"},{"line_number":84,"context_line":"        step_requires_ramdisk \u003d step.get(\u0027requires_ramdisk\u0027)"},{"line_number":85,"context_line":"        if step_requires_ramdisk:"}],"source_content_type":"text/x-python","patch_set":2,"id":"1476836a_9c2a31de","line":82,"updated":"2025-07-16 16:04:12.000000000","message":"Unused","commit_id":"2824eb75f0f42d0edc2b7241458d494ed0b167b1"},{"author":{"_account_id":32177,"name":"Jacob Anders","email":"jacob-anders-dev@proton.me","username":"janders"},"change_message_id":"5018274f5b8b671e6b555e695ad059644ad74325","unresolved":true,"context_lines":[{"line_number":79,"context_line":"        return utils.servicing_error_handler(task, msg)"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":"    steps \u003d node.driver_internal_info.get(\u0027service_steps\u0027, [])"},{"line_number":82,"context_line":"    step_index \u003d 0 if steps else None"},{"line_number":83,"context_line":"    for step in steps:"},{"line_number":84,"context_line":"        step_requires_ramdisk \u003d step.get(\u0027requires_ramdisk\u0027)"},{"line_number":85,"context_line":"        if step_requires_ramdisk:"}],"source_content_type":"text/x-python","patch_set":2,"id":"5347d5bd_ceba42af","line":82,"in_reply_to":"1476836a_9c2a31de","updated":"2025-07-18 01:36:21.000000000","message":"If I understand correctly this (step_index) is passed to do_next_service_step() in the end, will this now be no longer needed?","commit_id":"2824eb75f0f42d0edc2b7241458d494ed0b167b1"},{"author":{"_account_id":15519,"name":"Iury Gregory Melo Ferreira","display_name":"Iury Gregory","email":"iurygregory@gmail.com","username":"iurygregory"},"change_message_id":"1ee0bc364bf9ce605d321bab7cdd3cf00fe93086","unresolved":true,"context_lines":[{"line_number":79,"context_line":"        return utils.servicing_error_handler(task, msg)"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":"    steps \u003d node.driver_internal_info.get(\u0027service_steps\u0027, [])"},{"line_number":82,"context_line":"    step_index \u003d 0 if steps else None"},{"line_number":83,"context_line":"    for step in steps:"},{"line_number":84,"context_line":"        step_requires_ramdisk \u003d step.get(\u0027requires_ramdisk\u0027)"},{"line_number":85,"context_line":"        if step_requires_ramdisk:"}],"source_content_type":"text/x-python","patch_set":2,"id":"5f33466f_b8d1c252","line":82,"in_reply_to":"5347d5bd_ceba42af","updated":"2025-07-22 01:39:34.000000000","message":"Agree, we still use step_index here,","commit_id":"2824eb75f0f42d0edc2b7241458d494ed0b167b1"},{"author":{"_account_id":32177,"name":"Jacob Anders","email":"jacob-anders-dev@proton.me","username":"janders"},"change_message_id":"2cb446fd9837a3b92864dbc0bd6569b0b6aa4570","unresolved":true,"context_lines":[{"line_number":79,"context_line":"        return utils.servicing_error_handler(task, msg)"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":"    steps \u003d node.driver_internal_info.get(\u0027service_steps\u0027, [])"},{"line_number":82,"context_line":"    step_index \u003d 0 if steps else None"},{"line_number":83,"context_line":"    for step in steps:"},{"line_number":84,"context_line":"        step_requires_ramdisk \u003d step.get(\u0027requires_ramdisk\u0027)"},{"line_number":85,"context_line":"        if step_requires_ramdisk:"}],"source_content_type":"text/x-python","patch_set":2,"id":"f82b71c8_052a6e63","line":82,"in_reply_to":"5f33466f_b8d1c252","updated":"2025-07-22 02:44:48.000000000","message":"Thank you, Iury. I will wait to see what Dmitry thinks and will resolve this.","commit_id":"2824eb75f0f42d0edc2b7241458d494ed0b167b1"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"76c18ac0769d41c3edb8f0f62efa08ebdb9070bf","unresolved":false,"context_lines":[{"line_number":79,"context_line":"        return utils.servicing_error_handler(task, msg)"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":"    steps \u003d node.driver_internal_info.get(\u0027service_steps\u0027, [])"},{"line_number":82,"context_line":"    step_index \u003d 0 if steps else None"},{"line_number":83,"context_line":"    for step in steps:"},{"line_number":84,"context_line":"        step_requires_ramdisk \u003d step.get(\u0027requires_ramdisk\u0027)"},{"line_number":85,"context_line":"        if step_requires_ramdisk:"}],"source_content_type":"text/x-python","patch_set":2,"id":"53489218_8b643586","line":82,"in_reply_to":"f82b71c8_052a6e63","updated":"2025-07-23 11:09:35.000000000","message":"Missed that, sorry.","commit_id":"2824eb75f0f42d0edc2b7241458d494ed0b167b1"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"76c18ac0769d41c3edb8f0f62efa08ebdb9070bf","unresolved":true,"context_lines":[{"line_number":61,"context_line":"        conductor_steps.set_node_service_steps("},{"line_number":62,"context_line":"            task, disable_ramdisk\u003ddisable_ramdisk)"},{"line_number":63,"context_line":"    except exception.InvalidParameterValue:"},{"line_number":64,"context_line":"        LOG.debug(\u0027Failed to compose list of service steps for node \u0027"},{"line_number":65,"context_line":"                  \u0027%s\u0027, node.uuid)"},{"line_number":66,"context_line":"        if disable_ramdisk:"},{"line_number":67,"context_line":"            raise"}],"source_content_type":"text/x-python","patch_set":6,"id":"e5a2a34e_6397a18c","line":64,"updated":"2025-07-23 11:09:35.000000000","message":"Let\u0027s change the level based on disable_ramdisk: use LOG.error when disable_ramdisk is true because we\u0027re about to blow up.","commit_id":"33ffdb4eeaaad15676ea47d1551ddc50f460d034"},{"author":{"_account_id":32177,"name":"Jacob Anders","email":"jacob-anders-dev@proton.me","username":"janders"},"change_message_id":"87f732c034434eafcaccf000424582a60a4bdbac","unresolved":false,"context_lines":[{"line_number":61,"context_line":"        conductor_steps.set_node_service_steps("},{"line_number":62,"context_line":"            task, disable_ramdisk\u003ddisable_ramdisk)"},{"line_number":63,"context_line":"    except exception.InvalidParameterValue:"},{"line_number":64,"context_line":"        LOG.debug(\u0027Failed to compose list of service steps for node \u0027"},{"line_number":65,"context_line":"                  \u0027%s\u0027, node.uuid)"},{"line_number":66,"context_line":"        if disable_ramdisk:"},{"line_number":67,"context_line":"            raise"}],"source_content_type":"text/x-python","patch_set":6,"id":"d60228d9_427e82be","line":64,"in_reply_to":"e5a2a34e_6397a18c","updated":"2025-07-23 13:06:56.000000000","message":"Done","commit_id":"33ffdb4eeaaad15676ea47d1551ddc50f460d034"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"76c18ac0769d41c3edb8f0f62efa08ebdb9070bf","unresolved":true,"context_lines":[{"line_number":62,"context_line":"            task, disable_ramdisk\u003ddisable_ramdisk)"},{"line_number":63,"context_line":"    except exception.InvalidParameterValue:"},{"line_number":64,"context_line":"        LOG.debug(\u0027Failed to compose list of service steps for node \u0027"},{"line_number":65,"context_line":"                  \u0027%s\u0027, node.uuid)"},{"line_number":66,"context_line":"        if disable_ramdisk:"},{"line_number":67,"context_line":"            raise"},{"line_number":68,"context_line":"        ramdisk_needed \u003d True"}],"source_content_type":"text/x-python","patch_set":6,"id":"e0d357e6_6ccc9587","line":65,"updated":"2025-07-23 11:09:35.000000000","message":"Ideally, also different error messages. When disable_ramdisk is False, let\u0027s have a more mild wording and mention that we\u0027re going to retry after the ramdisk is booted.","commit_id":"33ffdb4eeaaad15676ea47d1551ddc50f460d034"},{"author":{"_account_id":32177,"name":"Jacob Anders","email":"jacob-anders-dev@proton.me","username":"janders"},"change_message_id":"87f732c034434eafcaccf000424582a60a4bdbac","unresolved":false,"context_lines":[{"line_number":62,"context_line":"            task, disable_ramdisk\u003ddisable_ramdisk)"},{"line_number":63,"context_line":"    except exception.InvalidParameterValue:"},{"line_number":64,"context_line":"        LOG.debug(\u0027Failed to compose list of service steps for node \u0027"},{"line_number":65,"context_line":"                  \u0027%s\u0027, node.uuid)"},{"line_number":66,"context_line":"        if disable_ramdisk:"},{"line_number":67,"context_line":"            raise"},{"line_number":68,"context_line":"        ramdisk_needed \u003d True"}],"source_content_type":"text/x-python","patch_set":6,"id":"7c666799_4bc26efe","line":65,"in_reply_to":"e0d357e6_6ccc9587","updated":"2025-07-23 13:06:56.000000000","message":"Done","commit_id":"33ffdb4eeaaad15676ea47d1551ddc50f460d034"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"e4f17fb021d2e2fc94219b49fcef9a6559e34fe0","unresolved":true,"context_lines":[{"line_number":98,"context_line":"            # continue_node_service to start service operations."},{"line_number":99,"context_line":"            task.process_event(\u0027wait\u0027)"},{"line_number":100,"context_line":"            return"},{"line_number":101,"context_line":""},{"line_number":102,"context_line":"    do_next_service_step(task, step_index, disable_ramdisk\u003ddisable_ramdisk)"},{"line_number":103,"context_line":""},{"line_number":104,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"6f1876ff_21a27765","line":101,"updated":"2025-07-24 11:47:13.000000000","message":"Maybe a debug logging in the \"else\" branch that we\u0027re going to proceed without booting the ramdisk?","commit_id":"d8ee0e37b1ca9e0193213ce709aa089e977ff24c"},{"author":{"_account_id":32177,"name":"Jacob Anders","email":"jacob-anders-dev@proton.me","username":"janders"},"change_message_id":"046cc38202551da420d958e28b085f52bed27409","unresolved":false,"context_lines":[{"line_number":98,"context_line":"            # continue_node_service to start service operations."},{"line_number":99,"context_line":"            task.process_event(\u0027wait\u0027)"},{"line_number":100,"context_line":"            return"},{"line_number":101,"context_line":""},{"line_number":102,"context_line":"    do_next_service_step(task, step_index, disable_ramdisk\u003ddisable_ramdisk)"},{"line_number":103,"context_line":""},{"line_number":104,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"fecd0ad0_f1868cff","line":101,"in_reply_to":"6f1876ff_21a27765","updated":"2025-07-24 13:13:12.000000000","message":"That\u0027s a great suggestion. Done.","commit_id":"d8ee0e37b1ca9e0193213ce709aa089e977ff24c"}],"ironic/conductor/steps.py":[{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"acb84cfdc7794c74810f2f4e567274c782701980","unresolved":true,"context_lines":[{"line_number":496,"context_line":"        are accepted."},{"line_number":497,"context_line":"    :raises: InvalidParameterValue if there is a problem with the user\u0027s"},{"line_number":498,"context_line":"             clean steps."},{"line_number":499,"context_line":"    :raises: NodeServicingFailure if there was a problem getting the"},{"line_number":500,"context_line":"             service steps."},{"line_number":501,"context_line":"    \"\"\""},{"line_number":502,"context_line":"    node \u003d task.node"}],"source_content_type":"text/x-python","patch_set":2,"id":"b947baa2_09b722af","line":499,"updated":"2025-07-16 16:04:12.000000000","message":"I wonder if it\u0027s actually possible, I can only find references to InvalidParameterValue","commit_id":"2824eb75f0f42d0edc2b7241458d494ed0b167b1"},{"author":{"_account_id":32177,"name":"Jacob Anders","email":"jacob-anders-dev@proton.me","username":"janders"},"change_message_id":"5018274f5b8b671e6b555e695ad059644ad74325","unresolved":true,"context_lines":[{"line_number":496,"context_line":"        are accepted."},{"line_number":497,"context_line":"    :raises: InvalidParameterValue if there is a problem with the user\u0027s"},{"line_number":498,"context_line":"             clean steps."},{"line_number":499,"context_line":"    :raises: NodeServicingFailure if there was a problem getting the"},{"line_number":500,"context_line":"             service steps."},{"line_number":501,"context_line":"    \"\"\""},{"line_number":502,"context_line":"    node \u003d task.node"}],"source_content_type":"text/x-python","patch_set":2,"id":"c547d841_4fd774a5","line":499,"in_reply_to":"b947baa2_09b722af","updated":"2025-07-18 01:36:21.000000000","message":"I had a quick look and I agree - I changed it from NodeCleaningFailure to NodeServicingFailure while I was at it, but should I just remove it entirely? Adding a FIXME as reminder.","commit_id":"2824eb75f0f42d0edc2b7241458d494ed0b167b1"},{"author":{"_account_id":32177,"name":"Jacob Anders","email":"jacob-anders-dev@proton.me","username":"janders"},"change_message_id":"4e9e3464d9065508edd468678448de346fc2f61c","unresolved":false,"context_lines":[{"line_number":496,"context_line":"        are accepted."},{"line_number":497,"context_line":"    :raises: InvalidParameterValue if there is a problem with the user\u0027s"},{"line_number":498,"context_line":"             clean steps."},{"line_number":499,"context_line":"    :raises: NodeServicingFailure if there was a problem getting the"},{"line_number":500,"context_line":"             service steps."},{"line_number":501,"context_line":"    \"\"\""},{"line_number":502,"context_line":"    node \u003d task.node"}],"source_content_type":"text/x-python","patch_set":2,"id":"c8ac548e_c2397c73","line":499,"in_reply_to":"c547d841_4fd774a5","updated":"2025-07-24 13:13:44.000000000","message":"Done","commit_id":"2824eb75f0f42d0edc2b7241458d494ed0b167b1"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"e4f17fb021d2e2fc94219b49fcef9a6559e34fe0","unresolved":true,"context_lines":[{"line_number":496,"context_line":"        are accepted."},{"line_number":497,"context_line":"    :raises: InvalidParameterValue if there is a problem with the user\u0027s"},{"line_number":498,"context_line":"             clean steps."},{"line_number":499,"context_line":"    # FIXME(janders) it seems this exception is never actually raised,"},{"line_number":500,"context_line":"    # perhaps we should remove it?"},{"line_number":501,"context_line":"    :raises: NodeServicingFailure if there was a problem getting the"},{"line_number":502,"context_line":"             service steps."}],"source_content_type":"text/x-python","patch_set":8,"id":"d175c27b_4c50cdca","line":499,"updated":"2025-07-24 11:47:13.000000000","message":"Could you move FIXME out of the docstring? It will render otherwise.","commit_id":"d8ee0e37b1ca9e0193213ce709aa089e977ff24c"},{"author":{"_account_id":32177,"name":"Jacob Anders","email":"jacob-anders-dev@proton.me","username":"janders"},"change_message_id":"046cc38202551da420d958e28b085f52bed27409","unresolved":false,"context_lines":[{"line_number":496,"context_line":"        are accepted."},{"line_number":497,"context_line":"    :raises: InvalidParameterValue if there is a problem with the user\u0027s"},{"line_number":498,"context_line":"             clean steps."},{"line_number":499,"context_line":"    # FIXME(janders) it seems this exception is never actually raised,"},{"line_number":500,"context_line":"    # perhaps we should remove it?"},{"line_number":501,"context_line":"    :raises: NodeServicingFailure if there was a problem getting the"},{"line_number":502,"context_line":"             service steps."}],"source_content_type":"text/x-python","patch_set":8,"id":"2c71271f_18215a28","line":499,"in_reply_to":"d175c27b_4c50cdca","updated":"2025-07-24 13:13:12.000000000","message":"Good pickup, fixed.","commit_id":"d8ee0e37b1ca9e0193213ce709aa089e977ff24c"}],"ironic/drivers/modules/deploy_utils.py":[{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"acb84cfdc7794c74810f2f4e567274c782701980","unresolved":true,"context_lines":[{"line_number":1750,"context_line":"    task.driver.boot.prepare_ramdisk(task, deploy_opts)"},{"line_number":1751,"context_line":""},{"line_number":1752,"context_line":""},{"line_number":1753,"context_line":"def reboot_to_finish_step(task, timeout\u003dNone, force_skip_ipa\u003dFalse):"},{"line_number":1754,"context_line":"    \"\"\"Reboot the node into IPA to finish a deploy/clean step."},{"line_number":1755,"context_line":""},{"line_number":1756,"context_line":"    :param task: a TaskManager instance."}],"source_content_type":"text/x-python","patch_set":2,"id":"ad852775_204a57b4","line":1753,"updated":"2025-07-16 16:04:12.000000000","message":"Let\u0027s call it disable_ramdisk too. If it is set to None, then take the value from dii","commit_id":"2824eb75f0f42d0edc2b7241458d494ed0b167b1"},{"author":{"_account_id":32177,"name":"Jacob Anders","email":"jacob-anders-dev@proton.me","username":"janders"},"change_message_id":"5018274f5b8b671e6b555e695ad059644ad74325","unresolved":false,"context_lines":[{"line_number":1750,"context_line":"    task.driver.boot.prepare_ramdisk(task, deploy_opts)"},{"line_number":1751,"context_line":""},{"line_number":1752,"context_line":""},{"line_number":1753,"context_line":"def reboot_to_finish_step(task, timeout\u003dNone, force_skip_ipa\u003dFalse):"},{"line_number":1754,"context_line":"    \"\"\"Reboot the node into IPA to finish a deploy/clean step."},{"line_number":1755,"context_line":""},{"line_number":1756,"context_line":"    :param task: a TaskManager instance."}],"source_content_type":"text/x-python","patch_set":2,"id":"914eca20_a45a823d","line":1753,"in_reply_to":"ad852775_204a57b4","updated":"2025-07-18 01:36:21.000000000","message":"Done","commit_id":"2824eb75f0f42d0edc2b7241458d494ed0b167b1"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"acb84cfdc7794c74810f2f4e567274c782701980","unresolved":true,"context_lines":[{"line_number":1760,"context_line":"              or states.DEPLOYWAIT if deploy operation in progress."},{"line_number":1761,"context_line":"    \"\"\""},{"line_number":1762,"context_line":"    disable_ramdisk \u003d task.node.driver_internal_info.get("},{"line_number":1763,"context_line":"        \u0027cleaning_disable_ramdisk\u0027)"},{"line_number":1764,"context_line":"    if not disable_ramdisk and not force_skip_ipa:"},{"line_number":1765,"context_line":"        if (manager_utils.is_fast_track(task)"},{"line_number":1766,"context_line":"                and not task.node.disable_power_off):"}],"source_content_type":"text/x-python","patch_set":2,"id":"56880535_7a1b0209","line":1763,"updated":"2025-07-16 16:04:12.000000000","message":"\"cleaning\" oops, this is broken","commit_id":"2824eb75f0f42d0edc2b7241458d494ed0b167b1"},{"author":{"_account_id":32177,"name":"Jacob Anders","email":"jacob-anders-dev@proton.me","username":"janders"},"change_message_id":"5018274f5b8b671e6b555e695ad059644ad74325","unresolved":true,"context_lines":[{"line_number":1760,"context_line":"              or states.DEPLOYWAIT if deploy operation in progress."},{"line_number":1761,"context_line":"    \"\"\""},{"line_number":1762,"context_line":"    disable_ramdisk \u003d task.node.driver_internal_info.get("},{"line_number":1763,"context_line":"        \u0027cleaning_disable_ramdisk\u0027)"},{"line_number":1764,"context_line":"    if not disable_ramdisk and not force_skip_ipa:"},{"line_number":1765,"context_line":"        if (manager_utils.is_fast_track(task)"},{"line_number":1766,"context_line":"                and not task.node.disable_power_off):"}],"source_content_type":"text/x-python","patch_set":2,"id":"c1757d93_7954caf9","line":1763,"in_reply_to":"56880535_7a1b0209","updated":"2025-07-18 01:36:21.000000000","message":"agreed, let\u0027s discuss and I will either try to fix it in this change or post a separate fix, whichever makes more sense, from a quick look at the code this may be a bit more involved as servicing and cleaning logic may not be the same in this case","commit_id":"2824eb75f0f42d0edc2b7241458d494ed0b167b1"},{"author":{"_account_id":32177,"name":"Jacob Anders","email":"jacob-anders-dev@proton.me","username":"janders"},"change_message_id":"4e9e3464d9065508edd468678448de346fc2f61c","unresolved":false,"context_lines":[{"line_number":1760,"context_line":"              or states.DEPLOYWAIT if deploy operation in progress."},{"line_number":1761,"context_line":"    \"\"\""},{"line_number":1762,"context_line":"    disable_ramdisk \u003d task.node.driver_internal_info.get("},{"line_number":1763,"context_line":"        \u0027cleaning_disable_ramdisk\u0027)"},{"line_number":1764,"context_line":"    if not disable_ramdisk and not force_skip_ipa:"},{"line_number":1765,"context_line":"        if (manager_utils.is_fast_track(task)"},{"line_number":1766,"context_line":"                and not task.node.disable_power_off):"}],"source_content_type":"text/x-python","patch_set":2,"id":"f5c9e614_82ec12a7","line":1763,"in_reply_to":"c1757d93_7954caf9","updated":"2025-07-24 13:13:44.000000000","message":"Done","commit_id":"2824eb75f0f42d0edc2b7241458d494ed0b167b1"},{"author":{"_account_id":15519,"name":"Iury Gregory Melo Ferreira","display_name":"Iury Gregory","email":"iurygregory@gmail.com","username":"iurygregory"},"change_message_id":"1ee0bc364bf9ce605d321bab7cdd3cf00fe93086","unresolved":true,"context_lines":[{"line_number":1761,"context_line":"    \"\"\""},{"line_number":1762,"context_line":"    if disable_ramdisk is None:"},{"line_number":1763,"context_line":"        disable_ramdisk \u003d task.node.driver_internal_info.get("},{"line_number":1764,"context_line":"            \u0027cleaning_disable_ramdisk\u0027)"},{"line_number":1765,"context_line":"    if not disable_ramdisk:"},{"line_number":1766,"context_line":"        if (manager_utils.is_fast_track(task)"},{"line_number":1767,"context_line":"                and not task.node.disable_power_off):"}],"source_content_type":"text/x-python","patch_set":6,"id":"49213c4b_4689818d","line":1764,"range":{"start_line":1764,"start_character":13,"end_line":1764,"end_character":37},"updated":"2025-07-22 01:39:34.000000000","message":"I\u0027m a bit puzzled here, but doesn\u0027t this function would also return states.SERVICEWAIT?\nAlso, we only disable the ramdisk based on cleaning_disable_ramdisk?","commit_id":"33ffdb4eeaaad15676ea47d1551ddc50f460d034"},{"author":{"_account_id":32177,"name":"Jacob Anders","email":"jacob-anders-dev@proton.me","username":"janders"},"change_message_id":"4e9e3464d9065508edd468678448de346fc2f61c","unresolved":false,"context_lines":[{"line_number":1761,"context_line":"    \"\"\""},{"line_number":1762,"context_line":"    if disable_ramdisk is None:"},{"line_number":1763,"context_line":"        disable_ramdisk \u003d task.node.driver_internal_info.get("},{"line_number":1764,"context_line":"            \u0027cleaning_disable_ramdisk\u0027)"},{"line_number":1765,"context_line":"    if not disable_ramdisk:"},{"line_number":1766,"context_line":"        if (manager_utils.is_fast_track(task)"},{"line_number":1767,"context_line":"                and not task.node.disable_power_off):"}],"source_content_type":"text/x-python","patch_set":6,"id":"6a57d5cb_5f256efa","line":1764,"range":{"start_line":1764,"start_character":13,"end_line":1764,"end_character":37},"in_reply_to":"22b9d412_6c87666b","updated":"2025-07-24 13:13:44.000000000","message":"Done","commit_id":"33ffdb4eeaaad15676ea47d1551ddc50f460d034"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"76c18ac0769d41c3edb8f0f62efa08ebdb9070bf","unresolved":true,"context_lines":[{"line_number":1761,"context_line":"    \"\"\""},{"line_number":1762,"context_line":"    if disable_ramdisk is None:"},{"line_number":1763,"context_line":"        disable_ramdisk \u003d task.node.driver_internal_info.get("},{"line_number":1764,"context_line":"            \u0027cleaning_disable_ramdisk\u0027)"},{"line_number":1765,"context_line":"    if not disable_ramdisk:"},{"line_number":1766,"context_line":"        if (manager_utils.is_fast_track(task)"},{"line_number":1767,"context_line":"                and not task.node.disable_power_off):"}],"source_content_type":"text/x-python","patch_set":6,"id":"ac8d247a_ebcfe2e9","line":1764,"range":{"start_line":1764,"start_character":13,"end_line":1764,"end_character":37},"in_reply_to":"2748e372_56e7d19c","updated":"2025-07-23 11:09:35.000000000","message":"Can you fix the \"cleaning\" part please? It needs to depend on the nature of the current step.","commit_id":"33ffdb4eeaaad15676ea47d1551ddc50f460d034"},{"author":{"_account_id":32177,"name":"Jacob Anders","email":"jacob-anders-dev@proton.me","username":"janders"},"change_message_id":"2cb446fd9837a3b92864dbc0bd6569b0b6aa4570","unresolved":false,"context_lines":[{"line_number":1761,"context_line":"    \"\"\""},{"line_number":1762,"context_line":"    if disable_ramdisk is None:"},{"line_number":1763,"context_line":"        disable_ramdisk \u003d task.node.driver_internal_info.get("},{"line_number":1764,"context_line":"            \u0027cleaning_disable_ramdisk\u0027)"},{"line_number":1765,"context_line":"    if not disable_ramdisk:"},{"line_number":1766,"context_line":"        if (manager_utils.is_fast_track(task)"},{"line_number":1767,"context_line":"                and not task.node.disable_power_off):"}],"source_content_type":"text/x-python","patch_set":6,"id":"2748e372_56e7d19c","line":1764,"range":{"start_line":1764,"start_character":13,"end_line":1764,"end_character":37},"in_reply_to":"49213c4b_4689818d","updated":"2025-07-22 02:44:48.000000000","message":"While there is still a fair bit of cleaning-derived code carried over into servicing, this change should only retain original behaviour after adding the additional disable_ramdisk argument needed to avoid the initial unconditional reboot so I think it makes sense this way here.\n\nI am not 100% across this codepath but I do think this is needed in cleaning for fasttrack (this function is shared across servicing and cleaning).","commit_id":"33ffdb4eeaaad15676ea47d1551ddc50f460d034"},{"author":{"_account_id":32177,"name":"Jacob Anders","email":"jacob-anders-dev@proton.me","username":"janders"},"change_message_id":"87f732c034434eafcaccf000424582a60a4bdbac","unresolved":true,"context_lines":[{"line_number":1761,"context_line":"    \"\"\""},{"line_number":1762,"context_line":"    if disable_ramdisk is None:"},{"line_number":1763,"context_line":"        disable_ramdisk \u003d task.node.driver_internal_info.get("},{"line_number":1764,"context_line":"            \u0027cleaning_disable_ramdisk\u0027)"},{"line_number":1765,"context_line":"    if not disable_ramdisk:"},{"line_number":1766,"context_line":"        if (manager_utils.is_fast_track(task)"},{"line_number":1767,"context_line":"                and not task.node.disable_power_off):"}],"source_content_type":"text/x-python","patch_set":6,"id":"22b9d412_6c87666b","line":1764,"range":{"start_line":1764,"start_character":13,"end_line":1764,"end_character":37},"in_reply_to":"ac8d247a_ebcfe2e9","updated":"2025-07-23 13:06:56.000000000","message":"I tried to clean this up (pun not intended :) ), let me know if this is good.","commit_id":"33ffdb4eeaaad15676ea47d1551ddc50f460d034"}],"ironic/drivers/modules/redfish/firmware.py":[{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"f7992c8c279a70b3355548dbda5ef26fc4cb8eba","unresolved":true,"context_lines":[{"line_number":169,"context_line":""},{"line_number":170,"context_line":"        # indicate that reboot into IPA is not required"},{"line_number":171,"context_line":"        # TODO(janders): figure out where to best unset it"},{"line_number":172,"context_line":"        node.set_driver_internal_info(\u0027skip_reboot_to_ipa\u0027, True)"},{"line_number":173,"context_line":"        node.save()"},{"line_number":174,"context_line":""},{"line_number":175,"context_line":"        LOG.debug(\u0027Updating Firmware on node %(node_uuid)s with settings \u0027"}],"source_content_type":"text/x-python","patch_set":1,"id":"10d16c2d_f2e8ce28","line":172,"updated":"2025-07-08 12:43:24.000000000","message":"This does not look useful to me.","commit_id":"43968fe8fee9ec691e6b72ac34cfab71d867e134"},{"author":{"_account_id":32177,"name":"Jacob Anders","email":"jacob-anders-dev@proton.me","username":"janders"},"change_message_id":"361048a5fc38d46a997b9fc448568fc1d8c2ad35","unresolved":false,"context_lines":[{"line_number":169,"context_line":""},{"line_number":170,"context_line":"        # indicate that reboot into IPA is not required"},{"line_number":171,"context_line":"        # TODO(janders): figure out where to best unset it"},{"line_number":172,"context_line":"        node.set_driver_internal_info(\u0027skip_reboot_to_ipa\u0027, True)"},{"line_number":173,"context_line":"        node.save()"},{"line_number":174,"context_line":""},{"line_number":175,"context_line":"        LOG.debug(\u0027Updating Firmware on node %(node_uuid)s with settings \u0027"}],"source_content_type":"text/x-python","patch_set":1,"id":"b48b5100_9b48f4c5","line":172,"in_reply_to":"10d16c2d_f2e8ce28","updated":"2025-07-14 04:35:57.000000000","message":"Noted, removing this (this was supposed to be used with the helper which I no longer use).","commit_id":"43968fe8fee9ec691e6b72ac34cfab71d867e134"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"f7992c8c279a70b3355548dbda5ef26fc4cb8eba","unresolved":true,"context_lines":[{"line_number":186,"context_line":"            polling\u003dTrue"},{"line_number":187,"context_line":"        )"},{"line_number":188,"context_line":""},{"line_number":189,"context_line":"        return deploy_utils.reboot_to_finish_step(task, timeout\u003dwait_interval)"},{"line_number":190,"context_line":""},{"line_number":191,"context_line":"    def _execute_firmware_update(self, node, update_service, settings):"},{"line_number":192,"context_line":"        \"\"\"Executes the next firmware update to the node"}],"source_content_type":"text/x-python","patch_set":1,"id":"248710d2_47e0b083","line":189,"updated":"2025-07-08 12:43:24.000000000","message":"The way reboot_to_finish_step is written, it will try to reboot into IPA, unless disable_ramdisk was requested (which is not the case for us). Since we don\u0027t rely on IPA for status check (using polling\u003dTrue and a periodic task), we need a new argument to that call to instruct it not to boot IPA in any case.","commit_id":"43968fe8fee9ec691e6b72ac34cfab71d867e134"},{"author":{"_account_id":32177,"name":"Jacob Anders","email":"jacob-anders-dev@proton.me","username":"janders"},"change_message_id":"361048a5fc38d46a997b9fc448568fc1d8c2ad35","unresolved":false,"context_lines":[{"line_number":186,"context_line":"            polling\u003dTrue"},{"line_number":187,"context_line":"        )"},{"line_number":188,"context_line":""},{"line_number":189,"context_line":"        return deploy_utils.reboot_to_finish_step(task, timeout\u003dwait_interval)"},{"line_number":190,"context_line":""},{"line_number":191,"context_line":"    def _execute_firmware_update(self, node, update_service, settings):"},{"line_number":192,"context_line":"        \"\"\"Executes the next firmware update to the node"}],"source_content_type":"text/x-python","patch_set":1,"id":"8c4229fd_34377d21","line":189,"in_reply_to":"248710d2_47e0b083","updated":"2025-07-14 04:35:57.000000000","message":"Noted, thank you Dmitry. I made my first attempt of implementing this change.","commit_id":"43968fe8fee9ec691e6b72ac34cfab71d867e134"}],"ironic/tests/unit/conductor/test_servicing.py":[{"author":{"_account_id":32177,"name":"Jacob Anders","email":"jacob-anders-dev@proton.me","username":"janders"},"change_message_id":"fe5b953541b24625e364cf6bb6b259e30c9ab5ec","unresolved":true,"context_lines":[{"line_number":131,"context_line":"                self.context, node.uuid, shared\u003dFalse) as task:"},{"line_number":132,"context_line":"            servicing.do_node_service(task, service_steps\u003dservice_steps)"},{"line_number":133,"context_line":"            node.refresh()"},{"line_number":134,"context_line":"            # FIXME(janders) this needs to be adjusted for the new flow"},{"line_number":135,"context_line":"            # self.assertEqual(states.SERVICEFAIL, node.provision_state)"},{"line_number":136,"context_line":"            # self.assertEqual(tgt_prov_state, node.target_provision_state)"},{"line_number":137,"context_line":"            mock_prep.assert_called_once_with(mock.ANY, task)"}],"source_content_type":"text/x-python","patch_set":6,"id":"37a5ca9e_a8bffb1d","line":134,"updated":"2025-07-21 11:31:11.000000000","message":"under the new flow, I do not think we should be expecting SERVICEFAIL here, but I am not 100% sure if this check needs to be removed or replaced with another one.. suggestions welcome! :)","commit_id":"33ffdb4eeaaad15676ea47d1551ddc50f460d034"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"e4f17fb021d2e2fc94219b49fcef9a6559e34fe0","unresolved":true,"context_lines":[{"line_number":131,"context_line":"                self.context, node.uuid, shared\u003dFalse) as task:"},{"line_number":132,"context_line":"            servicing.do_node_service(task, service_steps\u003dservice_steps)"},{"line_number":133,"context_line":"            node.refresh()"},{"line_number":134,"context_line":"            # FIXME(janders) this needs to be adjusted for the new flow"},{"line_number":135,"context_line":"            # self.assertEqual(states.SERVICEFAIL, node.provision_state)"},{"line_number":136,"context_line":"            # self.assertEqual(tgt_prov_state, node.target_provision_state)"},{"line_number":137,"context_line":"            mock_prep.assert_called_once_with(mock.ANY, task)"}],"source_content_type":"text/x-python","patch_set":6,"id":"9c04ba83_b47d6ea8","line":134,"in_reply_to":"2edf17ff_7c12ede8","updated":"2025-07-24 11:47:13.000000000","message":"Is there a unit test for the new behavior now? I don\u0027t see new cases added, so I guess no? Please add.","commit_id":"33ffdb4eeaaad15676ea47d1551ddc50f460d034"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"76c18ac0769d41c3edb8f0f62efa08ebdb9070bf","unresolved":true,"context_lines":[{"line_number":131,"context_line":"                self.context, node.uuid, shared\u003dFalse) as task:"},{"line_number":132,"context_line":"            servicing.do_node_service(task, service_steps\u003dservice_steps)"},{"line_number":133,"context_line":"            node.refresh()"},{"line_number":134,"context_line":"            # FIXME(janders) this needs to be adjusted for the new flow"},{"line_number":135,"context_line":"            # self.assertEqual(states.SERVICEFAIL, node.provision_state)"},{"line_number":136,"context_line":"            # self.assertEqual(tgt_prov_state, node.target_provision_state)"},{"line_number":137,"context_line":"            mock_prep.assert_called_once_with(mock.ANY, task)"}],"source_content_type":"text/x-python","patch_set":6,"id":"afe45fd9_95cc703b","line":134,"in_reply_to":"37a5ca9e_a8bffb1d","updated":"2025-07-23 11:09:35.000000000","message":"The test was checking what happens if prepare_service fails, you\u0027re changing its semantics. I\u0027d prefer to keep this test as it is and maybe create a new one if you wish.","commit_id":"33ffdb4eeaaad15676ea47d1551ddc50f460d034"},{"author":{"_account_id":32177,"name":"Jacob Anders","email":"jacob-anders-dev@proton.me","username":"janders"},"change_message_id":"046cc38202551da420d958e28b085f52bed27409","unresolved":false,"context_lines":[{"line_number":131,"context_line":"                self.context, node.uuid, shared\u003dFalse) as task:"},{"line_number":132,"context_line":"            servicing.do_node_service(task, service_steps\u003dservice_steps)"},{"line_number":133,"context_line":"            node.refresh()"},{"line_number":134,"context_line":"            # FIXME(janders) this needs to be adjusted for the new flow"},{"line_number":135,"context_line":"            # self.assertEqual(states.SERVICEFAIL, node.provision_state)"},{"line_number":136,"context_line":"            # self.assertEqual(tgt_prov_state, node.target_provision_state)"},{"line_number":137,"context_line":"            mock_prep.assert_called_once_with(mock.ANY, task)"}],"source_content_type":"text/x-python","patch_set":6,"id":"35d9c3b3_c21db837","line":134,"in_reply_to":"9c04ba83_b47d6ea8","updated":"2025-07-24 13:13:12.000000000","message":"I added a couple new tests now (for running OOB as well as falling back to ramdisk if steps have require_ramdisk) - is this sufficient?","commit_id":"33ffdb4eeaaad15676ea47d1551ddc50f460d034"},{"author":{"_account_id":32177,"name":"Jacob Anders","email":"jacob-anders-dev@proton.me","username":"janders"},"change_message_id":"87f732c034434eafcaccf000424582a60a4bdbac","unresolved":true,"context_lines":[{"line_number":131,"context_line":"                self.context, node.uuid, shared\u003dFalse) as task:"},{"line_number":132,"context_line":"            servicing.do_node_service(task, service_steps\u003dservice_steps)"},{"line_number":133,"context_line":"            node.refresh()"},{"line_number":134,"context_line":"            # FIXME(janders) this needs to be adjusted for the new flow"},{"line_number":135,"context_line":"            # self.assertEqual(states.SERVICEFAIL, node.provision_state)"},{"line_number":136,"context_line":"            # self.assertEqual(tgt_prov_state, node.target_provision_state)"},{"line_number":137,"context_line":"            mock_prep.assert_called_once_with(mock.ANY, task)"}],"source_content_type":"text/x-python","patch_set":6,"id":"2edf17ff_7c12ede8","line":134,"in_reply_to":"afe45fd9_95cc703b","updated":"2025-07-23 13:06:56.000000000","message":"I think I need to make set_node_service_steps() raise InvalidParameterValue to make sure prepare_service() is called - I made sure to make only this change and leave everything as is, please let me know if this is good or needs further rework.","commit_id":"33ffdb4eeaaad15676ea47d1551ddc50f460d034"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"f2dd0cd1238c1b38f18b41e11ddb2830f30ddee9","unresolved":true,"context_lines":[{"line_number":195,"context_line":"                self.context, node.uuid, shared\u003dFalse) as task:"},{"line_number":196,"context_line":"            servicing.do_node_service(task, service_steps\u003dservice_steps)"},{"line_number":197,"context_line":"        node.refresh()"},{"line_number":198,"context_line":"        self.assertEqual(states.SERVICEWAIT, node.provision_state)"},{"line_number":199,"context_line":"        self.assertEqual(tgt_prov_state, node.target_provision_state)"},{"line_number":200,"context_line":"        mock_prep.assert_not_called()"},{"line_number":201,"context_line":"        mock_validate.assert_called_once_with(mock.ANY, mock.ANY)"}],"source_content_type":"text/x-python","patch_set":9,"id":"c51f00c8_5fd685c5","line":198,"updated":"2025-07-24 16:25:35.000000000","message":"This took me a minute to figure out that SERVICEWAIT is an effect of the step, not a bug in your code :) \n\nI\u0027d probably add some check that the step actually got executed. Maybe inspect the node\u0027s service_step? Otherwise, the case is easy to confuse with the case of booting IPA (modulo not running prepare_service).","commit_id":"1b2c01185c7907a1d17c4d90cf3bcd73fe345658"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"f2dd0cd1238c1b38f18b41e11ddb2830f30ddee9","unresolved":true,"context_lines":[{"line_number":226,"context_line":"        self.assertEqual(states.SERVICEWAIT, node.provision_state)"},{"line_number":227,"context_line":"        self.assertEqual(tgt_prov_state, node.target_provision_state)"},{"line_number":228,"context_line":"        mock_prep.assert_called_once_with(mock.ANY, mock.ANY)"},{"line_number":229,"context_line":"        mock_validate.assert_called_once_with(mock.ANY, mock.ANY)"},{"line_number":230,"context_line":""},{"line_number":231,"context_line":"    @mock.patch(\u0027ironic.drivers.modules.network.flat.FlatNetwork.validate\u0027,"},{"line_number":232,"context_line":"                autospec\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":9,"id":"ae664a10_363e561e","line":229,"updated":"2025-07-24 16:25:35.000000000","message":"And here validate that the step was not run yet.","commit_id":"1b2c01185c7907a1d17c4d90cf3bcd73fe345658"}]}
