)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":38059,"name":"Anoop Kumar Shukla","display_name":"Anoop Shukla","email":"anoop.shukla@netapp.com","username":"anoop2","status":"NetApp"},"change_message_id":"7c090d0bfaf73bd793fac678532da4326ba38db1","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"c4b756de_f4c7b416","updated":"2026-04-24 09:21:58.000000000","message":"Added some comments.","commit_id":"52a68270f4631256c52b0a9f5b170a7313218cad"},{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@everpuredata.com","username":"sdodsley"},"change_message_id":"6b6a517e4fecfc3123663d7677b44990e1165fb0","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"b50a4cec_b5e1d562","updated":"2026-04-23 16:16:14.000000000","message":"Some thoughts and comments","commit_id":"52a68270f4631256c52b0a9f5b170a7313218cad"},{"author":{"_account_id":27615,"name":"Rajat Dhasmana","email":"rajatdhasmana@gmail.com","username":"whoami-rajat"},"change_message_id":"f783f52b89fc8dbaee95f6cb2d02150b0f7e3f06","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"33d49f58_e3303df5","updated":"2026-04-29 19:48:48.000000000","message":"Thanks everyone, please find the replies inline.","commit_id":"b2db8a4ab25aed86982b4e295b3a0696a27b49cf"},{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@everpuredata.com","username":"sdodsley"},"change_message_id":"bf4e9c7afad976753ec100dd88d45b4d3321f291","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":5,"id":"71a46062_ec6c6b41","updated":"2026-07-14 15:27:23.000000000","message":"Getting closer","commit_id":"ea08aa0c7103cf8eb674982a3a51ddb567000a6b"},{"author":{"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},"change_message_id":"8ec07bf0b0cf186470277bf3611978873f94cf5b","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":5,"id":"f79cea1b_39c193b1","updated":"2026-07-16 20:42:02.000000000","message":"Left a few more comments.","commit_id":"ea08aa0c7103cf8eb674982a3a51ddb567000a6b"},{"author":{"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},"change_message_id":"1e62a506a710629ee7aa4589b29cadf5318d188c","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":5,"id":"b7d9dc52_ee7d3e24","updated":"2026-07-16 13:07:15.000000000","message":"Simon has some good comments.  I\u0027ve read about 3/4 of the way through; just have one comment inline.","commit_id":"ea08aa0c7103cf8eb674982a3a51ddb567000a6b"},{"author":{"_account_id":27615,"name":"Rajat Dhasmana","email":"rajatdhasmana@gmail.com","username":"whoami-rajat"},"change_message_id":"b8703633f27d5ae9ec3a80aadb119dd456d28887","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":5,"id":"81eccfce_4e43af77","updated":"2026-08-12 10:43:57.000000000","message":"Thanks Simon and Brian for the review.","commit_id":"ea08aa0c7103cf8eb674982a3a51ddb567000a6b"},{"author":{"_account_id":38059,"name":"Anoop Kumar Shukla","display_name":"Anoop Shukla","email":"anoop.shukla@netapp.com","username":"anoop2","status":"NetApp"},"change_message_id":"2926395df9acd462f37ef6576411d08560af5869","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":6,"id":"e665f155_f5641f58","updated":"2026-08-24 08:48:41.000000000","message":"Added some additional comments.","commit_id":"f7e9e1773c99f3f44ff9867ffee6cc6469c2f177"},{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@everpuredata.com","username":"sdodsley"},"change_message_id":"a7c812e0a11c020ae9fd4487656504c9f72ff1b3","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":6,"id":"84589345_8eed8d8e","updated":"2026-08-24 15:37:02.000000000","message":"Thanks for the rework — the Nova/BDM caveat and the exception-based auto-failover model are both improvements.\n\nThis round is mostly FlashArray-specific: four of the comments below are factual mismatches between the spec and what the FlashArray driver does today, and one of them (the `replication_type` enum) would break a shipped capability if implemented as written. There\u0027s also a naming collision with in-flight work that\u0027s worth catching now.\n\nMarking -1 for the enum and the extra-spec syntax; the rest are design gaps that I\u0027d be happy to see deferred explicitly rather than resolved here.","commit_id":"f7e9e1773c99f3f44ff9867ffee6cc6469c2f177"},{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@everpuredata.com","username":"sdodsley"},"change_message_id":"42c52bc20ba0700740801b84a5fb025809d590da","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":6,"id":"cf04a531_8486f582","updated":"2026-09-17 13:04:57.000000000","message":"This will need to move to 2027.1 now","commit_id":"f7e9e1773c99f3f44ff9867ffee6cc6469c2f177"},{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@everpuredata.com","username":"sdodsley"},"change_message_id":"473dd6da728cb3add93e82ad8120cc855ecc21c5","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":6,"id":"95c3dae5_d24d1271","updated":"2026-09-23 18:04:07.000000000","message":"please move to 2027.1","commit_id":"f7e9e1773c99f3f44ff9867ffee6cc6469c2f177"}],"specs/2026.2/replication-v3.rst":[{"author":{"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},"change_message_id":"5ae2703eb691e55263b44e92836500b90378daac","unresolved":true,"context_lines":[{"line_number":19,"context_line":"The need for a replication v3 effort emerges due to the following limitations:"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"1. **Limited Granularity**: The existing replication implementation"},{"line_number":22,"context_line":"    (v1, v2.1/Cheesecake, and Tiramisu) supports DR functionality at the"},{"line_number":23,"context_line":"    backend level and group level but certain vendors support more granularity"},{"line_number":24,"context_line":"    levels to which Cinder is currently not aware."},{"line_number":25,"context_line":""}],"source_content_type":"text/x-rst","patch_set":1,"id":"ef85a153_efcc9e45","line":22,"updated":"2026-04-23 16:33:13.000000000","message":"there\u0027s an extra space at the start of lines 22-24.  Sphinx interprets that as an indentation, and is turning this into a description list.","commit_id":"52a68270f4631256c52b0a9f5b170a7313218cad"},{"author":{"_account_id":27615,"name":"Rajat Dhasmana","email":"rajatdhasmana@gmail.com","username":"whoami-rajat"},"change_message_id":"f783f52b89fc8dbaee95f6cb2d02150b0f7e3f06","unresolved":false,"context_lines":[{"line_number":19,"context_line":"The need for a replication v3 effort emerges due to the following limitations:"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"1. **Limited Granularity**: The existing replication implementation"},{"line_number":22,"context_line":"    (v1, v2.1/Cheesecake, and Tiramisu) supports DR functionality at the"},{"line_number":23,"context_line":"    backend level and group level but certain vendors support more granularity"},{"line_number":24,"context_line":"    levels to which Cinder is currently not aware."},{"line_number":25,"context_line":""}],"source_content_type":"text/x-rst","patch_set":1,"id":"9f5f69aa_08f098c8","line":22,"in_reply_to":"ef85a153_efcc9e45","updated":"2026-04-29 19:48:48.000000000","message":"Thanks Brian! fixed for all bullet points.","commit_id":"52a68270f4631256c52b0a9f5b170a7313218cad"},{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@everpuredata.com","username":"sdodsley"},"change_message_id":"6b6a517e4fecfc3123663d7677b44990e1165fb0","unresolved":true,"context_lines":[{"line_number":27,"context_line":"    primary and secondary backend reside in the same OpenStack cluster which"},{"line_number":28,"context_line":"    is not True for some planned maintenance activities."},{"line_number":29,"context_line":""},{"line_number":30,"context_line":"3. **Sync vs Async mode**: There is no distinction on the Cinder side for"},{"line_number":31,"context_line":"    sync vs async replication and the vendor driver manages all of the"},{"line_number":32,"context_line":"    details regarding the mode of replication."},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"Additional (Optional) Scenarios:"},{"line_number":35,"context_line":""}],"source_content_type":"text/x-rst","patch_set":1,"id":"28253fdf_a4862fd1","line":32,"range":{"start_line":30,"start_character":27,"end_line":32,"end_character":46},"updated":"2026-04-23 16:16:14.000000000","message":"What does \"distinction on the Cinder side\" actually means in practice — does Cinder enforce anything, or is it purely metadata?","commit_id":"52a68270f4631256c52b0a9f5b170a7313218cad"},{"author":{"_account_id":27615,"name":"Rajat Dhasmana","email":"rajatdhasmana@gmail.com","username":"whoami-rajat"},"change_message_id":"b9222c8a6e6cac1468a0ae799a70c588e1f4e385","unresolved":false,"context_lines":[{"line_number":27,"context_line":"    primary and secondary backend reside in the same OpenStack cluster which"},{"line_number":28,"context_line":"    is not True for some planned maintenance activities."},{"line_number":29,"context_line":""},{"line_number":30,"context_line":"3. **Sync vs Async mode**: There is no distinction on the Cinder side for"},{"line_number":31,"context_line":"    sync vs async replication and the vendor driver manages all of the"},{"line_number":32,"context_line":"    details regarding the mode of replication."},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"Additional (Optional) Scenarios:"},{"line_number":35,"context_line":""}],"source_content_type":"text/x-rst","patch_set":1,"id":"79587584_a848d6d4","line":32,"range":{"start_line":30,"start_character":27,"end_line":32,"end_character":46},"in_reply_to":"139f84a4_ea9bef8e","updated":"2026-07-13 21:09:32.000000000","message":"Marked as resolved.","commit_id":"52a68270f4631256c52b0a9f5b170a7313218cad"},{"author":{"_account_id":27615,"name":"Rajat Dhasmana","email":"rajatdhasmana@gmail.com","username":"whoami-rajat"},"change_message_id":"f783f52b89fc8dbaee95f6cb2d02150b0f7e3f06","unresolved":true,"context_lines":[{"line_number":27,"context_line":"    primary and secondary backend reside in the same OpenStack cluster which"},{"line_number":28,"context_line":"    is not True for some planned maintenance activities."},{"line_number":29,"context_line":""},{"line_number":30,"context_line":"3. **Sync vs Async mode**: There is no distinction on the Cinder side for"},{"line_number":31,"context_line":"    sync vs async replication and the vendor driver manages all of the"},{"line_number":32,"context_line":"    details regarding the mode of replication."},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"Additional (Optional) Scenarios:"},{"line_number":35,"context_line":""}],"source_content_type":"text/x-rst","patch_set":1,"id":"139f84a4_ea9bef8e","line":32,"range":{"start_line":30,"start_character":27,"end_line":32,"end_character":46},"in_reply_to":"28253fdf_a4862fd1","updated":"2026-04-29 19:48:48.000000000","message":"This means that Cinder (currently) is not aware if the backend driver supports sync or async workflow and if we want to make any distinction based on it, we can\u0027t today","commit_id":"52a68270f4631256c52b0a9f5b170a7313218cad"},{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@everpuredata.com","username":"sdodsley"},"change_message_id":"6b6a517e4fecfc3123663d7677b44990e1165fb0","unresolved":true,"context_lines":[{"line_number":44,"context_line":"* As an operator, I want to failover at a more granular level to support"},{"line_number":45,"context_line":"  moving specific volumes belonging to a critical workload."},{"line_number":46,"context_line":"* As an operator, I want to be able to differentiate between synchronous"},{"line_number":47,"context_line":"  and asynchronous replication so as to determine the expected RTO and RPO."},{"line_number":48,"context_line":"* As an operator, I want the ability to failover workloads across OpenStack"},{"line_number":49,"context_line":"  deployments."},{"line_number":50,"context_line":""}],"source_content_type":"text/x-rst","patch_set":1,"id":"808c22db_012ecdfd","line":47,"range":{"start_line":47,"start_character":40,"end_line":47,"end_character":74},"updated":"2026-04-23 16:16:14.000000000","message":"if this is a goal, then the API responses should expose these or there should be a note explaining they\u0027re out of scope for v3","commit_id":"52a68270f4631256c52b0a9f5b170a7313218cad"},{"author":{"_account_id":38059,"name":"Anoop Kumar Shukla","display_name":"Anoop Shukla","email":"anoop.shukla@netapp.com","username":"anoop2","status":"NetApp"},"change_message_id":"7c090d0bfaf73bd793fac678532da4326ba38db1","unresolved":true,"context_lines":[{"line_number":44,"context_line":"* As an operator, I want to failover at a more granular level to support"},{"line_number":45,"context_line":"  moving specific volumes belonging to a critical workload."},{"line_number":46,"context_line":"* As an operator, I want to be able to differentiate between synchronous"},{"line_number":47,"context_line":"  and asynchronous replication so as to determine the expected RTO and RPO."},{"line_number":48,"context_line":"* As an operator, I want the ability to failover workloads across OpenStack"},{"line_number":49,"context_line":"  deployments."},{"line_number":50,"context_line":""}],"source_content_type":"text/x-rst","patch_set":1,"id":"db631cb6_aeec3f4b","line":47,"range":{"start_line":47,"start_character":40,"end_line":47,"end_character":74},"in_reply_to":"808c22db_012ecdfd","updated":"2026-04-24 09:21:58.000000000","message":"RPOs and RTOs cannot be determined. They need to be configured while configuring replication. So are we saying that Cinder will now provide a way to configure RTO and RPO with replication? How does that translate to APIs and Driver compatibilities?","commit_id":"52a68270f4631256c52b0a9f5b170a7313218cad"},{"author":{"_account_id":27615,"name":"Rajat Dhasmana","email":"rajatdhasmana@gmail.com","username":"whoami-rajat"},"change_message_id":"f783f52b89fc8dbaee95f6cb2d02150b0f7e3f06","unresolved":false,"context_lines":[{"line_number":44,"context_line":"* As an operator, I want to failover at a more granular level to support"},{"line_number":45,"context_line":"  moving specific volumes belonging to a critical workload."},{"line_number":46,"context_line":"* As an operator, I want to be able to differentiate between synchronous"},{"line_number":47,"context_line":"  and asynchronous replication so as to determine the expected RTO and RPO."},{"line_number":48,"context_line":"* As an operator, I want the ability to failover workloads across OpenStack"},{"line_number":49,"context_line":"  deployments."},{"line_number":50,"context_line":""}],"source_content_type":"text/x-rst","patch_set":1,"id":"b7dbb052_7616596b","line":47,"range":{"start_line":47,"start_character":40,"end_line":47,"end_character":74},"in_reply_to":"db631cb6_aeec3f4b","updated":"2026-04-29 19:48:48.000000000","message":"The intent here wasn\u0027t to determine the exact numbers for RPO and RTO rather the objective was that operators would be able to determine if there will be downtime (RTO) and data loss (RPO) in a DR scenario.\nAlso the sync vs async distinction helps cinder to make better decisions on the management path.\nRephrased it to describe it more clearly.","commit_id":"52a68270f4631256c52b0a9f5b170a7313218cad"},{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@everpuredata.com","username":"sdodsley"},"change_message_id":"6b6a517e4fecfc3123663d7677b44990e1165fb0","unresolved":true,"context_lines":[{"line_number":59,"context_line":"   * ``group``: Group-level replication"},{"line_number":60,"context_line":"   * ``pool``: All volumes in a storage pool"},{"line_number":61,"context_line":"   * ``backend``: All volumes on a backend"},{"line_number":62,"context_line":"   * ``project``: All volumes belonging to a project"},{"line_number":63,"context_line":""},{"line_number":64,"context_line":"2. **Multi-OpenStack Replication**"},{"line_number":65,"context_line":"   * Support for native APIs to export and import replicated Volume before/after failover"}],"source_content_type":"text/x-rst","patch_set":1,"id":"cf6465a9_e2398e17","line":62,"range":{"start_line":62,"start_character":0,"end_line":62,"end_character":52},"updated":"2026-04-23 16:16:14.000000000","message":"What\u0027s the behavior when a project\u0027s volumes span backends with conflicting capabilities or different replication targets?","commit_id":"52a68270f4631256c52b0a9f5b170a7313218cad"},{"author":{"_account_id":27615,"name":"Rajat Dhasmana","email":"rajatdhasmana@gmail.com","username":"whoami-rajat"},"change_message_id":"f783f52b89fc8dbaee95f6cb2d02150b0f7e3f06","unresolved":false,"context_lines":[{"line_number":59,"context_line":"   * ``group``: Group-level replication"},{"line_number":60,"context_line":"   * ``pool``: All volumes in a storage pool"},{"line_number":61,"context_line":"   * ``backend``: All volumes on a backend"},{"line_number":62,"context_line":"   * ``project``: All volumes belonging to a project"},{"line_number":63,"context_line":""},{"line_number":64,"context_line":"2. **Multi-OpenStack Replication**"},{"line_number":65,"context_line":"   * Support for native APIs to export and import replicated Volume before/after failover"}],"source_content_type":"text/x-rst","patch_set":1,"id":"25eebc8d_33945645","line":62,"range":{"start_line":62,"start_character":0,"end_line":62,"end_character":52},"in_reply_to":"ac1854e8_6c3732c8","updated":"2026-04-29 19:48:48.000000000","message":"The idea was added based on Simon\u0027s blogs regarding project Aegis[1] which relies on PG/Pod + volume types + default type per project but looks like it isn\u0027t a good candidate for the granularity here so will remove it.\n\n[1] http://theansibleguy.com/openstack-cinder-replication-and-disaster-recovery-pt-3/","commit_id":"52a68270f4631256c52b0a9f5b170a7313218cad"},{"author":{"_account_id":38059,"name":"Anoop Kumar Shukla","display_name":"Anoop Shukla","email":"anoop.shukla@netapp.com","username":"anoop2","status":"NetApp"},"change_message_id":"7c090d0bfaf73bd793fac678532da4326ba38db1","unresolved":true,"context_lines":[{"line_number":59,"context_line":"   * ``group``: Group-level replication"},{"line_number":60,"context_line":"   * ``pool``: All volumes in a storage pool"},{"line_number":61,"context_line":"   * ``backend``: All volumes on a backend"},{"line_number":62,"context_line":"   * ``project``: All volumes belonging to a project"},{"line_number":63,"context_line":""},{"line_number":64,"context_line":"2. **Multi-OpenStack Replication**"},{"line_number":65,"context_line":"   * Support for native APIs to export and import replicated Volume before/after failover"}],"source_content_type":"text/x-rst","patch_set":1,"id":"ac1854e8_6c3732c8","line":62,"range":{"start_line":62,"start_character":0,"end_line":62,"end_character":52},"in_reply_to":"cf6465a9_e2398e17","updated":"2026-04-24 09:21:58.000000000","message":"+1. A project can be using multiple backends or same backend to manage volumes. This cannot IMO span across backends and will become equivalent to backend level replication?","commit_id":"52a68270f4631256c52b0a9f5b170a7313218cad"},{"author":{"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},"change_message_id":"9927e3ef0304d307f5cef514c78f6f296e704770","unresolved":true,"context_lines":[{"line_number":61,"context_line":"   * ``backend``: All volumes on a backend"},{"line_number":62,"context_line":"   * ``project``: All volumes belonging to a project"},{"line_number":63,"context_line":""},{"line_number":64,"context_line":"2. **Multi-OpenStack Replication**"},{"line_number":65,"context_line":"   * Support for native APIs to export and import replicated Volume before/after failover"},{"line_number":66,"context_line":"   * Driver interface to export volume metadata for cross-OpenStack import"},{"line_number":67,"context_line":"   * New API to import replicated volumes from external OpenStack clouds"}],"source_content_type":"text/x-rst","patch_set":1,"id":"b3a3f5c9_9eecbdd0","line":64,"updated":"2026-04-23 16:38:16.000000000","message":"need a blank line here before the list","commit_id":"52a68270f4631256c52b0a9f5b170a7313218cad"},{"author":{"_account_id":27615,"name":"Rajat Dhasmana","email":"rajatdhasmana@gmail.com","username":"whoami-rajat"},"change_message_id":"f783f52b89fc8dbaee95f6cb2d02150b0f7e3f06","unresolved":false,"context_lines":[{"line_number":61,"context_line":"   * ``backend``: All volumes on a backend"},{"line_number":62,"context_line":"   * ``project``: All volumes belonging to a project"},{"line_number":63,"context_line":""},{"line_number":64,"context_line":"2. **Multi-OpenStack Replication**"},{"line_number":65,"context_line":"   * Support for native APIs to export and import replicated Volume before/after failover"},{"line_number":66,"context_line":"   * Driver interface to export volume metadata for cross-OpenStack import"},{"line_number":67,"context_line":"   * New API to import replicated volumes from external OpenStack clouds"}],"source_content_type":"text/x-rst","patch_set":1,"id":"e8ef0176_3ec445fe","line":64,"in_reply_to":"b3a3f5c9_9eecbdd0","updated":"2026-04-29 19:48:48.000000000","message":"Done","commit_id":"52a68270f4631256c52b0a9f5b170a7313218cad"},{"author":{"_account_id":38059,"name":"Anoop Kumar Shukla","display_name":"Anoop Shukla","email":"anoop.shukla@netapp.com","username":"anoop2","status":"NetApp"},"change_message_id":"7c090d0bfaf73bd793fac678532da4326ba38db1","unresolved":true,"context_lines":[{"line_number":67,"context_line":"   * New API to import replicated volumes from external OpenStack clouds"},{"line_number":68,"context_line":""},{"line_number":69,"context_line":"3. **Replication Modes**"},{"line_number":70,"context_line":"   * New ``replication_mode`` extra-spec with values: ``sync``, ``async``"},{"line_number":71,"context_line":"   * Driver capability reporting for supported replication modes"},{"line_number":72,"context_line":"   * API responses include current replication mode"},{"line_number":73,"context_line":""}],"source_content_type":"text/x-rst","patch_set":1,"id":"a2b3083f_4ee32722","line":70,"range":{"start_line":70,"start_character":66,"end_line":70,"end_character":71},"updated":"2026-04-24 09:21:58.000000000","message":"How are the RPO expectations going to be passed to drivers for async replication?","commit_id":"52a68270f4631256c52b0a9f5b170a7313218cad"},{"author":{"_account_id":38059,"name":"Anoop Kumar Shukla","display_name":"Anoop Shukla","email":"anoop.shukla@netapp.com","username":"anoop2","status":"NetApp"},"change_message_id":"7c090d0bfaf73bd793fac678532da4326ba38db1","unresolved":true,"context_lines":[{"line_number":67,"context_line":"   * New API to import replicated volumes from external OpenStack clouds"},{"line_number":68,"context_line":""},{"line_number":69,"context_line":"3. **Replication Modes**"},{"line_number":70,"context_line":"   * New ``replication_mode`` extra-spec with values: ``sync``, ``async``"},{"line_number":71,"context_line":"   * Driver capability reporting for supported replication modes"},{"line_number":72,"context_line":"   * API responses include current replication mode"},{"line_number":73,"context_line":""}],"source_content_type":"text/x-rst","patch_set":1,"id":"0425f9d6_00fffb28","line":70,"range":{"start_line":70,"start_character":56,"end_line":70,"end_character":61},"updated":"2026-04-24 09:21:58.000000000","message":"Sync can be of multiple types. Active Active and Active Passive. Are we planning to support both via sync?","commit_id":"52a68270f4631256c52b0a9f5b170a7313218cad"},{"author":{"_account_id":27615,"name":"Rajat Dhasmana","email":"rajatdhasmana@gmail.com","username":"whoami-rajat"},"change_message_id":"f783f52b89fc8dbaee95f6cb2d02150b0f7e3f06","unresolved":true,"context_lines":[{"line_number":67,"context_line":"   * New API to import replicated volumes from external OpenStack clouds"},{"line_number":68,"context_line":""},{"line_number":69,"context_line":"3. **Replication Modes**"},{"line_number":70,"context_line":"   * New ``replication_mode`` extra-spec with values: ``sync``, ``async``"},{"line_number":71,"context_line":"   * Driver capability reporting for supported replication modes"},{"line_number":72,"context_line":"   * API responses include current replication mode"},{"line_number":73,"context_line":""}],"source_content_type":"text/x-rst","patch_set":1,"id":"4a6c93a1_4d00a1c8","line":70,"range":{"start_line":70,"start_character":56,"end_line":70,"end_character":61},"in_reply_to":"0425f9d6_00fffb28","updated":"2026-04-29 19:48:48.000000000","message":"Depends on how many vendors support the different types and what is the recommended strategy for end users.\nI think A/A sync replication will generally be the preferred one here since it offers the best RTO and RPO numbers but correct me if my understanding is wrong.\nI want to make this simpler for Cinder otherwise we might end up with more cases for management path decisions.","commit_id":"52a68270f4631256c52b0a9f5b170a7313218cad"},{"author":{"_account_id":27615,"name":"Rajat Dhasmana","email":"rajatdhasmana@gmail.com","username":"whoami-rajat"},"change_message_id":"b9222c8a6e6cac1468a0ae799a70c588e1f4e385","unresolved":false,"context_lines":[{"line_number":67,"context_line":"   * New API to import replicated volumes from external OpenStack clouds"},{"line_number":68,"context_line":""},{"line_number":69,"context_line":"3. **Replication Modes**"},{"line_number":70,"context_line":"   * New ``replication_mode`` extra-spec with values: ``sync``, ``async``"},{"line_number":71,"context_line":"   * Driver capability reporting for supported replication modes"},{"line_number":72,"context_line":"   * API responses include current replication mode"},{"line_number":73,"context_line":""}],"source_content_type":"text/x-rst","patch_set":1,"id":"4dedb7c5_fee6d4f5","line":70,"range":{"start_line":70,"start_character":56,"end_line":70,"end_character":61},"in_reply_to":"3779cc45_233baae0","updated":"2026-07-13 21:09:32.000000000","message":"Done","commit_id":"52a68270f4631256c52b0a9f5b170a7313218cad"},{"author":{"_account_id":38059,"name":"Anoop Kumar Shukla","display_name":"Anoop Shukla","email":"anoop.shukla@netapp.com","username":"anoop2","status":"NetApp"},"change_message_id":"c063f6c5f7673e3ca93bef86e82f941ba0e7efdb","unresolved":true,"context_lines":[{"line_number":67,"context_line":"   * New API to import replicated volumes from external OpenStack clouds"},{"line_number":68,"context_line":""},{"line_number":69,"context_line":"3. **Replication Modes**"},{"line_number":70,"context_line":"   * New ``replication_mode`` extra-spec with values: ``sync``, ``async``"},{"line_number":71,"context_line":"   * Driver capability reporting for supported replication modes"},{"line_number":72,"context_line":"   * API responses include current replication mode"},{"line_number":73,"context_line":""}],"source_content_type":"text/x-rst","patch_set":1,"id":"3779cc45_233baae0","line":70,"range":{"start_line":70,"start_character":56,"end_line":70,"end_character":61},"in_reply_to":"4a6c93a1_4d00a1c8","updated":"2026-05-04 18:12:47.000000000","message":"A/A sync replications generally offer 0 RPO and near 0 RTO. The way A/A works can also be classified into symmetric (where the writes to both site are acknowledged before responding to the client) vs asymmetric (where the write to the secondary can be via a passive/proxy write from primary). In most of the A/A solutions, the failover would be automated on storage via a third party mediator. This helps with 0RPO and 0RTO as storage can immediately failover if there is a downtime discovered. Hence the classification of sync can be:\n\nsync (active/active) without mediator\nsync (active/passive) without mediator\nsync (active/active) with mediator\nsync (active/passive) with mediator.","commit_id":"52a68270f4631256c52b0a9f5b170a7313218cad"},{"author":{"_account_id":27615,"name":"Rajat Dhasmana","email":"rajatdhasmana@gmail.com","username":"whoami-rajat"},"change_message_id":"f783f52b89fc8dbaee95f6cb2d02150b0f7e3f06","unresolved":true,"context_lines":[{"line_number":67,"context_line":"   * New API to import replicated volumes from external OpenStack clouds"},{"line_number":68,"context_line":""},{"line_number":69,"context_line":"3. **Replication Modes**"},{"line_number":70,"context_line":"   * New ``replication_mode`` extra-spec with values: ``sync``, ``async``"},{"line_number":71,"context_line":"   * Driver capability reporting for supported replication modes"},{"line_number":72,"context_line":"   * API responses include current replication mode"},{"line_number":73,"context_line":""}],"source_content_type":"text/x-rst","patch_set":1,"id":"b4504fa1_62bf15c7","line":70,"range":{"start_line":70,"start_character":66,"end_line":70,"end_character":71},"in_reply_to":"a2b3083f_4ee32722","updated":"2026-04-29 19:48:48.000000000","message":"Previously I was thinking it as a capability that driver can report but I guess it doesn\u0027t add much value and dropped the idea. let me know if NetApp (or other vendors) think it will be useful","commit_id":"52a68270f4631256c52b0a9f5b170a7313218cad"},{"author":{"_account_id":38059,"name":"Anoop Kumar Shukla","display_name":"Anoop Shukla","email":"anoop.shukla@netapp.com","username":"anoop2","status":"NetApp"},"change_message_id":"c063f6c5f7673e3ca93bef86e82f941ba0e7efdb","unresolved":true,"context_lines":[{"line_number":67,"context_line":"   * New API to import replicated volumes from external OpenStack clouds"},{"line_number":68,"context_line":""},{"line_number":69,"context_line":"3. **Replication Modes**"},{"line_number":70,"context_line":"   * New ``replication_mode`` extra-spec with values: ``sync``, ``async``"},{"line_number":71,"context_line":"   * Driver capability reporting for supported replication modes"},{"line_number":72,"context_line":"   * API responses include current replication mode"},{"line_number":73,"context_line":""}],"source_content_type":"text/x-rst","patch_set":1,"id":"e1098177_71812369","line":70,"range":{"start_line":70,"start_character":66,"end_line":70,"end_character":71},"in_reply_to":"b4504fa1_62bf15c7","updated":"2026-05-04 18:12:47.000000000","message":"It definitely is useful as an async replication is defined by the RPO expectation. We have an embedded schedule resource in our policies to tweak the RPO expectations. If we just pass async, the RPO expectations will either have to be defaulted on drivers or will need to be input via cinder.conf which can become tedious.","commit_id":"52a68270f4631256c52b0a9f5b170a7313218cad"},{"author":{"_account_id":27615,"name":"Rajat Dhasmana","email":"rajatdhasmana@gmail.com","username":"whoami-rajat"},"change_message_id":"b9222c8a6e6cac1468a0ae799a70c588e1f4e385","unresolved":false,"context_lines":[{"line_number":67,"context_line":"   * New API to import replicated volumes from external OpenStack clouds"},{"line_number":68,"context_line":""},{"line_number":69,"context_line":"3. **Replication Modes**"},{"line_number":70,"context_line":"   * New ``replication_mode`` extra-spec with values: ``sync``, ``async``"},{"line_number":71,"context_line":"   * Driver capability reporting for supported replication modes"},{"line_number":72,"context_line":"   * API responses include current replication mode"},{"line_number":73,"context_line":""}],"source_content_type":"text/x-rst","patch_set":1,"id":"10a89775_f4027c55","line":70,"range":{"start_line":70,"start_character":66,"end_line":70,"end_character":71},"in_reply_to":"e1098177_71812369","updated":"2026-07-13 21:09:32.000000000","message":"let\u0027s keep this as a potential future improvement, we won\u0027t be offering numbers of RPO and RTO as part of this spec.","commit_id":"52a68270f4631256c52b0a9f5b170a7313218cad"},{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@everpuredata.com","username":"sdodsley"},"change_message_id":"6b6a517e4fecfc3123663d7677b44990e1165fb0","unresolved":true,"context_lines":[{"line_number":82,"context_line":""},{"line_number":83,"context_line":"REST API Changes"},{"line_number":84,"context_line":"----------------"},{"line_number":85,"context_line":""},{"line_number":86,"context_line":"**1. Export Volume Metadata for Cross-OpenStack Replication**"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"New API endpoint to export volume metadata for external import:"}],"source_content_type":"text/x-rst","patch_set":1,"id":"827dd558_f05c4b00","line":85,"updated":"2026-04-23 16:16:14.000000000","message":"There seems to be no failover action API - are we relying on v2 APIs here?","commit_id":"52a68270f4631256c52b0a9f5b170a7313218cad"},{"author":{"_account_id":27615,"name":"Rajat Dhasmana","email":"rajatdhasmana@gmail.com","username":"whoami-rajat"},"change_message_id":"f783f52b89fc8dbaee95f6cb2d02150b0f7e3f06","unresolved":true,"context_lines":[{"line_number":82,"context_line":""},{"line_number":83,"context_line":"REST API Changes"},{"line_number":84,"context_line":"----------------"},{"line_number":85,"context_line":""},{"line_number":86,"context_line":"**1. Export Volume Metadata for Cross-OpenStack Replication**"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"New API endpoint to export volume metadata for external import:"}],"source_content_type":"text/x-rst","patch_set":1,"id":"9b5cd204_5940e4d5","line":85,"in_reply_to":"827dd558_f05c4b00","updated":"2026-04-29 19:48:48.000000000","message":"The idea is to have a unified API \"failover\" that will dynamically make decisions  depending on the type or replication, granularity, cross openstack failover etc to call respective driver methods.","commit_id":"52a68270f4631256c52b0a9f5b170a7313218cad"},{"author":{"_account_id":27615,"name":"Rajat Dhasmana","email":"rajatdhasmana@gmail.com","username":"whoami-rajat"},"change_message_id":"b9222c8a6e6cac1468a0ae799a70c588e1f4e385","unresolved":false,"context_lines":[{"line_number":82,"context_line":""},{"line_number":83,"context_line":"REST API Changes"},{"line_number":84,"context_line":"----------------"},{"line_number":85,"context_line":""},{"line_number":86,"context_line":"**1. Export Volume Metadata for Cross-OpenStack Replication**"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"New API endpoint to export volume metadata for external import:"}],"source_content_type":"text/x-rst","patch_set":1,"id":"0835ec8e_024c5198","line":85,"in_reply_to":"9b5cd204_5940e4d5","updated":"2026-07-13 21:09:32.000000000","message":"Marked as resolved.","commit_id":"52a68270f4631256c52b0a9f5b170a7313218cad"},{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@everpuredata.com","username":"sdodsley"},"change_message_id":"6b6a517e4fecfc3123663d7677b44990e1165fb0","unresolved":true,"context_lines":[{"line_number":120,"context_line":"            ],"},{"line_number":121,"context_line":"            \"volume_metadata\": {},"},{"line_number":122,"context_line":"            \"encrypted\": true,"},{"line_number":123,"context_line":"            \"encryption_key_id\": \"barbican-key-uuid\""},{"line_number":124,"context_line":"        }"},{"line_number":125,"context_line":"    }"},{"line_number":126,"context_line":""}],"source_content_type":"text/x-rst","patch_set":1,"id":"5cbe724a_6626a238","line":123,"range":{"start_line":123,"start_character":12,"end_line":123,"end_character":52},"updated":"2026-04-23 16:16:14.000000000","message":"Barbican federation or key re-wrapping at import time needs to be addressed here. Exporting a key UUID is meaningless if the target cloud can\u0027t resolve it.","commit_id":"52a68270f4631256c52b0a9f5b170a7313218cad"},{"author":{"_account_id":27615,"name":"Rajat Dhasmana","email":"rajatdhasmana@gmail.com","username":"whoami-rajat"},"change_message_id":"f783f52b89fc8dbaee95f6cb2d02150b0f7e3f06","unresolved":false,"context_lines":[{"line_number":120,"context_line":"            ],"},{"line_number":121,"context_line":"            \"volume_metadata\": {},"},{"line_number":122,"context_line":"            \"encrypted\": true,"},{"line_number":123,"context_line":"            \"encryption_key_id\": \"barbican-key-uuid\""},{"line_number":124,"context_line":"        }"},{"line_number":125,"context_line":"    }"},{"line_number":126,"context_line":""}],"source_content_type":"text/x-rst","patch_set":1,"id":"b4546bd2_09e75065","line":123,"range":{"start_line":123,"start_character":12,"end_line":123,"end_character":52},"in_reply_to":"5cbe724a_6626a238","updated":"2026-04-29 19:48:48.000000000","message":"Makes sense, I had similar thoughts about the metadata for other services that is required for this import to succeed, so looks like encrypted volumes is unsupported with cross openstack failover operations.","commit_id":"52a68270f4631256c52b0a9f5b170a7313218cad"},{"author":{"_account_id":38059,"name":"Anoop Kumar Shukla","display_name":"Anoop Shukla","email":"anoop.shukla@netapp.com","username":"anoop2","status":"NetApp"},"change_message_id":"7c090d0bfaf73bd793fac678532da4326ba38db1","unresolved":true,"context_lines":[{"line_number":130,"context_line":"OpenStack deployment:"},{"line_number":131,"context_line":""},{"line_number":132,"context_line":"* Method: POST"},{"line_number":133,"context_line":"* URL: ``/v3/\u003cproject_id\u003e/volumes/import-replica``"},{"line_number":134,"context_line":""},{"line_number":135,"context_line":".. code-block:: json"},{"line_number":136,"context_line":""}],"source_content_type":"text/x-rst","patch_set":1,"id":"ad66ca40_2505488b","line":133,"range":{"start_line":133,"start_character":34,"end_line":133,"end_character":48},"updated":"2026-04-24 09:21:58.000000000","message":"This can only be done after failover? Will the API fail if failover is not performed?","commit_id":"52a68270f4631256c52b0a9f5b170a7313218cad"},{"author":{"_account_id":27615,"name":"Rajat Dhasmana","email":"rajatdhasmana@gmail.com","username":"whoami-rajat"},"change_message_id":"f783f52b89fc8dbaee95f6cb2d02150b0f7e3f06","unresolved":false,"context_lines":[{"line_number":130,"context_line":"OpenStack deployment:"},{"line_number":131,"context_line":""},{"line_number":132,"context_line":"* Method: POST"},{"line_number":133,"context_line":"* URL: ``/v3/\u003cproject_id\u003e/volumes/import-replica``"},{"line_number":134,"context_line":""},{"line_number":135,"context_line":".. code-block:: json"},{"line_number":136,"context_line":""}],"source_content_type":"text/x-rst","patch_set":1,"id":"716f12be_0bdf71ba","line":133,"range":{"start_line":133,"start_character":34,"end_line":133,"end_character":48},"in_reply_to":"ad66ca40_2505488b","updated":"2026-04-29 19:48:48.000000000","message":"Yes, updated the section to specify more details.","commit_id":"52a68270f4631256c52b0a9f5b170a7313218cad"},{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@everpuredata.com","username":"sdodsley"},"change_message_id":"6b6a517e4fecfc3123663d7677b44990e1165fb0","unresolved":true,"context_lines":[{"line_number":161,"context_line":"                {"},{"line_number":162,"context_line":"                    \u0027backend_id\u0027: \u0027backend-b\u0027,"},{"line_number":163,"context_line":"                    \u0027replication_mode\u0027: [\u0027sync\u0027, \u0027async\u0027],"},{"line_number":164,"context_line":"                    \u0027cross_os\u0027: False"},{"line_number":165,"context_line":"                },"},{"line_number":166,"context_line":"                {"},{"line_number":167,"context_line":"                    \u0027backend_id\u0027: \u0027remote-openstack-1\u0027,"}],"source_content_type":"text/x-rst","patch_set":1,"id":"beffe340_d6bbfc5e","line":164,"range":{"start_line":164,"start_character":20,"end_line":164,"end_character":37},"updated":"2026-04-23 16:16:14.000000000","message":"`cross_os` or `cross_cloud` - normalize?","commit_id":"52a68270f4631256c52b0a9f5b170a7313218cad"},{"author":{"_account_id":27615,"name":"Rajat Dhasmana","email":"rajatdhasmana@gmail.com","username":"whoami-rajat"},"change_message_id":"f783f52b89fc8dbaee95f6cb2d02150b0f7e3f06","unresolved":false,"context_lines":[{"line_number":161,"context_line":"                {"},{"line_number":162,"context_line":"                    \u0027backend_id\u0027: \u0027backend-b\u0027,"},{"line_number":163,"context_line":"                    \u0027replication_mode\u0027: [\u0027sync\u0027, \u0027async\u0027],"},{"line_number":164,"context_line":"                    \u0027cross_os\u0027: False"},{"line_number":165,"context_line":"                },"},{"line_number":166,"context_line":"                {"},{"line_number":167,"context_line":"                    \u0027backend_id\u0027: \u0027remote-openstack-1\u0027,"}],"source_content_type":"text/x-rst","patch_set":1,"id":"80e025dc_1d809b97","line":164,"range":{"start_line":164,"start_character":20,"end_line":164,"end_character":37},"in_reply_to":"beffe340_d6bbfc5e","updated":"2026-04-29 19:48:48.000000000","message":"cross_os indicates across openstack clusters so using that terminology","commit_id":"52a68270f4631256c52b0a9f5b170a7313218cad"},{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@everpuredata.com","username":"sdodsley"},"change_message_id":"6b6a517e4fecfc3123663d7677b44990e1165fb0","unresolved":true,"context_lines":[{"line_number":166,"context_line":"                {"},{"line_number":167,"context_line":"                    \u0027backend_id\u0027: \u0027remote-openstack-1\u0027,"},{"line_number":168,"context_line":"                    \u0027replication_mode\u0027: [\u0027async\u0027],"},{"line_number":169,"context_line":"                    \u0027cross_cloud\u0027: True,"},{"line_number":170,"context_line":"                }"},{"line_number":171,"context_line":"            ]"},{"line_number":172,"context_line":"        }"}],"source_content_type":"text/x-rst","patch_set":1,"id":"ef0e2dde_a81f4d77","line":169,"range":{"start_line":169,"start_character":21,"end_line":169,"end_character":40},"updated":"2026-04-23 16:16:14.000000000","message":"`cross_os` or `cross_cloud` - normalize?","commit_id":"52a68270f4631256c52b0a9f5b170a7313218cad"},{"author":{"_account_id":27615,"name":"Rajat Dhasmana","email":"rajatdhasmana@gmail.com","username":"whoami-rajat"},"change_message_id":"f783f52b89fc8dbaee95f6cb2d02150b0f7e3f06","unresolved":false,"context_lines":[{"line_number":166,"context_line":"                {"},{"line_number":167,"context_line":"                    \u0027backend_id\u0027: \u0027remote-openstack-1\u0027,"},{"line_number":168,"context_line":"                    \u0027replication_mode\u0027: [\u0027async\u0027],"},{"line_number":169,"context_line":"                    \u0027cross_cloud\u0027: True,"},{"line_number":170,"context_line":"                }"},{"line_number":171,"context_line":"            ]"},{"line_number":172,"context_line":"        }"}],"source_content_type":"text/x-rst","patch_set":1,"id":"3bd725e3_12929bd8","line":169,"range":{"start_line":169,"start_character":21,"end_line":169,"end_character":40},"in_reply_to":"ef0e2dde_a81f4d77","updated":"2026-04-29 19:48:48.000000000","message":"Thanks, changed this to cross_os","commit_id":"52a68270f4631256c52b0a9f5b170a7313218cad"},{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@everpuredata.com","username":"sdodsley"},"change_message_id":"6b6a517e4fecfc3123663d7677b44990e1165fb0","unresolved":true,"context_lines":[{"line_number":190,"context_line":"        \"\"\""},{"line_number":191,"context_line":"        replication_config \u003d self._get_replication_config(volume)"},{"line_number":192,"context_line":"        if replication_config.get(\u0027enabled\u0027):"},{"line_number":193,"context_line":"            mode \u003d replication_config.get(\u0027replication_mode\u0027, \u0027async\u0027)"},{"line_number":194,"context_line":"            scope \u003d replication_config.get(\u0027replication_scope\u0027, \u0027volume\u0027)"},{"line_number":195,"context_line":"            ..."},{"line_number":196,"context_line":""}],"source_content_type":"text/x-rst","patch_set":1,"id":"fcd5a1af_dea8707c","line":193,"range":{"start_line":193,"start_character":12,"end_line":193,"end_character":70},"updated":"2026-04-23 16:16:14.000000000","message":"Precedence order should be documented. If a volume type specifies sync and the config default is async, which wins? Same question for group-level overrides...","commit_id":"52a68270f4631256c52b0a9f5b170a7313218cad"},{"author":{"_account_id":27615,"name":"Rajat Dhasmana","email":"rajatdhasmana@gmail.com","username":"whoami-rajat"},"change_message_id":"f783f52b89fc8dbaee95f6cb2d02150b0f7e3f06","unresolved":false,"context_lines":[{"line_number":190,"context_line":"        \"\"\""},{"line_number":191,"context_line":"        replication_config \u003d self._get_replication_config(volume)"},{"line_number":192,"context_line":"        if replication_config.get(\u0027enabled\u0027):"},{"line_number":193,"context_line":"            mode \u003d replication_config.get(\u0027replication_mode\u0027, \u0027async\u0027)"},{"line_number":194,"context_line":"            scope \u003d replication_config.get(\u0027replication_scope\u0027, \u0027volume\u0027)"},{"line_number":195,"context_line":"            ..."},{"line_number":196,"context_line":""}],"source_content_type":"text/x-rst","patch_set":1,"id":"b94af468_9fdd8a6b","line":193,"range":{"start_line":193,"start_character":12,"end_line":193,"end_character":70},"in_reply_to":"fcd5a1af_dea8707c","updated":"2026-04-29 19:48:48.000000000","message":"The user configured values will take priority over the global default. will update here to explicity mention it.","commit_id":"52a68270f4631256c52b0a9f5b170a7313218cad"},{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@everpuredata.com","username":"sdodsley"},"change_message_id":"6b6a517e4fecfc3123663d7677b44990e1165fb0","unresolved":true,"context_lines":[{"line_number":229,"context_line":""},{"line_number":230,"context_line":"* Continue with Existing Replication Models:"},{"line_number":231,"context_line":"  We could continue using Cheesecake for backend-level failover and Tiramisu"},{"line_number":232,"context_line":"  for group-level failover. However, this doesn\u0027t address granularities,"},{"line_number":233,"context_line":"  multi-cloud and explicit sync/async differentiation requirements."},{"line_number":234,"context_line":""},{"line_number":235,"context_line":"REST API impact"},{"line_number":236,"context_line":"---------------"},{"line_number":237,"context_line":""}],"source_content_type":"text/x-rst","patch_set":1,"id":"22abd098_eaf696d5","line":234,"range":{"start_line":232,"start_character":37,"end_line":234,"end_character":0},"updated":"2026-04-23 16:16:14.000000000","message":"Add a brief note on why AZ-awareness was also not folded into this effort, since it appears in the problem description as optional but is closely related to scope granularity.","commit_id":"52a68270f4631256c52b0a9f5b170a7313218cad"},{"author":{"_account_id":27615,"name":"Rajat Dhasmana","email":"rajatdhasmana@gmail.com","username":"whoami-rajat"},"change_message_id":"f783f52b89fc8dbaee95f6cb2d02150b0f7e3f06","unresolved":false,"context_lines":[{"line_number":229,"context_line":""},{"line_number":230,"context_line":"* Continue with Existing Replication Models:"},{"line_number":231,"context_line":"  We could continue using Cheesecake for backend-level failover and Tiramisu"},{"line_number":232,"context_line":"  for group-level failover. However, this doesn\u0027t address granularities,"},{"line_number":233,"context_line":"  multi-cloud and explicit sync/async differentiation requirements."},{"line_number":234,"context_line":""},{"line_number":235,"context_line":"REST API impact"},{"line_number":236,"context_line":"---------------"},{"line_number":237,"context_line":""}],"source_content_type":"text/x-rst","patch_set":1,"id":"093e9b35_3ac94f0a","line":234,"range":{"start_line":232,"start_character":37,"end_line":234,"end_character":0},"in_reply_to":"22abd098_eaf696d5","updated":"2026-04-29 19:48:48.000000000","message":"Done","commit_id":"52a68270f4631256c52b0a9f5b170a7313218cad"},{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@everpuredata.com","username":"sdodsley"},"change_message_id":"6b6a517e4fecfc3123663d7677b44990e1165fb0","unresolved":true,"context_lines":[{"line_number":287,"context_line":""},{"line_number":288,"context_line":"* Unit test coverage for all new methods and code paths"},{"line_number":289,"context_line":"* Tempest test coverage for failover/failback and import/export APIs"},{"line_number":290,"context_line":"* Integration testing in cross-OpenStack deployments (manual)"},{"line_number":291,"context_line":""},{"line_number":292,"context_line":"Documentation Impact"},{"line_number":293,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"}],"source_content_type":"text/x-rst","patch_set":1,"id":"7d3042b0_d8b96cb2","line":290,"range":{"start_line":290,"start_character":2,"end_line":290,"end_character":61},"updated":"2026-04-23 16:16:14.000000000","message":"\"Manual\" is a red flag for a feature with this much operational risk. Should note whether CI gate coverage is planned or explicitly acknowledge this as a gap requiring follow-up.","commit_id":"52a68270f4631256c52b0a9f5b170a7313218cad"},{"author":{"_account_id":27615,"name":"Rajat Dhasmana","email":"rajatdhasmana@gmail.com","username":"whoami-rajat"},"change_message_id":"b9222c8a6e6cac1468a0ae799a70c588e1f4e385","unresolved":false,"context_lines":[{"line_number":287,"context_line":""},{"line_number":288,"context_line":"* Unit test coverage for all new methods and code paths"},{"line_number":289,"context_line":"* Tempest test coverage for failover/failback and import/export APIs"},{"line_number":290,"context_line":"* Integration testing in cross-OpenStack deployments (manual)"},{"line_number":291,"context_line":""},{"line_number":292,"context_line":"Documentation Impact"},{"line_number":293,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"}],"source_content_type":"text/x-rst","patch_set":1,"id":"be458b4f_2cb9b73c","line":290,"range":{"start_line":290,"start_character":2,"end_line":290,"end_character":61},"in_reply_to":"1ed57fb1_abd1d223","updated":"2026-07-13 21:09:32.000000000","message":"Done","commit_id":"52a68270f4631256c52b0a9f5b170a7313218cad"},{"author":{"_account_id":27615,"name":"Rajat Dhasmana","email":"rajatdhasmana@gmail.com","username":"whoami-rajat"},"change_message_id":"f783f52b89fc8dbaee95f6cb2d02150b0f7e3f06","unresolved":true,"context_lines":[{"line_number":287,"context_line":""},{"line_number":288,"context_line":"* Unit test coverage for all new methods and code paths"},{"line_number":289,"context_line":"* Tempest test coverage for failover/failback and import/export APIs"},{"line_number":290,"context_line":"* Integration testing in cross-OpenStack deployments (manual)"},{"line_number":291,"context_line":""},{"line_number":292,"context_line":"Documentation Impact"},{"line_number":293,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"}],"source_content_type":"text/x-rst","patch_set":1,"id":"e041dc66_9a83925d","line":290,"range":{"start_line":290,"start_character":2,"end_line":290,"end_character":61},"in_reply_to":"7d3042b0_d8b96cb2","updated":"2026-04-29 19:48:48.000000000","message":"There is currently no way in CI (or at least I\u0027m aware of) to deploy two openstack clusters and test features across it.\nThe operational risk part would come if the feature is productized and deployed in a large scale environment, for which, I think there will be a separate series of tests performed before supporting this at scale.\nFor the scope of opensource development, I don\u0027t think we have enough resources to automate this let alone build CI jobs to test this.","commit_id":"52a68270f4631256c52b0a9f5b170a7313218cad"},{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@everpuredata.com","username":"sdodsley"},"change_message_id":"f40ca396a786bebdc1e155afb3b2a637e662aad4","unresolved":true,"context_lines":[{"line_number":287,"context_line":""},{"line_number":288,"context_line":"* Unit test coverage for all new methods and code paths"},{"line_number":289,"context_line":"* Tempest test coverage for failover/failback and import/export APIs"},{"line_number":290,"context_line":"* Integration testing in cross-OpenStack deployments (manual)"},{"line_number":291,"context_line":""},{"line_number":292,"context_line":"Documentation Impact"},{"line_number":293,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"}],"source_content_type":"text/x-rst","patch_set":1,"id":"1ed57fb1_abd1d223","line":290,"range":{"start_line":290,"start_character":2,"end_line":290,"end_character":61},"in_reply_to":"e041dc66_9a83925d","updated":"2026-04-30 10:17:20.000000000","message":"I\u0027d add a comment about cross-cluster testing being out of scope","commit_id":"52a68270f4631256c52b0a9f5b170a7313218cad"},{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@everpuredata.com","username":"sdodsley"},"change_message_id":"f40ca396a786bebdc1e155afb3b2a637e662aad4","unresolved":true,"context_lines":[{"line_number":87,"context_line":""},{"line_number":88,"context_line":"Note that, creating a volume with a replication scope set should be"},{"line_number":89,"context_line":"mutually exclusive from the other scopes."},{"line_number":90,"context_line":"If a user has enabled backend level replication then creating individual"},{"line_number":91,"context_line":"volumes with replication_scope at volume level inside the **already**"},{"line_number":92,"context_line":"replicated backend, this operation should not be permitted."},{"line_number":93,"context_line":""},{"line_number":94,"context_line":"Along with the current proposed changes, another important use case is to"},{"line_number":95,"context_line":"perform automated failover in case of sync replication."}],"source_content_type":"text/x-rst","patch_set":2,"id":"f31ed034_96f7e0de","line":92,"range":{"start_line":90,"start_character":0,"end_line":92,"end_character":59},"updated":"2026-04-30 10:17:20.000000000","message":"Where this is enforced? Is it a Cinder API validation, a scheduler check, or delegated to the driver?","commit_id":"b2db8a4ab25aed86982b4e295b3a0696a27b49cf"},{"author":{"_account_id":27615,"name":"Rajat Dhasmana","email":"rajatdhasmana@gmail.com","username":"whoami-rajat"},"change_message_id":"b9222c8a6e6cac1468a0ae799a70c588e1f4e385","unresolved":false,"context_lines":[{"line_number":87,"context_line":""},{"line_number":88,"context_line":"Note that, creating a volume with a replication scope set should be"},{"line_number":89,"context_line":"mutually exclusive from the other scopes."},{"line_number":90,"context_line":"If a user has enabled backend level replication then creating individual"},{"line_number":91,"context_line":"volumes with replication_scope at volume level inside the **already**"},{"line_number":92,"context_line":"replicated backend, this operation should not be permitted."},{"line_number":93,"context_line":""},{"line_number":94,"context_line":"Along with the current proposed changes, another important use case is to"},{"line_number":95,"context_line":"perform automated failover in case of sync replication."}],"source_content_type":"text/x-rst","patch_set":2,"id":"99e9d8c1_fe876949","line":92,"range":{"start_line":90,"start_character":0,"end_line":92,"end_character":59},"in_reply_to":"f31ed034_96f7e0de","updated":"2026-07-13 21:09:32.000000000","message":"This is not relevant now so resolving.","commit_id":"b2db8a4ab25aed86982b4e295b3a0696a27b49cf"},{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@everpuredata.com","username":"sdodsley"},"change_message_id":"f40ca396a786bebdc1e155afb3b2a637e662aad4","unresolved":true,"context_lines":[{"line_number":114,"context_line":"will clear all the DB records so there is no scenario where"},{"line_number":115,"context_line":"the primary array coming back could lead to data corruption"},{"line_number":116,"context_line":"scenarios."},{"line_number":117,"context_line":"Note that we can only control this for the Cinder related"},{"line_number":118,"context_line":"databases and require some operation on nova side to clear"},{"line_number":119,"context_line":"out the block device mapping table(s)."},{"line_number":120,"context_line":""},{"line_number":121,"context_line":"Request:"},{"line_number":122,"context_line":""}],"source_content_type":"text/x-rst","patch_set":2,"id":"a8bf731d_7d31aeaa","line":119,"range":{"start_line":117,"start_character":0,"end_line":119,"end_character":38},"updated":"2026-04-30 10:17:20.000000000","message":"This means the export API can potentially leave Nova in an inconsistent state. This needs either a cross-project work item or an explicit note that clear_existing\u003dtrue is unsafe for attached volumes without Nova coordination.","commit_id":"b2db8a4ab25aed86982b4e295b3a0696a27b49cf"},{"author":{"_account_id":27615,"name":"Rajat Dhasmana","email":"rajatdhasmana@gmail.com","username":"whoami-rajat"},"change_message_id":"b9222c8a6e6cac1468a0ae799a70c588e1f4e385","unresolved":false,"context_lines":[{"line_number":114,"context_line":"will clear all the DB records so there is no scenario where"},{"line_number":115,"context_line":"the primary array coming back could lead to data corruption"},{"line_number":116,"context_line":"scenarios."},{"line_number":117,"context_line":"Note that we can only control this for the Cinder related"},{"line_number":118,"context_line":"databases and require some operation on nova side to clear"},{"line_number":119,"context_line":"out the block device mapping table(s)."},{"line_number":120,"context_line":""},{"line_number":121,"context_line":"Request:"},{"line_number":122,"context_line":""}],"source_content_type":"text/x-rst","patch_set":2,"id":"0bc83f4d_2e79647f","line":119,"range":{"start_line":117,"start_character":0,"end_line":119,"end_character":38},"in_reply_to":"a8bf731d_7d31aeaa","updated":"2026-07-13 21:09:32.000000000","message":"Done","commit_id":"b2db8a4ab25aed86982b4e295b3a0696a27b49cf"},{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@everpuredata.com","username":"sdodsley"},"change_message_id":"bf4e9c7afad976753ec100dd88d45b4d3321f291","unresolved":true,"context_lines":[{"line_number":11,"context_line":"https://blueprints.launchpad.net/cinder/+spec/replication-v3"},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"The current state of replication is limited in certain ways that"},{"line_number":14,"context_line":"constraints addressing new emerging industry use cases."},{"line_number":15,"context_line":""},{"line_number":16,"context_line":"Problem description"},{"line_number":17,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"}],"source_content_type":"text/x-rst","patch_set":5,"id":"9444ee5c_3b42a433","line":14,"range":{"start_line":14,"start_character":0,"end_line":14,"end_character":12},"updated":"2026-07-14 15:27:23.000000000","message":"nit: constrain","commit_id":"ea08aa0c7103cf8eb674982a3a51ddb567000a6b"},{"author":{"_account_id":27615,"name":"Rajat Dhasmana","email":"rajatdhasmana@gmail.com","username":"whoami-rajat"},"change_message_id":"b8703633f27d5ae9ec3a80aadb119dd456d28887","unresolved":false,"context_lines":[{"line_number":11,"context_line":"https://blueprints.launchpad.net/cinder/+spec/replication-v3"},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"The current state of replication is limited in certain ways that"},{"line_number":14,"context_line":"constraints addressing new emerging industry use cases."},{"line_number":15,"context_line":""},{"line_number":16,"context_line":"Problem description"},{"line_number":17,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"}],"source_content_type":"text/x-rst","patch_set":5,"id":"7c46ed52_4713cdef","line":14,"range":{"start_line":14,"start_character":0,"end_line":14,"end_character":12},"in_reply_to":"9444ee5c_3b42a433","updated":"2026-08-12 10:43:57.000000000","message":"Done","commit_id":"ea08aa0c7103cf8eb674982a3a51ddb567000a6b"},{"author":{"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},"change_message_id":"8ec07bf0b0cf186470277bf3611978873f94cf5b","unresolved":true,"context_lines":[{"line_number":56,"context_line":"   This spec addresses granularity at the backend level (existing Cheesecake/v2.1)."},{"line_number":57,"context_line":"   For finer granularity support (volume-level, group-level, pool-level), backends"},{"line_number":58,"context_line":"   should leverage the existing **Replication Groups** functionality as defined in"},{"line_number":59,"context_line":"   the Pike/Tiramisu spec [4]. Backends wanting to support these granularities"},{"line_number":60,"context_line":"   must implement the group replication driver methods (``enable_replication``,"},{"line_number":61,"context_line":"   ``disable_replication``, ``failover_replication``)."},{"line_number":62,"context_line":""}],"source_content_type":"text/x-rst","patch_set":5,"id":"ebb5b37c_c3c1534b","line":59,"updated":"2026-07-16 20:42:02.000000000","message":"Question about volume-level granularity.  Tiramisu/mv3.38 gives you volume-level indirectly by making a volume the only member of a replication group, is that correct?","commit_id":"ea08aa0c7103cf8eb674982a3a51ddb567000a6b"},{"author":{"_account_id":27615,"name":"Rajat Dhasmana","email":"rajatdhasmana@gmail.com","username":"whoami-rajat"},"change_message_id":"b8703633f27d5ae9ec3a80aadb119dd456d28887","unresolved":false,"context_lines":[{"line_number":56,"context_line":"   This spec addresses granularity at the backend level (existing Cheesecake/v2.1)."},{"line_number":57,"context_line":"   For finer granularity support (volume-level, group-level, pool-level), backends"},{"line_number":58,"context_line":"   should leverage the existing **Replication Groups** functionality as defined in"},{"line_number":59,"context_line":"   the Pike/Tiramisu spec [4]. Backends wanting to support these granularities"},{"line_number":60,"context_line":"   must implement the group replication driver methods (``enable_replication``,"},{"line_number":61,"context_line":"   ``disable_replication``, ``failover_replication``)."},{"line_number":62,"context_line":""}],"source_content_type":"text/x-rst","patch_set":5,"id":"2c919b42_3e43d1da","line":59,"in_reply_to":"ebb5b37c_c3c1534b","updated":"2026-08-12 10:43:57.000000000","message":"Yes, correct. A group can contain 1 or more volumes so it is flexible across any user identified container (like group containing all volumes of a particular tenant whether it\u0027s 1 volume or 100)","commit_id":"ea08aa0c7103cf8eb674982a3a51ddb567000a6b"},{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@everpuredata.com","username":"sdodsley"},"change_message_id":"bf4e9c7afad976753ec100dd88d45b4d3321f291","unresolved":true,"context_lines":[{"line_number":104,"context_line":""},{"line_number":105,"context_line":"Along with the current proposed changes, another important use case is to"},{"line_number":106,"context_line":"perform automated failover in case of sync replication."},{"line_number":107,"context_line":"This requires drivers to report a signal indicating that the backend is down"},{"line_number":108,"context_line":"and an automated failover can be performed. Since the data paths switch"},{"line_number":109,"context_line":"automatically, the expectation is from Cinder to switch the management paths"},{"line_number":110,"context_line":"automatically as well which requires periodic interaction between the driver"},{"line_number":111,"context_line":"and Cinder volume service."},{"line_number":112,"context_line":""},{"line_number":113,"context_line":"REST API Changes"},{"line_number":114,"context_line":"----------------"}],"source_content_type":"text/x-rst","patch_set":5,"id":"aaa64695_12ae453e","line":111,"range":{"start_line":107,"start_character":0,"end_line":111,"end_character":26},"updated":"2026-07-14 15:27:23.000000000","message":"this needs more work - how is the signal reported, what polls for it? maybe thi sis follow-on work, in which case this should be noted.","commit_id":"ea08aa0c7103cf8eb674982a3a51ddb567000a6b"},{"author":{"_account_id":27615,"name":"Rajat Dhasmana","email":"rajatdhasmana@gmail.com","username":"whoami-rajat"},"change_message_id":"b8703633f27d5ae9ec3a80aadb119dd456d28887","unresolved":false,"context_lines":[{"line_number":104,"context_line":""},{"line_number":105,"context_line":"Along with the current proposed changes, another important use case is to"},{"line_number":106,"context_line":"perform automated failover in case of sync replication."},{"line_number":107,"context_line":"This requires drivers to report a signal indicating that the backend is down"},{"line_number":108,"context_line":"and an automated failover can be performed. Since the data paths switch"},{"line_number":109,"context_line":"automatically, the expectation is from Cinder to switch the management paths"},{"line_number":110,"context_line":"automatically as well which requires periodic interaction between the driver"},{"line_number":111,"context_line":"and Cinder volume service."},{"line_number":112,"context_line":""},{"line_number":113,"context_line":"REST API Changes"},{"line_number":114,"context_line":"----------------"}],"source_content_type":"text/x-rst","patch_set":5,"id":"fe206375_ab728dc0","line":111,"range":{"start_line":107,"start_character":0,"end_line":111,"end_character":26},"in_reply_to":"8e901cb1_e520950d","updated":"2026-08-12 10:43:57.000000000","message":"Thanks for the feedback, I\u0027m rethinking this in context of volume groups where the backend switch doesn\u0027t happen, the \"special exception\" approach is interesting, will explore on that and update here.","commit_id":"ea08aa0c7103cf8eb674982a3a51ddb567000a6b"},{"author":{"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},"change_message_id":"1e62a506a710629ee7aa4589b29cadf5318d188c","unresolved":true,"context_lines":[{"line_number":104,"context_line":""},{"line_number":105,"context_line":"Along with the current proposed changes, another important use case is to"},{"line_number":106,"context_line":"perform automated failover in case of sync replication."},{"line_number":107,"context_line":"This requires drivers to report a signal indicating that the backend is down"},{"line_number":108,"context_line":"and an automated failover can be performed. Since the data paths switch"},{"line_number":109,"context_line":"automatically, the expectation is from Cinder to switch the management paths"},{"line_number":110,"context_line":"automatically as well which requires periodic interaction between the driver"},{"line_number":111,"context_line":"and Cinder volume service."},{"line_number":112,"context_line":""},{"line_number":113,"context_line":"REST API Changes"},{"line_number":114,"context_line":"----------------"}],"source_content_type":"text/x-rst","patch_set":5,"id":"8e901cb1_e520950d","line":111,"range":{"start_line":107,"start_character":0,"end_line":111,"end_character":26},"in_reply_to":"aaa64695_12ae453e","updated":"2026-07-16 13:07:15.000000000","message":"By assumption, the data paths have switched automatically, so we don\u0027t need to worry about in-use volumes.  So cinder really doesn\u0027t need to know anything until the first time it interacts with the driver after the backend-switch event.  Instead of polling, maybe the driver raises a special exception when a backend-switch has occurred, and that\u0027s how cinder knows to change management paths?","commit_id":"ea08aa0c7103cf8eb674982a3a51ddb567000a6b"},{"author":{"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},"change_message_id":"8ec07bf0b0cf186470277bf3611978873f94cf5b","unresolved":true,"context_lines":[{"line_number":113,"context_line":"REST API Changes"},{"line_number":114,"context_line":"----------------"},{"line_number":115,"context_line":""},{"line_number":116,"context_line":"**1. Export Volume Metadata for Cross-OpenStack Replication**"},{"line_number":117,"context_line":""},{"line_number":118,"context_line":"New API endpoint to export volume metadata for external import:"},{"line_number":119,"context_line":""}],"source_content_type":"text/x-rst","patch_set":5,"id":"8c459f87_a781d80a","line":116,"range":{"start_line":116,"start_character":5,"end_line":116,"end_character":27},"updated":"2026-07-16 20:42:02.000000000","message":"nit: I suggest calling this \"Export Volume Replication Metadata\" (since it\u0027s more than what what we usually call \"volume metadata\" (i.e., the response to /v3/volumes/{volume_id}/metadata))","commit_id":"ea08aa0c7103cf8eb674982a3a51ddb567000a6b"},{"author":{"_account_id":27615,"name":"Rajat Dhasmana","email":"rajatdhasmana@gmail.com","username":"whoami-rajat"},"change_message_id":"b8703633f27d5ae9ec3a80aadb119dd456d28887","unresolved":false,"context_lines":[{"line_number":113,"context_line":"REST API Changes"},{"line_number":114,"context_line":"----------------"},{"line_number":115,"context_line":""},{"line_number":116,"context_line":"**1. Export Volume Metadata for Cross-OpenStack Replication**"},{"line_number":117,"context_line":""},{"line_number":118,"context_line":"New API endpoint to export volume metadata for external import:"},{"line_number":119,"context_line":""}],"source_content_type":"text/x-rst","patch_set":5,"id":"355e6fb9_66c27636","line":116,"range":{"start_line":116,"start_character":5,"end_line":116,"end_character":27},"in_reply_to":"8c459f87_a781d80a","updated":"2026-08-12 10:43:57.000000000","message":"Done","commit_id":"ea08aa0c7103cf8eb674982a3a51ddb567000a6b"},{"author":{"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},"change_message_id":"8ec07bf0b0cf186470277bf3611978873f94cf5b","unresolved":true,"context_lines":[{"line_number":118,"context_line":"New API endpoint to export volume metadata for external import:"},{"line_number":119,"context_line":""},{"line_number":120,"context_line":"* Method: POST"},{"line_number":121,"context_line":"* URL: ``/v3/\u003cproject_id\u003e/volumes/\u003cvolume_uuid\u003e/action``"},{"line_number":122,"context_line":""},{"line_number":123,"context_line":"The export should be performed after the volume has failed over."},{"line_number":124,"context_line":"This API also aacepts a parameter ``clear_existing`` which"}],"source_content_type":"text/x-rst","patch_set":5,"id":"0c3917a8_b4cac9de","line":121,"range":{"start_line":121,"start_character":26,"end_line":121,"end_character":33},"updated":"2026-07-16 20:42:02.000000000","message":"It seems a bit odd to make this volume-based if replication is group based, but maybe this is better so that if there\u0027s a problem with one of the volumes in the group, this call would error for that volume (instead of the caller having to sort through a list to figure out which volumes we have metadata for and which ones failed).  I guess the way you\u0027d get the list of volumes is to make the show-group-details call to mv3.38 (so you will get replication status) with \"?list_volume\u003dtrue\"?","commit_id":"ea08aa0c7103cf8eb674982a3a51ddb567000a6b"},{"author":{"_account_id":27615,"name":"Rajat Dhasmana","email":"rajatdhasmana@gmail.com","username":"whoami-rajat"},"change_message_id":"b8703633f27d5ae9ec3a80aadb119dd456d28887","unresolved":false,"context_lines":[{"line_number":118,"context_line":"New API endpoint to export volume metadata for external import:"},{"line_number":119,"context_line":""},{"line_number":120,"context_line":"* Method: POST"},{"line_number":121,"context_line":"* URL: ``/v3/\u003cproject_id\u003e/volumes/\u003cvolume_uuid\u003e/action``"},{"line_number":122,"context_line":""},{"line_number":123,"context_line":"The export should be performed after the volume has failed over."},{"line_number":124,"context_line":"This API also aacepts a parameter ``clear_existing`` which"}],"source_content_type":"text/x-rst","patch_set":5,"id":"5570759c_e4aaa20d","line":121,"range":{"start_line":121,"start_character":26,"end_line":121,"end_character":33},"in_reply_to":"0c3917a8_b4cac9de","updated":"2026-08-12 10:43:57.000000000","message":"This is intentional by design since it\u0027s easy to automate it for multiple volumes from the administrator side rather than Cinder handling all of the volumes metadata in one go and handling case for each of them going wrong failing/passing the operation as a whole.","commit_id":"ea08aa0c7103cf8eb674982a3a51ddb567000a6b"},{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@everpuredata.com","username":"sdodsley"},"change_message_id":"bf4e9c7afad976753ec100dd88d45b4d3321f291","unresolved":true,"context_lines":[{"line_number":121,"context_line":"* URL: ``/v3/\u003cproject_id\u003e/volumes/\u003cvolume_uuid\u003e/action``"},{"line_number":122,"context_line":""},{"line_number":123,"context_line":"The export should be performed after the volume has failed over."},{"line_number":124,"context_line":"This API also aacepts a parameter ``clear_existing`` which"},{"line_number":125,"context_line":"will clear all the DB records so there is no scenario where"},{"line_number":126,"context_line":"the primary array coming back could lead to data corruption"},{"line_number":127,"context_line":"scenarios."}],"source_content_type":"text/x-rst","patch_set":5,"id":"b7b52f32_f6360bd9","line":124,"range":{"start_line":124,"start_character":14,"end_line":124,"end_character":22},"updated":"2026-07-14 15:27:23.000000000","message":"nit: accepts","commit_id":"ea08aa0c7103cf8eb674982a3a51ddb567000a6b"},{"author":{"_account_id":27615,"name":"Rajat Dhasmana","email":"rajatdhasmana@gmail.com","username":"whoami-rajat"},"change_message_id":"b8703633f27d5ae9ec3a80aadb119dd456d28887","unresolved":false,"context_lines":[{"line_number":121,"context_line":"* URL: ``/v3/\u003cproject_id\u003e/volumes/\u003cvolume_uuid\u003e/action``"},{"line_number":122,"context_line":""},{"line_number":123,"context_line":"The export should be performed after the volume has failed over."},{"line_number":124,"context_line":"This API also aacepts a parameter ``clear_existing`` which"},{"line_number":125,"context_line":"will clear all the DB records so there is no scenario where"},{"line_number":126,"context_line":"the primary array coming back could lead to data corruption"},{"line_number":127,"context_line":"scenarios."}],"source_content_type":"text/x-rst","patch_set":5,"id":"8d89dbc0_47ad3f5f","line":124,"range":{"start_line":124,"start_character":14,"end_line":124,"end_character":22},"in_reply_to":"b7b52f32_f6360bd9","updated":"2026-08-12 10:43:57.000000000","message":"Done","commit_id":"ea08aa0c7103cf8eb674982a3a51ddb567000a6b"},{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@everpuredata.com","username":"sdodsley"},"change_message_id":"bf4e9c7afad976753ec100dd88d45b4d3321f291","unresolved":true,"context_lines":[{"line_number":164,"context_line":"                    \"replication_mode\": \"async\""},{"line_number":165,"context_line":"                }"},{"line_number":166,"context_line":"            ],"},{"line_number":167,"context_line":"            \"volume_metadata\": {},"},{"line_number":168,"context_line":"        }"},{"line_number":169,"context_line":"    }"},{"line_number":170,"context_line":""}],"source_content_type":"text/x-rst","patch_set":5,"id":"a6e98f46_8b7aa416","line":167,"range":{"start_line":167,"start_character":33,"end_line":167,"end_character":34},"updated":"2026-07-14 15:27:23.000000000","message":"nit: remove trailing comma","commit_id":"ea08aa0c7103cf8eb674982a3a51ddb567000a6b"},{"author":{"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},"change_message_id":"8ec07bf0b0cf186470277bf3611978873f94cf5b","unresolved":true,"context_lines":[{"line_number":164,"context_line":"                    \"replication_mode\": \"async\""},{"line_number":165,"context_line":"                }"},{"line_number":166,"context_line":"            ],"},{"line_number":167,"context_line":"            \"volume_metadata\": {},"},{"line_number":168,"context_line":"        }"},{"line_number":169,"context_line":"    }"},{"line_number":170,"context_line":""}],"source_content_type":"text/x-rst","patch_set":5,"id":"c674a27c_c6dbcc09","line":167,"range":{"start_line":167,"start_character":33,"end_line":167,"end_character":34},"in_reply_to":"a6e98f46_8b7aa416","updated":"2026-07-16 20:42:02.000000000","message":"Also, Is this just the volume metadata, or also the volume image metadata?  Do we need to worry about the volume admin metadata?  Also, there\u0027s the vendor metadata from the export_replication_metadata() call that I guess would get mixed in here too.","commit_id":"ea08aa0c7103cf8eb674982a3a51ddb567000a6b"},{"author":{"_account_id":27615,"name":"Rajat Dhasmana","email":"rajatdhasmana@gmail.com","username":"whoami-rajat"},"change_message_id":"b8703633f27d5ae9ec3a80aadb119dd456d28887","unresolved":false,"context_lines":[{"line_number":164,"context_line":"                    \"replication_mode\": \"async\""},{"line_number":165,"context_line":"                }"},{"line_number":166,"context_line":"            ],"},{"line_number":167,"context_line":"            \"volume_metadata\": {},"},{"line_number":168,"context_line":"        }"},{"line_number":169,"context_line":"    }"},{"line_number":170,"context_line":""}],"source_content_type":"text/x-rst","patch_set":5,"id":"235ed9fb_122f5844","line":167,"range":{"start_line":167,"start_character":33,"end_line":167,"end_character":34},"in_reply_to":"c674a27c_c6dbcc09","updated":"2026-08-12 10:43:57.000000000","message":"Since we want to recreate the whole volume on secondary site, we really need to include all the metadata for it to function the same way as on primary site so yes, it includes all types of metadata.\nRegarding the admin metadata, we can use a symmetric key that encrypts the admin metadata before export and decrypts it during import (note that it needs to be pre-configured in both source and target deployments)","commit_id":"ea08aa0c7103cf8eb674982a3a51ddb567000a6b"},{"author":{"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},"change_message_id":"8ec07bf0b0cf186470277bf3611978873f94cf5b","unresolved":true,"context_lines":[{"line_number":168,"context_line":"        }"},{"line_number":169,"context_line":"    }"},{"line_number":170,"context_line":""},{"line_number":171,"context_line":"**2. Import Replicated Volume from External OpenStack**"},{"line_number":172,"context_line":""},{"line_number":173,"context_line":"New API endpoint to import a volume that was replicated from another"},{"line_number":174,"context_line":"OpenStack deployment:"}],"source_content_type":"text/x-rst","patch_set":5,"id":"9e04db37_2b47c272","line":171,"range":{"start_line":171,"start_character":5,"end_line":171,"end_character":29},"updated":"2026-07-16 20:42:02.000000000","message":"nit: \"Import Volume Replication Metadata\"","commit_id":"ea08aa0c7103cf8eb674982a3a51ddb567000a6b"},{"author":{"_account_id":27615,"name":"Rajat Dhasmana","email":"rajatdhasmana@gmail.com","username":"whoami-rajat"},"change_message_id":"b8703633f27d5ae9ec3a80aadb119dd456d28887","unresolved":false,"context_lines":[{"line_number":168,"context_line":"        }"},{"line_number":169,"context_line":"    }"},{"line_number":170,"context_line":""},{"line_number":171,"context_line":"**2. Import Replicated Volume from External OpenStack**"},{"line_number":172,"context_line":""},{"line_number":173,"context_line":"New API endpoint to import a volume that was replicated from another"},{"line_number":174,"context_line":"OpenStack deployment:"}],"source_content_type":"text/x-rst","patch_set":5,"id":"4d394eb4_ccf82c90","line":171,"range":{"start_line":171,"start_character":5,"end_line":171,"end_character":29},"in_reply_to":"9e04db37_2b47c272","updated":"2026-08-12 10:43:57.000000000","message":"Done","commit_id":"ea08aa0c7103cf8eb674982a3a51ddb567000a6b"},{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@everpuredata.com","username":"sdodsley"},"change_message_id":"bf4e9c7afad976753ec100dd88d45b4d3321f291","unresolved":true,"context_lines":[{"line_number":225,"context_line":"    def get_volume_stats(self, refresh\u003dFalse):"},{"line_number":226,"context_line":"        stats \u003d {"},{"line_number":227,"context_line":"            \u0027replication_enabled\u0027: True,"},{"line_number":228,"context_line":"            \u0027replication_type\u0027: [\u0027sync\u0027, \u0027async\u0027],"},{"line_number":229,"context_line":"            \u0027replication_targets\u0027: ["},{"line_number":230,"context_line":"                {"},{"line_number":231,"context_line":"                    \u0027backend_id\u0027: \u0027backend-b\u0027,"}],"source_content_type":"text/x-rst","patch_set":5,"id":"e8b24a6d_da591bd8","line":228,"range":{"start_line":228,"start_character":13,"end_line":228,"end_character":29},"updated":"2026-07-14 15:27:23.000000000","message":"you use ``replication_mode`` everywhere else, so this is confusing - what\u0027s the difference? Check which is the current value, I think ``type``, so the values in ``replication_target`` should also be ``type``","commit_id":"ea08aa0c7103cf8eb674982a3a51ddb567000a6b"},{"author":{"_account_id":27615,"name":"Rajat Dhasmana","email":"rajatdhasmana@gmail.com","username":"whoami-rajat"},"change_message_id":"b8703633f27d5ae9ec3a80aadb119dd456d28887","unresolved":false,"context_lines":[{"line_number":225,"context_line":"    def get_volume_stats(self, refresh\u003dFalse):"},{"line_number":226,"context_line":"        stats \u003d {"},{"line_number":227,"context_line":"            \u0027replication_enabled\u0027: True,"},{"line_number":228,"context_line":"            \u0027replication_type\u0027: [\u0027sync\u0027, \u0027async\u0027],"},{"line_number":229,"context_line":"            \u0027replication_targets\u0027: ["},{"line_number":230,"context_line":"                {"},{"line_number":231,"context_line":"                    \u0027backend_id\u0027: \u0027backend-b\u0027,"}],"source_content_type":"text/x-rst","patch_set":5,"id":"31dd2292_75b17043","line":228,"range":{"start_line":228,"start_character":13,"end_line":228,"end_character":29},"in_reply_to":"e8b24a6d_da591bd8","updated":"2026-08-12 10:43:57.000000000","message":"Done","commit_id":"ea08aa0c7103cf8eb674982a3a51ddb567000a6b"},{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@everpuredata.com","username":"sdodsley"},"change_message_id":"bf4e9c7afad976753ec100dd88d45b4d3321f291","unresolved":true,"context_lines":[{"line_number":324,"context_line":"Other deployer impact"},{"line_number":325,"context_line":"---------------------"},{"line_number":326,"context_line":""},{"line_number":327,"context_line":"No new configuration options are required. The new v3 replication features"},{"line_number":328,"context_line":"(export/import APIs, replication mode support) will be available via a new"},{"line_number":329,"context_line":"microversion. Operators can use the existing replication configuration for"},{"line_number":330,"context_line":"their backends."}],"source_content_type":"text/x-rst","patch_set":5,"id":"b0b31ebf_d3693268","line":327,"range":{"start_line":327,"start_character":0,"end_line":327,"end_character":42},"updated":"2026-07-14 15:27:23.000000000","message":"this is contradictory to the async RPO expectation. there must be some parameter to pass to the backend to define the RPO, or it uses a default value in the backend. Many backends could support an RPO specification. Pure already has these options.","commit_id":"ea08aa0c7103cf8eb674982a3a51ddb567000a6b"},{"author":{"_account_id":27615,"name":"Rajat Dhasmana","email":"rajatdhasmana@gmail.com","username":"whoami-rajat"},"change_message_id":"b8703633f27d5ae9ec3a80aadb119dd456d28887","unresolved":false,"context_lines":[{"line_number":324,"context_line":"Other deployer impact"},{"line_number":325,"context_line":"---------------------"},{"line_number":326,"context_line":""},{"line_number":327,"context_line":"No new configuration options are required. The new v3 replication features"},{"line_number":328,"context_line":"(export/import APIs, replication mode support) will be available via a new"},{"line_number":329,"context_line":"microversion. Operators can use the existing replication configuration for"},{"line_number":330,"context_line":"their backends."}],"source_content_type":"text/x-rst","patch_set":5,"id":"0419b57e_42686613","line":327,"range":{"start_line":327,"start_character":0,"end_line":327,"end_character":42},"in_reply_to":"b0b31ebf_d3693268","updated":"2026-08-12 10:43:57.000000000","message":"I\u0027ve made the RPO spec as out of scope for Cinder as of now, maybe later we can revisit it and provide the option to make it configurable via Cinder.","commit_id":"ea08aa0c7103cf8eb674982a3a51ddb567000a6b"},{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@everpuredata.com","username":"sdodsley"},"change_message_id":"a7c812e0a11c020ae9fd4487656504c9f72ff1b3","unresolved":true,"context_lines":[{"line_number":27,"context_line":"   details regarding the mode of replication."},{"line_number":28,"context_line":""},{"line_number":29,"context_line":".. note::"},{"line_number":30,"context_line":"   Granularity support (backend-level and group-level) is already available"},{"line_number":31,"context_line":"   via Cheesecake (v2.1) and Tiramisu/Replication Groups specs. This v3 spec"},{"line_number":32,"context_line":"   focuses on cross-OpenStack replication and replication mode awareness."},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"Additional (Optional) Scenarios:"},{"line_number":35,"context_line":""}],"source_content_type":"text/x-rst","patch_set":6,"id":"c5d81ed2_70e23af6","line":32,"range":{"start_line":30,"start_character":0,"end_line":32,"end_character":73},"updated":"2026-08-24 15:37:02.000000000","message":"Maybe reword to \"Granularity support is available to backends that implement the Tiramisu group replication driver methods\", so this isn\u0027t overstating the current state.","commit_id":"f7e9e1773c99f3f44ff9867ffee6cc6469c2f177"},{"author":{"_account_id":38059,"name":"Anoop Kumar Shukla","display_name":"Anoop Shukla","email":"anoop.shukla@netapp.com","username":"anoop2","status":"NetApp"},"change_message_id":"2926395df9acd462f37ef6576411d08560af5869","unresolved":true,"context_lines":[{"line_number":57,"context_line":"   For finer granularity support (volume-level, group-level, pool-level), backends"},{"line_number":58,"context_line":"   should leverage the existing **Replication Groups** functionality as defined in"},{"line_number":59,"context_line":"   the Pike/Tiramisu spec [4]. Backends wanting to support these granularities"},{"line_number":60,"context_line":"   must implement the group replication driver methods (``enable_replication``,"},{"line_number":61,"context_line":"   ``disable_replication``, ``failover_replication``). Note that volume-level"},{"line_number":62,"context_line":"   granularity is achieved indirectly through Replication Groups by creating"},{"line_number":63,"context_line":"   a group containing a single volume; there is no separate volume-only"}],"source_content_type":"text/x-rst","patch_set":6,"id":"815d2433_8d9900ba","line":60,"range":{"start_line":60,"start_character":58,"end_line":60,"end_character":76},"updated":"2026-08-24 08:48:41.000000000","message":"Some drivers implement pool-level consistent replication using consistency groups (eg. NetApp via netapp_consistent_replication) which is orthogonal to Cinder Replication Groups (enable_replication / failover_replication). Operators may confuse the two; a short note in the spec would help.","commit_id":"f7e9e1773c99f3f44ff9867ffee6cc6469c2f177"},{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@everpuredata.com","username":"sdodsley"},"change_message_id":"a7c812e0a11c020ae9fd4487656504c9f72ff1b3","unresolved":true,"context_lines":[{"line_number":57,"context_line":"   For finer granularity support (volume-level, group-level, pool-level), backends"},{"line_number":58,"context_line":"   should leverage the existing **Replication Groups** functionality as defined in"},{"line_number":59,"context_line":"   the Pike/Tiramisu spec [4]. Backends wanting to support these granularities"},{"line_number":60,"context_line":"   must implement the group replication driver methods (``enable_replication``,"},{"line_number":61,"context_line":"   ``disable_replication``, ``failover_replication``). Note that volume-level"},{"line_number":62,"context_line":"   granularity is achieved indirectly through Replication Groups by creating"},{"line_number":63,"context_line":"   a group containing a single volume; there is no separate volume-only"}],"source_content_type":"text/x-rst","patch_set":6,"id":"4c82d1ff_6b7e70aa","line":60,"range":{"start_line":60,"start_character":58,"end_line":60,"end_character":76},"in_reply_to":"815d2433_8d9900ba","updated":"2026-08-24 15:37:02.000000000","message":"Worth stating plainly that for backends currently advertising `consistent_group_replication_enabled` without those methods, this is net-new driver work, and that it isn\u0027t captured in Work Items. It\u0027s a bigger lift than it looks: a group-scoped failover cannot move the driver\u0027s current array the way `failover_host()` does, so the driver needs per-volume array resolution for every subsequent operation. See the comment on line 246 about `replication_driver_data`.","commit_id":"f7e9e1773c99f3f44ff9867ffee6cc6469c2f177"},{"author":{"_account_id":38059,"name":"Anoop Kumar Shukla","display_name":"Anoop Shukla","email":"anoop.shukla@netapp.com","username":"anoop2","status":"NetApp"},"change_message_id":"2926395df9acd462f37ef6576411d08560af5869","unresolved":true,"context_lines":[{"line_number":72,"context_line":""},{"line_number":73,"context_line":"3. **Replication Modes**"},{"line_number":74,"context_line":""},{"line_number":75,"context_line":"   * New ``replication_type`` extra-spec with values: ``sync``, ``async``"},{"line_number":76,"context_line":"   * Driver capability reporting for supported replication modes"},{"line_number":77,"context_line":"   * API responses include current replication mode"},{"line_number":78,"context_line":""}],"source_content_type":"text/x-rst","patch_set":6,"id":"ec53f70e_209fb07b","line":75,"range":{"start_line":75,"start_character":30,"end_line":75,"end_character":41},"updated":"2026-08-24 08:48:41.000000000","message":"NetApp selects sync vs async via netapp_replication_policy at the backend stanza, not per-volume extra-specs. All volumes on that backend share one SnapMirror policy. Please clarify precedence when both backend config and volume-type replication_type are set, and whether extra-spec applies to backend-level replication vs only volume/group replication","commit_id":"f7e9e1773c99f3f44ff9867ffee6cc6469c2f177"},{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@everpuredata.com","username":"sdodsley"},"change_message_id":"a7c812e0a11c020ae9fd4487656504c9f72ff1b3","unresolved":true,"context_lines":[{"line_number":72,"context_line":""},{"line_number":73,"context_line":"3. **Replication Modes**"},{"line_number":74,"context_line":""},{"line_number":75,"context_line":"   * New ``replication_type`` extra-spec with values: ``sync``, ``async``"},{"line_number":76,"context_line":"   * Driver capability reporting for supported replication modes"},{"line_number":77,"context_line":"   * API responses include current replication mode"},{"line_number":78,"context_line":""}],"source_content_type":"text/x-rst","patch_set":6,"id":"f1a4abe5_943e84b7","line":75,"range":{"start_line":75,"start_character":30,"end_line":75,"end_character":41},"in_reply_to":"ec53f70e_209fb07b","updated":"2026-08-24 15:37:02.000000000","message":"Two issues.\n\nFirst, this isn\u0027t new. `replication_type` has been the de facto extra-spec since Cheesecake; the FlashArray driver has parsed it since 2016.\n\nSecond, and more seriously: FlashArray accepts a **third** value, `trisync` (sync-replicated ActiveCluster pod plus an async leg to a third array), backed by the `pure_trisync_enabled` and `pure_trisync_pg_name` config options and plumbed through create, clone, retype and group create. If the API or scheduler starts validating `replication_type` against a closed `{sync, async}` set, every existing FlashArray trisync volume type becomes invalid.\n\nPlease either state that `sync`/`async` is Cinder\u0027s _normalised_ vocabulary and drivers may accept vendor supersets, or model the composite case explicitly. As written the spec is narrower than what is already in-tree.","commit_id":"f7e9e1773c99f3f44ff9867ffee6cc6469c2f177"},{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@everpuredata.com","username":"sdodsley"},"change_message_id":"a7c812e0a11c020ae9fd4487656504c9f72ff1b3","unresolved":true,"context_lines":[{"line_number":96,"context_line":""},{"line_number":97,"context_line":".. code-block:: yaml"},{"line_number":98,"context_line":""},{"line_number":99,"context_line":"    extra_specs:"},{"line_number":100,"context_line":"      replication_enabled: True"},{"line_number":101,"context_line":"      replication_type: sync  # or async"},{"line_number":102,"context_line":""},{"line_number":103,"context_line":".. note::"},{"line_number":104,"context_line":"   For volume-level or group-level replication, refer to the Replication Groups"}],"source_content_type":"text/x-rst","patch_set":6,"id":"fc318b83_ca4f8999","line":101,"range":{"start_line":99,"start_character":0,"end_line":101,"end_character":40},"updated":"2026-08-24 15:37:02.000000000","message":"This isn\u0027t valid Cinder extra-spec syntax. `is_replicated_spec()` → `is_boolean_str()` in `cinder/volume/volume_utils.py` requires exactly `\u003cis\u003e True`; a bare `True` means `volume_type.is_replicated()` returns `False` and the volume is created unreplicated. Similarly, FlashArray matches `\"\u003cin\u003e sync\"` literally, not `\"sync\"`.\n\nEither the example needs fixing, or the spec is proposing a new bare-value syntax — in which case it needs an explicit compatibility statement, because every deployment in the field uses the `\u003cis\u003e`/`\u003cin\u003e` form. This is an upgrade question, not a nit.","commit_id":"f7e9e1773c99f3f44ff9867ffee6cc6469c2f177"},{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@everpuredata.com","username":"sdodsley"},"change_message_id":"a7c812e0a11c020ae9fd4487656504c9f72ff1b3","unresolved":true,"context_lines":[{"line_number":113,"context_line":"interacts with the driver after the backend-switch event. Rather than"},{"line_number":114,"context_line":"polling, the driver raises a special exception the next time it is invoked"},{"line_number":115,"context_line":"after a backend-switch has occurred, and Cinder uses this exception to"},{"line_number":116,"context_line":"trigger switching the management paths automatically."},{"line_number":117,"context_line":""},{"line_number":118,"context_line":"REST API Changes"},{"line_number":119,"context_line":"----------------"}],"source_content_type":"text/x-rst","patch_set":6,"id":"af0bb0c3_2a5e4695","line":116,"updated":"2026-08-24 15:37:02.000000000","message":"The premise holds for FlashArray: on ActiveCluster the pod is stretched and, in a uniform configuration, the host is attached to both arrays, so I/O survives array loss with no Cinder involvement. Brian\u0027s exception-based model is the right shape.\n\nWhat\u0027s missing is the raise point. For FlashArray the only thing invoked on a timer is `update_volume_stats`, and it talks to the current array — so if the array that died is the current one, that call fails with a transport error long before the driver could raise a well-formed replication exception. Pod state is only inspected inside `failover()`, i.e. once an operator has already asked.\n\nPlease name which driver entry points are expected to raise, and say what Cinder does when the driver is simply unreachable instead of raising cleanly.\n\nOne trisync-specific case to note: an automatic switch on the sync leg must leave the async leg to the third array intact.","commit_id":"f7e9e1773c99f3f44ff9867ffee6cc6469c2f177"},{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@everpuredata.com","username":"sdodsley"},"change_message_id":"a7c812e0a11c020ae9fd4487656504c9f72ff1b3","unresolved":true,"context_lines":[{"line_number":132,"context_line":"to a group can be enumerated via the show-group-details call (microversion"},{"line_number":133,"context_line":"3.38) with ``?list_volume\u003dtrue``."},{"line_number":134,"context_line":""},{"line_number":135,"context_line":"The export should be performed after the volume has failed over."},{"line_number":136,"context_line":"This API also accepts a parameter ``clear_existing`` which"},{"line_number":137,"context_line":"will clear all the DB records so there is no scenario where"},{"line_number":138,"context_line":"the primary array coming back could lead to data corruption"},{"line_number":139,"context_line":"scenarios."},{"line_number":140,"context_line":"Note that ``clear_existing`` only clears Cinder\u0027s own database"},{"line_number":141,"context_line":"records; it cannot modify Nova\u0027s block device mapping tables."},{"line_number":142,"context_line":"Using ``clear_existing\u003dtrue`` for volumes that are currently"}],"source_content_type":"text/x-rst","patch_set":6,"id":"90229a64_c7c12e83","line":139,"range":{"start_line":135,"start_character":0,"end_line":139,"end_character":9},"updated":"2026-08-24 15:37:02.000000000","message":"For FlashArray this does not achieve the stated purpose. Clearing Cinder\u0027s DB records leaves the volume on the source array and leaves it in the pod or protection group. ActiveCluster resyncs automatically once connectivity returns, so the source cloud\u0027s array resumes replicating into a volume the target cloud now believes it owns. Breaking that requires an array-side operation, not a DB delete.\n\nThe Nova BDM caveat added in PS6 is good; the array-side half of the same hazard is the more dangerous one and isn\u0027t mentioned.","commit_id":"f7e9e1773c99f3f44ff9867ffee6cc6469c2f177"},{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@everpuredata.com","username":"sdodsley"},"change_message_id":"a7c812e0a11c020ae9fd4487656504c9f72ff1b3","unresolved":true,"context_lines":[{"line_number":168,"context_line":"            \"volume_id\": \"uuid\","},{"line_number":169,"context_line":"            \"volume_name\": \"name\","},{"line_number":170,"context_line":"            \"size\": 100,"},{"line_number":171,"context_line":"            \"backend_id\": \"backend-id\","},{"line_number":172,"context_line":"            \"replication_targets\": ["},{"line_number":173,"context_line":"                {"},{"line_number":174,"context_line":"                    \"backend_id\": \"remote-backend-id\","}],"source_content_type":"text/x-rst","patch_set":6,"id":"4721e009_d1146749","line":171,"updated":"2026-08-24 15:37:02.000000000","message":"This reads as backend-level, but it can\u0027t be. Once group-scoped failover exists, a volume can be served by array B while the backend\u0027s active array is still A. Since `export_replication_metadata()` receives a volume, the driver can resolve this correctly — but the spec should say `backend_id` is the array serving that volume, not the backend\u0027s active array. Otherwise exports will be wrong for exactly the volumes most likely to be exported.","commit_id":"f7e9e1773c99f3f44ff9867ffee6cc6469c2f177"},{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@everpuredata.com","username":"sdodsley"},"change_message_id":"a7c812e0a11c020ae9fd4487656504c9f72ff1b3","unresolved":true,"context_lines":[{"line_number":169,"context_line":"            \"volume_name\": \"name\","},{"line_number":170,"context_line":"            \"size\": 100,"},{"line_number":171,"context_line":"            \"backend_id\": \"backend-id\","},{"line_number":172,"context_line":"            \"replication_targets\": ["},{"line_number":173,"context_line":"                {"},{"line_number":174,"context_line":"                    \"backend_id\": \"remote-backend-id\","},{"line_number":175,"context_line":"                    \"endpoint\": \"openstack-b\","}],"source_content_type":"text/x-rst","patch_set":6,"id":"6d4755ac_76245d4b","line":172,"updated":"2026-08-24 15:37:02.000000000","message":"This changes `replication_targets` from a flat list of `backend_id` strings to a list of objects. FlashArray reports the flat-string form today (plus `replication_count` and a FlashArray-specific `replication_capability`); Anoop notes NetApp does the same. That\u0027s a breaking capabilities-format change for at least two drivers.\n\nPlease add a migration statement: does Cinder accept both shapes, for how long, and which release drops the old one?","commit_id":"f7e9e1773c99f3f44ff9867ffee6cc6469c2f177"},{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@everpuredata.com","username":"sdodsley"},"change_message_id":"a7c812e0a11c020ae9fd4487656504c9f72ff1b3","unresolved":true,"context_lines":[{"line_number":188,"context_line":"sensitive, it is encrypted before being included in the export payload."},{"line_number":189,"context_line":"Operators configure a shared symmetric key per target cloud (a new config"},{"line_number":190,"context_line":"option) on both the source and target deployments out-of-band. On export,"},{"line_number":191,"context_line":"Cinder encrypts ``admin_metadata`` with that key using authenticated"},{"line_number":192,"context_line":"encryption (e.g. AES-GCM); on import, Cinder decrypts it with the same key"},{"line_number":193,"context_line":"and rejects the import if decryption/authentication fails (wrong key,"},{"line_number":194,"context_line":"tampered payload, or no key configured for that source cloud)."},{"line_number":195,"context_line":""},{"line_number":196,"context_line":"**2. Import Volume Replication Metadata**"},{"line_number":197,"context_line":""}],"source_content_type":"text/x-rst","patch_set":6,"id":"4508267c_ddee50e1","line":194,"range":{"start_line":191,"start_character":17,"end_line":194,"end_character":62},"updated":"2026-08-24 15:37:02.000000000","message":"The shared symmetric key added here covers `admin_metadata`, which is a different problem from the one I raised on PS1. `encryption_key_id` lives on the volume record, not in `admin_metadata`, so cross-cloud import of an encrypted volume still has no answer — the target cloud can\u0027t resolve a key UUID from the source cloud\u0027s Barbican. Either Barbican federation / re-wrapping at import time needs addressing, or encrypted volumes need to be declared out of scope for v3.","commit_id":"f7e9e1773c99f3f44ff9867ffee6cc6469c2f177"},{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@everpuredata.com","username":"sdodsley"},"change_message_id":"a7c812e0a11c020ae9fd4487656504c9f72ff1b3","unresolved":true,"context_lines":[{"line_number":231,"context_line":"    }"},{"line_number":232,"context_line":""},{"line_number":233,"context_line":".. note::"},{"line_number":234,"context_line":"   For group and volume-level failover APIs, refer to the Replication Groups"},{"line_number":235,"context_line":"   spec [4]."},{"line_number":236,"context_line":""},{"line_number":237,"context_line":""}],"source_content_type":"text/x-rst","patch_set":6,"id":"1f1ce9bc_d831a1d8","line":234,"updated":"2026-08-24 15:37:02.000000000","message":"Following up on my PS1 comment about a unified failover API: group-scoped and backend-scoped failover have genuinely different side effects and a unified entry point must preserve the distinction. A group failover has to leave `active_backend_id`, the driver\u0027s current array and the replication target lists untouched, otherwise one group\u0027s failover drags every other volume on the backend with it. Backend failover sets them. Worth stating explicitly here so the eventual implementation doesn\u0027t normalise the two.","commit_id":"f7e9e1773c99f3f44ff9867ffee6cc6469c2f177"},{"author":{"_account_id":38059,"name":"Anoop Kumar Shukla","display_name":"Anoop Shukla","email":"anoop.shukla@netapp.com","username":"anoop2","status":"NetApp"},"change_message_id":"2926395df9acd462f37ef6576411d08560af5869","unresolved":true,"context_lines":[{"line_number":241,"context_line":"Drivers need to modify/implement the following changes to support"},{"line_number":242,"context_line":"replication v3."},{"line_number":243,"context_line":""},{"line_number":244,"context_line":"1. **Replication Capabilities Reporting**"},{"line_number":245,"context_line":""},{"line_number":246,"context_line":"Drivers should report backend-level replication capabilities and supported modes:"},{"line_number":247,"context_line":""}],"source_content_type":"text/x-rst","patch_set":6,"id":"de965855_bd6ced02","line":244,"range":{"start_line":244,"start_character":5,"end_line":244,"end_character":39},"updated":"2026-08-24 08:48:41.000000000","message":"NetApp today reports replication_type as a single \u0027sync\u0027|\u0027async\u0027 string and replication_targets as backend name strings, not {backend_id, replication_type[], cross_os} objects. A backend supports one mode at a time. Consider adding that the example is aspirational and drivers may report a subset during transition.","commit_id":"f7e9e1773c99f3f44ff9867ffee6cc6469c2f177"},{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@everpuredata.com","username":"sdodsley"},"change_message_id":"a7c812e0a11c020ae9fd4487656504c9f72ff1b3","unresolved":true,"context_lines":[{"line_number":241,"context_line":"Drivers need to modify/implement the following changes to support"},{"line_number":242,"context_line":"replication v3."},{"line_number":243,"context_line":""},{"line_number":244,"context_line":"1. **Replication Capabilities Reporting**"},{"line_number":245,"context_line":""},{"line_number":246,"context_line":"Drivers should report backend-level replication capabilities and supported modes:"},{"line_number":247,"context_line":""}],"source_content_type":"text/x-rst","patch_set":6,"id":"0221468e_bf656c51","line":244,"range":{"start_line":244,"start_character":5,"end_line":244,"end_character":39},"in_reply_to":"de965855_bd6ced02","updated":"2026-08-24 15:37:02.000000000","message":"A collision to catch before implementation starts. In `https://review.opendev.org/c/openstack/cinder/+/996497` the FlashArray driver uses the volume\u0027s `replication_driver_data` to record which array serves a group-failed-over volume. That field is load-bearing: because a group failover deliberately does not move the driver\u0027s current array, it is the only thing routing attach, detach, extend, snapshot, revert and delete to the correct array.\n\nThis spec never says where the `vendor_metadata` from `export_replication_metadata()` is persisted on import. `replication_driver_data` is the obvious candidate and would silently clobber that routing. Please reserve `replication_driver_data` for driver-internal use and name an explicit home for imported vendor metadata — a new column, or the volume\u0027s admin_metadata.","commit_id":"f7e9e1773c99f3f44ff9867ffee6cc6469c2f177"},{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@everpuredata.com","username":"sdodsley"},"change_message_id":"a7c812e0a11c020ae9fd4487656504c9f72ff1b3","unresolved":true,"context_lines":[{"line_number":254,"context_line":"            \u0027replication_targets\u0027: ["},{"line_number":255,"context_line":"                {"},{"line_number":256,"context_line":"                    \u0027backend_id\u0027: \u0027backend-b\u0027,"},{"line_number":257,"context_line":"                    \u0027replication_type\u0027: [\u0027sync\u0027, \u0027async\u0027],"},{"line_number":258,"context_line":"                    \u0027cross_os\u0027: False"},{"line_number":259,"context_line":"                },"},{"line_number":260,"context_line":"                {"}],"source_content_type":"text/x-rst","patch_set":6,"id":"c9d3ef71_96c948c1","line":257,"range":{"start_line":257,"start_character":21,"end_line":257,"end_character":37},"updated":"2026-08-24 15:37:02.000000000","message":"The list shape is right, but the spec should say the list is **derived**, not independently declared, because the modes aren\u0027t orthogonal.\n\nOn FlashArray a `replication_device` stanza carries a single `type`, but that value is the _highest_ mode configured, and the lower one comes free. A `type \u003d sync` target is stretched into the ActiveCluster pod and added to the async protection group, so it genuinely reports `[\u0027sync\u0027, \u0027async\u0027]` and either can be used. A `type \u003d async` target reports `[\u0027async\u0027]` only. Sync implies async; the reverse is not true.\n\nTwo things follow that the spec should state:\n\n1. Drivers should be told to report the derived set, not echo the configured value. Otherwise two backends with identical capabilities will advertise differently depending on whether the driver author read type literally. FlashArray already does the derived thing at backend level in `get_volume_stats` — `async` is always present whenever replication is enabled, with `sync` added on top when ActiveCluster is up — so this is really just asking for the same treatment per target.\n\n2. Please separate the two namespaces that this field currently conflates. The values a target can report are drawn from `{sync, async}`. The values a volume type can carry include `trisync`, which is not a per-target mode at all — it\u0027s a property of the topology (a sync pod that additionally async-replicates to a third array, via a protection group inside the pod). There is no `trisync` replication device, which is exactly why group failover for a trisync group has to go and find the async leg to promote from. Using `replication_type` as the key for both the volume-type enum and the per-target capability list makes that distinction impossible to express.\n\nConcretely: the volume-type `replication_type` needs `trisync` (see my comment on line 75); the per-target replication_type does not, and shouldn\u0027t accept it.","commit_id":"f7e9e1773c99f3f44ff9867ffee6cc6469c2f177"},{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@everpuredata.com","username":"sdodsley"},"change_message_id":"a7c812e0a11c020ae9fd4487656504c9f72ff1b3","unresolved":true,"context_lines":[{"line_number":260,"context_line":"                {"},{"line_number":261,"context_line":"                    \u0027backend_id\u0027: \u0027remote-openstack-1\u0027,"},{"line_number":262,"context_line":"                    \u0027replication_type\u0027: [\u0027async\u0027],"},{"line_number":263,"context_line":"                    \u0027cross_os\u0027: True,"},{"line_number":264,"context_line":"                }"},{"line_number":265,"context_line":"            ]"},{"line_number":266,"context_line":"        }"}],"source_content_type":"text/x-rst","patch_set":6,"id":"ce4945e6_a4a49822","line":263,"range":{"start_line":263,"start_character":21,"end_line":263,"end_character":29},"updated":"2026-08-24 15:37:02.000000000","message":"Given the spec says \"cross-OpenStack\" throughout, `cross_os` reads as \"cross operating system\". Suggest `cross_cloud`, and normalise both occurrences.","commit_id":"f7e9e1773c99f3f44ff9867ffee6cc6469c2f177"},{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@everpuredata.com","username":"sdodsley"},"change_message_id":"a7c812e0a11c020ae9fd4487656504c9f72ff1b3","unresolved":true,"context_lines":[{"line_number":300,"context_line":"        Export metadata needed to import this volume in other OpenStack cluster."},{"line_number":301,"context_line":""},{"line_number":302,"context_line":"        Returns dict with volume metadata, replication state, and"},{"line_number":303,"context_line":"        backend-specific information needed for cross-OpenStack failover."},{"line_number":304,"context_line":"        \"\"\""},{"line_number":305,"context_line":"        return {"},{"line_number":306,"context_line":"            \u0027backend_volume_id\u0027: \u0027vendor-specific-id\u0027,"}],"source_content_type":"text/x-rst","patch_set":6,"id":"a4325016_360810d0","line":303,"updated":"2026-08-24 15:37:02.000000000","message":"FlashArray async replication is unidirectional, so `failover()` already puts non-sync volumes into `error` on failback. The example on line 262 shows the remote OpenStack target as async-only, which means for the cross-OpenStack case there is no failback path at all — returning is a fresh export/import in the opposite direction.\n\nThat\u0027s a defensible design, but the spec should say it rather than leaving operators to discover it.","commit_id":"f7e9e1773c99f3f44ff9867ffee6cc6469c2f177"},{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@everpuredata.com","username":"sdodsley"},"change_message_id":"a7c812e0a11c020ae9fd4487656504c9f72ff1b3","unresolved":true,"context_lines":[{"line_number":316,"context_line":"        \"\"\""},{"line_number":317,"context_line":"        Import a volume that was replicated from another OpenStack cluster."},{"line_number":318,"context_line":""},{"line_number":319,"context_line":"        Uses metadata from export_replication_metadata to locate and"},{"line_number":320,"context_line":"        import the replicated volume."},{"line_number":321,"context_line":"        \"\"\""},{"line_number":322,"context_line":"        ..."}],"source_content_type":"text/x-rst","patch_set":6,"id":"353cf484_2e19632d","line":319,"updated":"2026-08-24 15:37:02.000000000","message":"This implies the replicated volume already exists as a first-class volume on the target array. For FlashArray async that\u0027s false: on the target the data lives in the replicated protection-group snapshot namespace (`\u003csource-array\u003e:\u003cpg\u003e.\u003csnap\u003e.\u003cvolname\u003e`), not as a live volume. Importing it means promoting from the latest replicated pgroup snapshot first — effectively the whole of the existing async host-failover path — and only then managing it.\n\nPlease state that the import driver method is permitted to perform the array-side promote. And note that if this reuses the existing `manage_existing` path, that path refuses volumes with connected hosts and strips then rebuilds replication, which for a sync volume means a ghost-pod stretch/unstretch on a volume that has just survived a DR event. That\u0027s the wrong moment to be re-plumbing pod membership.","commit_id":"f7e9e1773c99f3f44ff9867ffee6cc6469c2f177"},{"author":{"_account_id":38059,"name":"Anoop Kumar Shukla","display_name":"Anoop Shukla","email":"anoop.shukla@netapp.com","username":"anoop2","status":"NetApp"},"change_message_id":"2926395df9acd462f37ef6576411d08560af5869","unresolved":true,"context_lines":[{"line_number":353,"context_line":"support) will be available via a new microversion. Operators can use the"},{"line_number":354,"context_line":"existing replication configuration for their backends, with the following"},{"line_number":355,"context_line":"addition: a new config option for the shared symmetric key used to encrypt"},{"line_number":356,"context_line":"``admin_metadata`` during cross-OpenStack export/import (see the Export"},{"line_number":357,"context_line":"Volume Replication Metadata section)."},{"line_number":358,"context_line":""},{"line_number":359,"context_line":"Specific RPO/RTO values remain a backend/driver concern, configured"},{"line_number":360,"context_line":"directly on the backend (e.g. Pure already exposes RPO configuration for"}],"source_content_type":"text/x-rst","patch_set":6,"id":"a7b36533_bb79fee7","line":357,"range":{"start_line":356,"start_character":65,"end_line":357,"end_character":27},"updated":"2026-08-24 08:48:41.000000000","message":"Reword to: Export Replication Metadata section","commit_id":"f7e9e1773c99f3f44ff9867ffee6cc6469c2f177"},{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@everpuredata.com","username":"sdodsley"},"change_message_id":"a7c812e0a11c020ae9fd4487656504c9f72ff1b3","unresolved":true,"context_lines":[{"line_number":356,"context_line":"``admin_metadata`` during cross-OpenStack export/import (see the Export"},{"line_number":357,"context_line":"Volume Replication Metadata section)."},{"line_number":358,"context_line":""},{"line_number":359,"context_line":"Specific RPO/RTO values remain a backend/driver concern, configured"},{"line_number":360,"context_line":"directly on the backend (e.g. Pure already exposes RPO configuration for"},{"line_number":361,"context_line":"async replication) rather than through a new Cinder configuration option;"},{"line_number":362,"context_line":"Cinder only distinguishes ``sync`` vs ``async`` and does not manage the"},{"line_number":363,"context_line":"underlying RPO/RTO numbers as part of this spec."},{"line_number":364,"context_line":""},{"line_number":365,"context_line":"Implementation"},{"line_number":366,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"}],"source_content_type":"text/x-rst","patch_set":6,"id":"e5bee430_824d3ab8","line":363,"range":{"start_line":359,"start_character":0,"end_line":363,"end_character":48},"updated":"2026-08-24 15:37:02.000000000","message":"This paragraph\u0027s premise is already being overtaken. We are actively discussing per-protection-group RPO within a single backend stanza on FlashArray, expressed through vendor-namespaced extra-specs — the driver already has the machinery for exactly this (`_get_volume_type_extra_spec` with the `flasharray:` scope, used today for `vg_name`, `vg_maxIOPS`, `vg_maxBWS`), so extending it to the replication interval is a natural step rather than new plumbing. NetApp is in similar territory with `netapp_replication_policy` and its embedded schedule resource.\n\nSo \"configured directly on the backend rather than through Cinder\" won\u0027t hold for long. That\u0027s fine as a decision — Cinder need not standardise RPO — but the spec should say what it actually means, which is that RPO is deliberately left to **vendor-specific extra-specs** and Cinder will not define a common key. Saying it\u0027s a backend/`cinder.conf` concern is a different claim and an inaccurate one.\n\nTwo consequences worth spelling out if you take that route:\n\n1. It fragments. Every vendor invents its own namespaced key for the same concept, and an operator moving a workload between backends has to rewrite volume types. If the spec is content with that, say so explicitly so nobody re-litigates it later. If not, reserving a standard key now is much cheaper than retrofitting one.\n\n2. It leaks into the export/import payload. If RPO becomes a volume-type property rather than a backend property, then `replication_type: async` no longer describes a volume\u0027s replication on its own, and the metadata exported at line 179 is incomplete. A volume re-imported into cloud B would silently pick up whatever RPO cloud B\u0027s volume type specifies, which may be nothing like what it had in cloud A. Either the vendor-specific extra-specs need to travel in `vendor_metadata`, or the spec needs to state that RPO is not preserved across a cross-OpenStack import and the operator is responsible for matching volume types on both sides.\n\nPoint 2 is the one I\u0027d most like addressed here, since it\u0027s squarely in this spec\u0027s scope rather than a general replication question.","commit_id":"f7e9e1773c99f3f44ff9867ffee6cc6469c2f177"}]}
