)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"18f4fe788c998a0081dd0111c2d2a4eae4b404d8","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":4,"id":"a76cf794_51490b4d","updated":"2026-01-19 09:45:06.000000000","message":"The direction looks good to me but I have a couple of comments here and inline:\n\n* It would be nice to see an openstackclient patch as well to adapt to the new microversion.\n* We have API sample tests that also needs to be extended https://github.com/openstack/nova/blob/master/nova/tests/functional/api_sample_tests/test_volume_attachments.py","commit_id":"bc421b74a094bd0c47002ceb49e783fed4ec28f6"},{"author":{"_account_id":26250,"name":"Johannes Kulik","email":"johannes.kulik@sap.com","username":"jkulik"},"change_message_id":"ca1b03bb86229020d1b6bfbbfbbcb8bd48e40814","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":4,"id":"6e46d7ff_695272ef","in_reply_to":"a76cf794_51490b4d","updated":"2026-01-20 14:12:57.000000000","message":"Added the api_sample_tests.\n\nI wrote it down the additional task to update the openstackclient.","commit_id":"bc421b74a094bd0c47002ceb49e783fed4ec28f6"},{"author":{"_account_id":26250,"name":"Johannes Kulik","email":"johannes.kulik@sap.com","username":"jkulik"},"change_message_id":"f2548ba35e6f12509219bc709acf67725288ae4c","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":5,"id":"e89188df_cfc48303","updated":"2026-01-26 11:27:37.000000000","message":"Finally figured out the MessagingTimeouts: nova/compute/api.py has a context object that contains `mq_connection` from getting the instance first. This is lost in the RPC call to n-super-cond and thus nova-conductor cannot reach nova-compute. Adding `@targets_cell` in the conductor code fixed this.","commit_id":"a6161375b1b285571567e98ec05752b2ec2e6675"},{"author":{"_account_id":13915,"name":"Silvan Kaiser","email":"silvan@quobyte.com","username":"kaisers"},"change_message_id":"866ee311b1a3e2c9b44cf9d22bdad574a025e754","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":7,"id":"d0ce0ecf_4f6f5b02","updated":"2026-01-21 13:39:38.000000000","message":"run-Quobyte CI\n\nThe failed run showed a number of failures atypical for flakiness, re-running to verify.","commit_id":"f0e0a6d88846a135d2e8977b77f417326e0bb668"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"dc69d712d32aa2f1178d79ee4dfb8410d7619920","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":9,"id":"b56469a2_075d5555","updated":"2026-02-23 17:14:11.000000000","message":"Looks good to me.\n* lets have tempest patch to cover the new microversion\n* lets have a client patch to cover the new microvesion.","commit_id":"2a51df27603cd07f8a4cd63276578f1815131e91"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"048b8ec7cd600575596783da8cb93781d1d124fd","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":9,"id":"d872a0ec_cc11edf8","in_reply_to":"b56469a2_075d5555","updated":"2026-02-26 17:13:01.000000000","message":"Yeah agree. Honestly, we probably should have that up already to show this is working, but the functional tests seem to cover it reasonably well.","commit_id":"2a51df27603cd07f8a4cd63276578f1815131e91"},{"author":{"_account_id":8556,"name":"Ghanshyam Maan","display_name":"Ghanshyam Maan","email":"gmaan.os14@gmail.com","username":"ghanshyam"},"change_message_id":"1d5bedc67e74eab8d16e09164af6b75011dc50c4","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":9,"id":"20a51a13_6de29fed","in_reply_to":"d872a0ec_cc11edf8","updated":"2026-02-26 17:34:06.000000000","message":"tempest one is up, I will be checking that https://review.opendev.org/c/openstack/tempest/+/977952","commit_id":"2a51df27603cd07f8a4cd63276578f1815131e91"}],"nova/api/openstack/compute/rest_api_version_history.rst":[{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"18f4fe788c998a0081dd0111c2d2a4eae4b404d8","unresolved":false,"context_lines":[{"line_number":1303,"context_line":""},{"line_number":1304,"context_line":".. _microversion 2.101:"},{"line_number":1305,"context_line":""},{"line_number":1306,"context_line":"2.101 (Maximum in 2026.1 Gazpacho)"},{"line_number":1307,"context_line":"----------------------------------"},{"line_number":1308,"context_line":""},{"line_number":1309,"context_line":"Attaching a volume via ``POST /servers/{server_id}/os-volume_attachments``"}],"source_content_type":"text/x-rst","patch_set":4,"id":"036d4340_36ee890b","line":1306,"range":{"start_line":1306,"start_character":6,"end_line":1306,"end_character":34},"updated":"2026-01-19 09:45:06.000000000","message":"Yeah, why not, we can move this marker if a new microversion is landed later.","commit_id":"bc421b74a094bd0c47002ceb49e783fed4ec28f6"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"18f4fe788c998a0081dd0111c2d2a4eae4b404d8","unresolved":true,"context_lines":[{"line_number":1310,"context_line":"returns an HTTP 202 Accepted response instead of the previous HTTP 200"},{"line_number":1311,"context_line":"containing a ``volumeAttachment`` object. Like before, callers need to watch"},{"line_number":1312,"context_line":"the volume\u0027s state and/or server actions to recognize when the"},{"line_number":1313,"context_line":"volume-attachment process finished."}],"source_content_type":"text/x-rst","patch_set":4,"id":"d4db038b_a86e5280","line":1313,"updated":"2026-01-19 09:45:06.000000000","message":"I would mention that 202 is now returned fully async","commit_id":"bc421b74a094bd0c47002ceb49e783fed4ec28f6"},{"author":{"_account_id":26250,"name":"Johannes Kulik","email":"johannes.kulik@sap.com","username":"jkulik"},"change_message_id":"ca1b03bb86229020d1b6bfbbfbbcb8bd48e40814","unresolved":false,"context_lines":[{"line_number":1310,"context_line":"returns an HTTP 202 Accepted response instead of the previous HTTP 200"},{"line_number":1311,"context_line":"containing a ``volumeAttachment`` object. Like before, callers need to watch"},{"line_number":1312,"context_line":"the volume\u0027s state and/or server actions to recognize when the"},{"line_number":1313,"context_line":"volume-attachment process finished."}],"source_content_type":"text/x-rst","patch_set":4,"id":"7eef792f_cd04144c","line":1313,"in_reply_to":"d4db038b_a86e5280","updated":"2026-01-20 14:12:57.000000000","message":"Done","commit_id":"bc421b74a094bd0c47002ceb49e783fed4ec28f6"}],"nova/api/openstack/compute/volume_attachments.py":[{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"18f4fe788c998a0081dd0111c2d2a4eae4b404d8","unresolved":true,"context_lines":[{"line_number":180,"context_line":"            )"},{"line_number":181,"context_line":"        }"},{"line_number":182,"context_line":""},{"line_number":183,"context_line":"    # TODO(mriedem): This API should return a 202 instead of a 200 response."},{"line_number":184,"context_line":"    @wsgi.expected_errors((400, 403, 404, 409))"},{"line_number":185,"context_line":"    @validation.schema(schema.create, \u00272.0\u0027, \u00272.48\u0027)"},{"line_number":186,"context_line":"    @validation.schema(schema.create_v249, \u00272.49\u0027, \u00272.78\u0027)"}],"source_content_type":"text/x-python","patch_set":4,"id":"fb7c7e35_1792f942","line":183,"updated":"2026-01-19 09:45:06.000000000","message":"I think this is being fixed now, so you can remove the TODO","commit_id":"bc421b74a094bd0c47002ceb49e783fed4ec28f6"},{"author":{"_account_id":26250,"name":"Johannes Kulik","email":"johannes.kulik@sap.com","username":"jkulik"},"change_message_id":"ca1b03bb86229020d1b6bfbbfbbcb8bd48e40814","unresolved":false,"context_lines":[{"line_number":180,"context_line":"            )"},{"line_number":181,"context_line":"        }"},{"line_number":182,"context_line":""},{"line_number":183,"context_line":"    # TODO(mriedem): This API should return a 202 instead of a 200 response."},{"line_number":184,"context_line":"    @wsgi.expected_errors((400, 403, 404, 409))"},{"line_number":185,"context_line":"    @validation.schema(schema.create, \u00272.0\u0027, \u00272.48\u0027)"},{"line_number":186,"context_line":"    @validation.schema(schema.create_v249, \u00272.49\u0027, \u00272.78\u0027)"}],"source_content_type":"text/x-python","patch_set":4,"id":"0774a7b3_789a52fd","line":183,"in_reply_to":"fb7c7e35_1792f942","updated":"2026-01-20 14:12:57.000000000","message":"Done","commit_id":"bc421b74a094bd0c47002ceb49e783fed4ec28f6"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"18f4fe788c998a0081dd0111c2d2a4eae4b404d8","unresolved":true,"context_lines":[{"line_number":236,"context_line":"        ) as e:"},{"line_number":237,"context_line":"            raise exc.HTTPBadRequest(explanation\u003de.format_message())"},{"line_number":238,"context_line":"        except exception.TooManyDiskDevices as e:"},{"line_number":239,"context_line":"            raise exc.HTTPForbidden(explanation\u003de.format_message())"},{"line_number":240,"context_line":""},{"line_number":241,"context_line":"        if not needs_device_returned:"},{"line_number":242,"context_line":"            # New return code starting from 2.101"}],"source_content_type":"text/x-python","patch_set":4,"id":"9124497e_93af3305","line":239,"updated":"2026-01-19 09:45:06.000000000","message":"I think we need an exception handler for ServiceTooOld here now. And we can hint to the client that while there is an old conductor in the system (or the RPC version is pinned) then only the old microversions are usable for volume attach","commit_id":"bc421b74a094bd0c47002ceb49e783fed4ec28f6"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"6b789eb7523852af0e9b0f6d86010b770eaf4327","unresolved":true,"context_lines":[{"line_number":236,"context_line":"        ) as e:"},{"line_number":237,"context_line":"            raise exc.HTTPBadRequest(explanation\u003de.format_message())"},{"line_number":238,"context_line":"        except exception.TooManyDiskDevices as e:"},{"line_number":239,"context_line":"            raise exc.HTTPForbidden(explanation\u003de.format_message())"},{"line_number":240,"context_line":""},{"line_number":241,"context_line":"        if not needs_device_returned:"},{"line_number":242,"context_line":"            # New return code starting from 2.101"}],"source_content_type":"text/x-python","patch_set":4,"id":"9d7ca553_d4f928bc","line":239,"in_reply_to":"534b845b_a1a70528","updated":"2026-02-02 14:40:08.000000000","message":"\u003e Gibi, did you mean \"old compute\" above? \n\nNope I mean the conductor is old while the API is new. This patch makes a change in the conductor RPC not in the compute RPC so the only thing that can be old here is the conductor. \n\n\u003e the API and conductors have to be upgraded at the same time\n\nOK. Then I agree that we have no problem here. Thanks for clarifying our rules.\n\n(That is a different question that in some installers we cannot ensure they are upgraded at the same time, just making sure that there are no long running old conductors during the upgrade)\n\n\u003e But yes, to your other question: if computes are not fully upgraded, the new microversion should be disallowed and the old microversion must continue to work regardless of if the computes have been partially or fully upgraded.\n\nAs far as I understand this patch does not change the computes so we are good in this regard.","commit_id":"bc421b74a094bd0c47002ceb49e783fed4ec28f6"},{"author":{"_account_id":26250,"name":"Johannes Kulik","email":"johannes.kulik@sap.com","username":"jkulik"},"change_message_id":"ca1b03bb86229020d1b6bfbbfbbcb8bd48e40814","unresolved":true,"context_lines":[{"line_number":236,"context_line":"        ) as e:"},{"line_number":237,"context_line":"            raise exc.HTTPBadRequest(explanation\u003de.format_message())"},{"line_number":238,"context_line":"        except exception.TooManyDiskDevices as e:"},{"line_number":239,"context_line":"            raise exc.HTTPForbidden(explanation\u003de.format_message())"},{"line_number":240,"context_line":""},{"line_number":241,"context_line":"        if not needs_device_returned:"},{"line_number":242,"context_line":"            # New return code starting from 2.101"}],"source_content_type":"text/x-python","patch_set":4,"id":"f44b3ea6_51faa96e","line":239,"in_reply_to":"9124497e_93af3305","updated":"2026-01-20 14:12:57.000000000","message":"The old API version will only work, if `nova-api` still runs the old code, too, because `nova/compute/api.py` will always call `nova-conductor` for attach - it just does a call or a cast depending on the requested API version.","commit_id":"bc421b74a094bd0c47002ceb49e783fed4ec28f6"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"dc69d712d32aa2f1178d79ee4dfb8410d7619920","unresolved":false,"context_lines":[{"line_number":236,"context_line":"        ) as e:"},{"line_number":237,"context_line":"            raise exc.HTTPBadRequest(explanation\u003de.format_message())"},{"line_number":238,"context_line":"        except exception.TooManyDiskDevices as e:"},{"line_number":239,"context_line":"            raise exc.HTTPForbidden(explanation\u003de.format_message())"},{"line_number":240,"context_line":""},{"line_number":241,"context_line":"        if not needs_device_returned:"},{"line_number":242,"context_line":"            # New return code starting from 2.101"}],"source_content_type":"text/x-python","patch_set":4,"id":"d9b119a8_b8f82388","line":239,"in_reply_to":"9d7ca553_d4f928bc","updated":"2026-02-23 17:14:11.000000000","message":"Done","commit_id":"bc421b74a094bd0c47002ceb49e783fed4ec28f6"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"77cf03eca42f53237c04d35ea4109560d4a9fb1e","unresolved":true,"context_lines":[{"line_number":236,"context_line":"        ) as e:"},{"line_number":237,"context_line":"            raise exc.HTTPBadRequest(explanation\u003de.format_message())"},{"line_number":238,"context_line":"        except exception.TooManyDiskDevices as e:"},{"line_number":239,"context_line":"            raise exc.HTTPForbidden(explanation\u003de.format_message())"},{"line_number":240,"context_line":""},{"line_number":241,"context_line":"        if not needs_device_returned:"},{"line_number":242,"context_line":"            # New return code starting from 2.101"}],"source_content_type":"text/x-python","patch_set":4,"id":"534b845b_a1a70528","line":239,"in_reply_to":"d236f925_cfbe2298","updated":"2026-01-28 19:10:50.000000000","message":"Gibi, did you mean \"old compute\" above? AFAIK, the API and conductors have to be upgraded at the same time, so we _technically_ shouldn\u0027t have a problem where a new API tries to call a conductor RPC that doesn\u0027t exist. However, if there\u0027s a dependency on the compute behavior, then we obviously need to handle that.\n\nBut yes, to your other question: if computes are not fully upgraded, the new microversion should be disallowed and the old microversion must continue to work regardless of if the computes have been partially or fully upgraded.","commit_id":"bc421b74a094bd0c47002ceb49e783fed4ec28f6"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"dd305e08db04cb23a2b0db3c1291656a51318d9c","unresolved":true,"context_lines":[{"line_number":236,"context_line":"        ) as e:"},{"line_number":237,"context_line":"            raise exc.HTTPBadRequest(explanation\u003de.format_message())"},{"line_number":238,"context_line":"        except exception.TooManyDiskDevices as e:"},{"line_number":239,"context_line":"            raise exc.HTTPForbidden(explanation\u003de.format_message())"},{"line_number":240,"context_line":""},{"line_number":241,"context_line":"        if not needs_device_returned:"},{"line_number":242,"context_line":"            # New return code starting from 2.101"}],"source_content_type":"text/x-python","patch_set":4,"id":"d236f925_cfbe2298","line":239,"in_reply_to":"f44b3ea6_51faa96e","updated":"2026-01-26 12:19:23.000000000","message":"I thought our intention was to keep the old microversion usable regardless versions of the code running. But now I\u0027m a bit hesitant about what are our exact upgrade rules to follow. \n\nSummoning @dms@danplanet.com here to help.\n\nSo to summarize my understanding. If the conductor task RPC is using the old version due to RPC pin or old nova-conductor still running. But nova-api already upgraded to the new code to always call the conductor RPC for volume attach, then we loose the possibility to use both the new and the old API microversions to attach volumes. \n\nOne way out of this is that keep the old microversion calling the compute RPC and only try to call the conductor RPC from the new microvresion. \n\nHowever I think our upgrade rules stating the upgrade all the conductors first before upgrading any other nova service. If this is a hard rule then the above situation can only happen if somebody kept the RPC pin unnecessarily low even though all the conductors are upgraded. Which can be considered a config issue not a software bug. \n\n@dms@danplanet.com How do you feel about it? (pinging you as you were part of the spec review)","commit_id":"bc421b74a094bd0c47002ceb49e783fed4ec28f6"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"18f4fe788c998a0081dd0111c2d2a4eae4b404d8","unresolved":true,"context_lines":[{"line_number":256,"context_line":"            attachment[\u0027tag\u0027] \u003d tag"},{"line_number":257,"context_line":"        if api_version_request.is_supported(req, \u00272.79\u0027):"},{"line_number":258,"context_line":"            attachment[\u0027delete_on_termination\u0027] \u003d delete_on_termination"},{"line_number":259,"context_line":"        # TODO(stephenfin): We forgot to apply 2.89 here. We should return"},{"line_number":260,"context_line":"        # \u0027bdm_uuid\u0027 and \u0027attachment_id\u0027 and stop returning \u0027id\u0027"},{"line_number":261,"context_line":"        return {\u0027volumeAttachment\u0027: attachment}"},{"line_number":262,"context_line":""},{"line_number":263,"context_line":"    def _update_volume_swap(self, req, instance, id, body):"},{"line_number":264,"context_line":"        context \u003d req.environ[\u0027nova.context\u0027]"}],"source_content_type":"text/x-python","patch_set":4,"id":"2d061ea6_6df1d944","line":261,"range":{"start_line":259,"start_character":0,"end_line":261,"end_character":47},"updated":"2026-01-19 09:45:06.000000000","message":"As you are here and adding a microversion, could you fix this as well? (feel free to disagree)\n\n// later\n\nI\u0027m stupid. :) This cannot be fixed any more as it is not part of the response in the new microversion. Could you change the TODO to a NOTE instead explaining that we missed applying 2.89 here, but we don\u0027t need it any more as 2.101 removed the whole payload.","commit_id":"bc421b74a094bd0c47002ceb49e783fed4ec28f6"},{"author":{"_account_id":26250,"name":"Johannes Kulik","email":"johannes.kulik@sap.com","username":"jkulik"},"change_message_id":"ca1b03bb86229020d1b6bfbbfbbcb8bd48e40814","unresolved":false,"context_lines":[{"line_number":256,"context_line":"            attachment[\u0027tag\u0027] \u003d tag"},{"line_number":257,"context_line":"        if api_version_request.is_supported(req, \u00272.79\u0027):"},{"line_number":258,"context_line":"            attachment[\u0027delete_on_termination\u0027] \u003d delete_on_termination"},{"line_number":259,"context_line":"        # TODO(stephenfin): We forgot to apply 2.89 here. We should return"},{"line_number":260,"context_line":"        # \u0027bdm_uuid\u0027 and \u0027attachment_id\u0027 and stop returning \u0027id\u0027"},{"line_number":261,"context_line":"        return {\u0027volumeAttachment\u0027: attachment}"},{"line_number":262,"context_line":""},{"line_number":263,"context_line":"    def _update_volume_swap(self, req, instance, id, body):"},{"line_number":264,"context_line":"        context \u003d req.environ[\u0027nova.context\u0027]"}],"source_content_type":"text/x-python","patch_set":4,"id":"82aad994_2c881e41","line":261,"range":{"start_line":259,"start_character":0,"end_line":261,"end_character":47},"in_reply_to":"2d061ea6_6df1d944","updated":"2026-01-20 14:12:57.000000000","message":"Done","commit_id":"bc421b74a094bd0c47002ceb49e783fed4ec28f6"}],"nova/compute/api.py":[{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"18f4fe788c998a0081dd0111c2d2a4eae4b404d8","unresolved":true,"context_lines":[{"line_number":5113,"context_line":"                                    vm_states.STOPPED, vm_states.RESIZED,"},{"line_number":5114,"context_line":"                                    vm_states.SOFT_DELETED, vm_states.SHELVED,"},{"line_number":5115,"context_line":"                                    vm_states.SHELVED_OFFLOADED])"},{"line_number":5116,"context_line":"    def attach_volume(self, context, instance, volume_id, device\u003dNone,"},{"line_number":5117,"context_line":"                      disk_bus\u003dNone, device_type\u003dNone, tag\u003dNone,"},{"line_number":5118,"context_line":"                      supports_multiattach\u003dFalse,"},{"line_number":5119,"context_line":"                      delete_on_termination\u003dFalse,"}],"source_content_type":"text/x-python","patch_set":4,"id":"cdd155fc_e78e6557","line":5116,"updated":"2026-01-19 09:45:06.000000000","message":"This can now raise ServiceTooOld if the new microversion is used but there is an old conductor in the cluster.","commit_id":"bc421b74a094bd0c47002ceb49e783fed4ec28f6"},{"author":{"_account_id":26250,"name":"Johannes Kulik","email":"johannes.kulik@sap.com","username":"jkulik"},"change_message_id":"54835de3d78c66bf4be31357091693deba602b86","unresolved":true,"context_lines":[{"line_number":5113,"context_line":"                                    vm_states.STOPPED, vm_states.RESIZED,"},{"line_number":5114,"context_line":"                                    vm_states.SOFT_DELETED, vm_states.SHELVED,"},{"line_number":5115,"context_line":"                                    vm_states.SHELVED_OFFLOADED])"},{"line_number":5116,"context_line":"    def attach_volume(self, context, instance, volume_id, device\u003dNone,"},{"line_number":5117,"context_line":"                      disk_bus\u003dNone, device_type\u003dNone, tag\u003dNone,"},{"line_number":5118,"context_line":"                      supports_multiattach\u003dFalse,"},{"line_number":5119,"context_line":"                      delete_on_termination\u003dFalse,"}],"source_content_type":"text/x-python","patch_set":4,"id":"c41b05c2_a8e119c2","line":5116,"in_reply_to":"08a5b057_24daa94d","updated":"2026-01-30 07:42:05.000000000","message":"I think I understand the statement, I just don\u0027t see the relevance in the context of this patch. The nova-compute RPC calls we use (`reserve_block_device_name()` and `attach_volume()`) haven\u0027t change since queens. This patch only moves the calling code from n-api into n-conductor. We don\u0027t add any new nova-compute RPC here. Hence, the version of nova-compute should not matter - unless there is somebody running nova-api on 2026.1 and nova-compute on queens/rocky.\n\nOh, or do you mean we need to safeguard for future changes of the code/RPC calls? Where we don\u0027t get BDMs back, but need to know that the feature, we requested, does not exist, yet?","commit_id":"bc421b74a094bd0c47002ceb49e783fed4ec28f6"},{"author":{"_account_id":26250,"name":"Johannes Kulik","email":"johannes.kulik@sap.com","username":"jkulik"},"change_message_id":"b78e20d009905024c5271273737207a5e7923b04","unresolved":true,"context_lines":[{"line_number":5113,"context_line":"                                    vm_states.STOPPED, vm_states.RESIZED,"},{"line_number":5114,"context_line":"                                    vm_states.SOFT_DELETED, vm_states.SHELVED,"},{"line_number":5115,"context_line":"                                    vm_states.SHELVED_OFFLOADED])"},{"line_number":5116,"context_line":"    def attach_volume(self, context, instance, volume_id, device\u003dNone,"},{"line_number":5117,"context_line":"                      disk_bus\u003dNone, device_type\u003dNone, tag\u003dNone,"},{"line_number":5118,"context_line":"                      supports_multiattach\u003dFalse,"},{"line_number":5119,"context_line":"                      delete_on_termination\u003dFalse,"}],"source_content_type":"text/x-python","patch_set":4,"id":"74e90ba7_608f590e","line":5116,"in_reply_to":"4b09c18e_7d925a7d","updated":"2026-01-29 09:06:13.000000000","message":"So, should we update the spec then? It explicitly states, that we move the functionality to the conductor and we either call or cast to it. Conductor then uses the _old_ compute APIs that n-api also called, so we\u0027ll never have a problem of too old computes.\n\n\u003e The _attach_volume() method in the current compute/api.py will be moved to the conductor task API, reachable over RPC. The API will make this delegating call to conductor for the older microversion and cast for the new one, returning the appropriate content and response code in each case.\n\nhttps://specs.openstack.org/openstack/nova-specs/specs/2026.1/approved/async-volume-attachments.html","commit_id":"bc421b74a094bd0c47002ceb49e783fed4ec28f6"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"124322f913af72a94fe37d4dd07089c6d0fdd51b","unresolved":true,"context_lines":[{"line_number":5113,"context_line":"                                    vm_states.STOPPED, vm_states.RESIZED,"},{"line_number":5114,"context_line":"                                    vm_states.SOFT_DELETED, vm_states.SHELVED,"},{"line_number":5115,"context_line":"                                    vm_states.SHELVED_OFFLOADED])"},{"line_number":5116,"context_line":"    def attach_volume(self, context, instance, volume_id, device\u003dNone,"},{"line_number":5117,"context_line":"                      disk_bus\u003dNone, device_type\u003dNone, tag\u003dNone,"},{"line_number":5118,"context_line":"                      supports_multiattach\u003dFalse,"},{"line_number":5119,"context_line":"                      delete_on_termination\u003dFalse,"}],"source_content_type":"text/x-python","patch_set":4,"id":"3ffe9b1d_f9ba74dd","line":5116,"in_reply_to":"7088ef32_0262be23","updated":"2026-02-02 14:45:06.000000000","message":"I talked about old conductor - new API situation. If that is not a supported setup then I think we are OK here as is.\n\nMaybe just adding an exception handler for TooOld to avoid returning bare HTTP500 and instead return 503 when temporarily happens that the API is newer than the conductor during an upgrade where the two services types are upgraded in parallel.","commit_id":"bc421b74a094bd0c47002ceb49e783fed4ec28f6"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"f12ba15b5607a22fea28cfa3ad3fca25f1a1edbe","unresolved":true,"context_lines":[{"line_number":5113,"context_line":"                                    vm_states.STOPPED, vm_states.RESIZED,"},{"line_number":5114,"context_line":"                                    vm_states.SOFT_DELETED, vm_states.SHELVED,"},{"line_number":5115,"context_line":"                                    vm_states.SHELVED_OFFLOADED])"},{"line_number":5116,"context_line":"    def attach_volume(self, context, instance, volume_id, device\u003dNone,"},{"line_number":5117,"context_line":"                      disk_bus\u003dNone, device_type\u003dNone, tag\u003dNone,"},{"line_number":5118,"context_line":"                      supports_multiattach\u003dFalse,"},{"line_number":5119,"context_line":"                      delete_on_termination\u003dFalse,"}],"source_content_type":"text/x-python","patch_set":4,"id":"08a5b057_24daa94d","line":5116,"in_reply_to":"74e90ba7_608f590e","updated":"2026-01-29 15:25:30.000000000","message":"Ouch, RTFM\u0027d.\n\nI guess I just forgot that we settled on that, even though what\u0027s here is not exactly what _I_ want us to do (because I don\u0027t want us communicating microversions or \"don\u0027t return me a thing\" type flags down to the lower layers). Regardless of the stylistic choice there, the old microversion _has_ to remain working with the same semantics, even with new nova-api code running.\n\nBut, the thing gibi is pointing out here is that if the API is going to delegate to the lower layers then _those_ need to check for the compute service minimum version before they allow the new behavior. If you do that after a cast, you have no way to say \"sorry, too old to do that new thing yet\" to the API consumer. Thus, checking the service version before you do is a minimum requirement before you fire off the cast.","commit_id":"bc421b74a094bd0c47002ceb49e783fed4ec28f6"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"5a12f728b0a238efddeee00e1c5a76ce599c6dca","unresolved":true,"context_lines":[{"line_number":5113,"context_line":"                                    vm_states.STOPPED, vm_states.RESIZED,"},{"line_number":5114,"context_line":"                                    vm_states.SOFT_DELETED, vm_states.SHELVED,"},{"line_number":5115,"context_line":"                                    vm_states.SHELVED_OFFLOADED])"},{"line_number":5116,"context_line":"    def attach_volume(self, context, instance, volume_id, device\u003dNone,"},{"line_number":5117,"context_line":"                      disk_bus\u003dNone, device_type\u003dNone, tag\u003dNone,"},{"line_number":5118,"context_line":"                      supports_multiattach\u003dFalse,"},{"line_number":5119,"context_line":"                      delete_on_termination\u003dFalse,"}],"source_content_type":"text/x-python","patch_set":4,"id":"7088ef32_0262be23","line":5116,"in_reply_to":"c41b05c2_a8e119c2","updated":"2026-01-30 15:29:33.000000000","message":"Okay yeah, I spent more time to re-read my own words, some of the discussion, and more of the patch here. I was thinking we were still planning to introduce a compute RPC bump to allow for not ever calling reserve first and that was wrapped up here. The concern gibi had about conductor was, I was sure, actually meant for the compute service because of that assumption. But now I\u0027m not sure _what_ gibi was concerned about, given that the conductor must be upgraded with the API and that is called out in the spec specifically:\n\nhttps://specs.openstack.org/openstack/nova-specs/specs/2026.1/approved/async-volume-attachments.html#upgrade-impact\n\nSo yep, ignore my previous complaints about the compute part but... gibi, can you elaborate?","commit_id":"bc421b74a094bd0c47002ceb49e783fed4ec28f6"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"77cf03eca42f53237c04d35ea4109560d4a9fb1e","unresolved":true,"context_lines":[{"line_number":5113,"context_line":"                                    vm_states.STOPPED, vm_states.RESIZED,"},{"line_number":5114,"context_line":"                                    vm_states.SOFT_DELETED, vm_states.SHELVED,"},{"line_number":5115,"context_line":"                                    vm_states.SHELVED_OFFLOADED])"},{"line_number":5116,"context_line":"    def attach_volume(self, context, instance, volume_id, device\u003dNone,"},{"line_number":5117,"context_line":"                      disk_bus\u003dNone, device_type\u003dNone, tag\u003dNone,"},{"line_number":5118,"context_line":"                      supports_multiattach\u003dFalse,"},{"line_number":5119,"context_line":"                      delete_on_termination\u003dFalse,"}],"source_content_type":"text/x-python","patch_set":4,"id":"4b09c18e_7d925a7d","line":5116,"in_reply_to":"cdd155fc_e78e6557","updated":"2026-01-28 19:10:50.000000000","message":"Again, I think only compute because we require conductors to be upgraded (and the conductor RPC version should handle that, if it\u0027s pinned). But as you note in the earlier file, we can\u0027t just always call the new conductor RPC here - we must refuse `needs_device_returned\u003d\u003dFalse` if compute is too old, and call the original code path if True. The latter could be only if all computes are not upgraded, but I think it\u0027s better to just keep the old behavior always if we\u0027re being synchronous, else you end up with a RPC-call-to-a-call for the synchronous path which just makes it worse.","commit_id":"bc421b74a094bd0c47002ceb49e783fed4ec28f6"}],"nova/conductor/manager.py":[{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"18f4fe788c998a0081dd0111c2d2a4eae4b404d8","unresolved":true,"context_lines":[{"line_number":2253,"context_line":"        except messaging.exceptions.MessagingTimeout:"},{"line_number":2254,"context_line":"            # The compute node might have already created the attachment but"},{"line_number":2255,"context_line":"            # we never received the answer. In this case it is safe to delete"},{"line_number":2256,"context_line":"            # the attachment as nobody will ever pick it up again."},{"line_number":2257,"context_line":"            with excutils.save_and_reraise_exception():"},{"line_number":2258,"context_line":"                try:"},{"line_number":2259,"context_line":"                    objects.BlockDeviceMapping.get_by_volume_and_instance("}],"source_content_type":"text/x-python","patch_set":4,"id":"ab3eaf5c_dc45df9f","line":2256,"updated":"2026-01-19 09:45:06.000000000","message":"This is not new but I guess here we have a race condition that could lead to leaked BDMs (a common problem reported from the field). If the compute is temporary unavailable (network outage, or nova-compute is down) then waiting for the response here can time out while the message sent to the compute is still waiting in the message bus to be consumed. In that case the below code will not see any BDM to clean as nothing was created yet. Then the compute eventually consumes the message, creates the BDM but the conductor already gave up on the attach so the compute RPC attach_volume will never be called.\n\nI don\u0027t suggest to blow up the scope of this change but If you have spare capacity it would be nice to independently from this change look that this leak.","commit_id":"bc421b74a094bd0c47002ceb49e783fed4ec28f6"},{"author":{"_account_id":26250,"name":"Johannes Kulik","email":"johannes.kulik@sap.com","username":"jkulik"},"change_message_id":"ca1b03bb86229020d1b6bfbbfbbcb8bd48e40814","unresolved":false,"context_lines":[{"line_number":2253,"context_line":"        except messaging.exceptions.MessagingTimeout:"},{"line_number":2254,"context_line":"            # The compute node might have already created the attachment but"},{"line_number":2255,"context_line":"            # we never received the answer. In this case it is safe to delete"},{"line_number":2256,"context_line":"            # the attachment as nobody will ever pick it up again."},{"line_number":2257,"context_line":"            with excutils.save_and_reraise_exception():"},{"line_number":2258,"context_line":"                try:"},{"line_number":2259,"context_line":"                    objects.BlockDeviceMapping.get_by_volume_and_instance("}],"source_content_type":"text/x-python","patch_set":4,"id":"864d258d_9cb6db65","line":2256,"in_reply_to":"ab3eaf5c_dc45df9f","updated":"2026-01-20 14:12:57.000000000","message":"Acknowledged","commit_id":"bc421b74a094bd0c47002ceb49e783fed4ec28f6"}],"nova/tests/unit/api/openstack/compute/test_volume_attachments.py":[{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"18f4fe788c998a0081dd0111c2d2a4eae4b404d8","unresolved":true,"context_lines":[{"line_number":274,"context_line":"                \u0027device\u0027: \u0027/dev/fake\u0027}}"},{"line_number":275,"context_line":"        result \u003d self.controller.create(self.req, FAKE_UUID, body\u003dbody)"},{"line_number":276,"context_line":"        if api_version_request.is_supported(self.req, \u00272.101\u0027):"},{"line_number":277,"context_line":"            return"},{"line_number":278,"context_line":"        self.assertEqual(\u002700000000-aaaa-aaaa-aaaa-000000000000\u0027,"},{"line_number":279,"context_line":"                         result[\u0027volumeAttachment\u0027][\u0027id\u0027])"},{"line_number":280,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"d3b955b4_b2036971","line":277,"updated":"2026-01-19 09:45:06.000000000","message":"alternatively you can assert the empty response here","commit_id":"bc421b74a094bd0c47002ceb49e783fed4ec28f6"},{"author":{"_account_id":26250,"name":"Johannes Kulik","email":"johannes.kulik@sap.com","username":"jkulik"},"change_message_id":"ca1b03bb86229020d1b6bfbbfbbcb8bd48e40814","unresolved":false,"context_lines":[{"line_number":274,"context_line":"                \u0027device\u0027: \u0027/dev/fake\u0027}}"},{"line_number":275,"context_line":"        result \u003d self.controller.create(self.req, FAKE_UUID, body\u003dbody)"},{"line_number":276,"context_line":"        if api_version_request.is_supported(self.req, \u00272.101\u0027):"},{"line_number":277,"context_line":"            return"},{"line_number":278,"context_line":"        self.assertEqual(\u002700000000-aaaa-aaaa-aaaa-000000000000\u0027,"},{"line_number":279,"context_line":"                         result[\u0027volumeAttachment\u0027][\u0027id\u0027])"},{"line_number":280,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"9da94afc_6c7df806","line":277,"in_reply_to":"d3b955b4_b2036971","updated":"2026-01-20 14:12:57.000000000","message":"Done","commit_id":"bc421b74a094bd0c47002ceb49e783fed4ec28f6"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"18f4fe788c998a0081dd0111c2d2a4eae4b404d8","unresolved":true,"context_lines":[{"line_number":336,"context_line":"                \u0027device\u0027: None}}"},{"line_number":337,"context_line":"        result \u003d self.controller.create(self.req, FAKE_UUID, body\u003dbody)"},{"line_number":338,"context_line":"        if api_version_request.is_supported(self.req, \u00272.101\u0027):"},{"line_number":339,"context_line":"            return"},{"line_number":340,"context_line":"        self.assertEqual(\u002700000000-aaaa-aaaa-aaaa-000000000000\u0027,"},{"line_number":341,"context_line":"                         result[\u0027volumeAttachment\u0027][\u0027id\u0027])"},{"line_number":342,"context_line":"        self.assertEqual(\u0027/dev/myfake\u0027, result[\u0027volumeAttachment\u0027][\u0027device\u0027])"}],"source_content_type":"text/x-python","patch_set":4,"id":"9618b543_5ff741b2","line":339,"updated":"2026-01-19 09:45:06.000000000","message":"ditto","commit_id":"bc421b74a094bd0c47002ceb49e783fed4ec28f6"},{"author":{"_account_id":26250,"name":"Johannes Kulik","email":"johannes.kulik@sap.com","username":"jkulik"},"change_message_id":"ca1b03bb86229020d1b6bfbbfbbcb8bd48e40814","unresolved":false,"context_lines":[{"line_number":336,"context_line":"                \u0027device\u0027: None}}"},{"line_number":337,"context_line":"        result \u003d self.controller.create(self.req, FAKE_UUID, body\u003dbody)"},{"line_number":338,"context_line":"        if api_version_request.is_supported(self.req, \u00272.101\u0027):"},{"line_number":339,"context_line":"            return"},{"line_number":340,"context_line":"        self.assertEqual(\u002700000000-aaaa-aaaa-aaaa-000000000000\u0027,"},{"line_number":341,"context_line":"                         result[\u0027volumeAttachment\u0027][\u0027id\u0027])"},{"line_number":342,"context_line":"        self.assertEqual(\u0027/dev/myfake\u0027, result[\u0027volumeAttachment\u0027][\u0027device\u0027])"}],"source_content_type":"text/x-python","patch_set":4,"id":"e7edf240_ea5086e3","line":339,"in_reply_to":"9618b543_5ff741b2","updated":"2026-01-20 14:12:57.000000000","message":"Done","commit_id":"bc421b74a094bd0c47002ceb49e783fed4ec28f6"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"18f4fe788c998a0081dd0111c2d2a4eae4b404d8","unresolved":true,"context_lines":[{"line_number":1349,"context_line":"        req \u003d self._get_req(body)"},{"line_number":1350,"context_line":"        result \u003d self.controller.create(req, FAKE_UUID, body\u003dbody)"},{"line_number":1351,"context_line":"        self.assertEqual(202, result.status_int)"},{"line_number":1352,"context_line":"        self.assertNotIn(\u0027volumeAttachment\u0027, result)"},{"line_number":1353,"context_line":"        mock_attach_volume.assert_called_once_with("},{"line_number":1354,"context_line":"            req.environ[\u0027nova.context\u0027], test.MatchType(objects.Instance),"},{"line_number":1355,"context_line":"            FAKE_UUID_A, None, tag\u003dNone, supports_multiattach\u003dTrue,"}],"source_content_type":"text/x-python","patch_set":4,"id":"322682b3_7c86a57f","line":1352,"updated":"2026-01-19 09:45:06.000000000","message":"can we check instead that the response is empty? That would be a bit more generic","commit_id":"bc421b74a094bd0c47002ceb49e783fed4ec28f6"},{"author":{"_account_id":26250,"name":"Johannes Kulik","email":"johannes.kulik@sap.com","username":"jkulik"},"change_message_id":"ca1b03bb86229020d1b6bfbbfbbcb8bd48e40814","unresolved":false,"context_lines":[{"line_number":1349,"context_line":"        req \u003d self._get_req(body)"},{"line_number":1350,"context_line":"        result \u003d self.controller.create(req, FAKE_UUID, body\u003dbody)"},{"line_number":1351,"context_line":"        self.assertEqual(202, result.status_int)"},{"line_number":1352,"context_line":"        self.assertNotIn(\u0027volumeAttachment\u0027, result)"},{"line_number":1353,"context_line":"        mock_attach_volume.assert_called_once_with("},{"line_number":1354,"context_line":"            req.environ[\u0027nova.context\u0027], test.MatchType(objects.Instance),"},{"line_number":1355,"context_line":"            FAKE_UUID_A, None, tag\u003dNone, supports_multiattach\u003dTrue,"}],"source_content_type":"text/x-python","patch_set":4,"id":"eff33002_ceb4cef2","line":1352,"in_reply_to":"322682b3_7c86a57f","updated":"2026-01-20 14:12:57.000000000","message":"Done","commit_id":"bc421b74a094bd0c47002ceb49e783fed4ec28f6"}]}
