)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"282700bdb3b7a5286ece1974a914a8b42f5523fd","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"f9b93c46_96c5e320","updated":"2026-10-01 17:50:39.000000000","message":"Thanks for all the feedbacks! i\u0027m working in a new version of the spec considering your concerns!","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"}],"specs/2027.1/approved/zone-migration-az-drain.rst":[{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"77b0d7124ce6d8897ce66bd09ff7eadd3dbf7c69","unresolved":true,"context_lines":[{"line_number":14,"context_line":"every workload out of it — both instances and their volumes — before the zone"},{"line_number":15,"context_line":"can be taken down. Watcher\u0027s ``zone_migration`` strategy already drains"},{"line_number":16,"context_line":"operator-named compute nodes and storage pools, but it has no concept of an"},{"line_number":17,"context_line":"OpenStack availability zone: the operator must enumerate every source host and"},{"line_number":18,"context_line":"every source pool by hand, and nothing keeps the workload inside the intended"},{"line_number":19,"context_line":"destination zone. This spec adds an AZ-to-AZ mode to ``zone_migration``."},{"line_number":20,"context_line":""}],"source_content_type":"text/x-rst","patch_set":1,"id":"11fc6bec_1bc8ccd7","line":17,"range":{"start_line":17,"start_character":0,"end_line":17,"end_character":27},"updated":"2026-09-30 22:57:10.000000000","message":"There is not really a single OpenStack-wide concept of an availability\nzone.\n\nNova, Cinder, and Neutron each expose independently defined AZs with\ndifferent semantics and APIs. We therefore cannot assume that an AZ\nname identifies the same location or failure domain across services.\n\nIn Nova, an AZ is effectively a named host aggregate used as a\nscheduling domain. A compute host may belong to multiple host\naggregates, but only one Nova AZ. Importantly, a Nova AZ is not\ninherently a fault domain or physical location; an operator is free to\nuse AZs to model whatever grouping is useful for scheduling.\n\nCinder has a separate AZ concept associated with storage backends. A\nvolume has its own Cinder AZ independently of the Nova AZ of the server\nto which it is attached.\n\nNeutron has another AZ concept used for placement of networking\nservices such as L3 routing and DHCP. Nova passes the selected compute\nhost via `binding:host_id`, while Nova-owned ports use the `compute:`\n`device_owner` namespace (normally `compute:nova`). Neither establishes\nan equivalence between the Nova and Neutron AZ namespaces.\n\nAn operator could therefore legitimately have a workload using:\n\n    Nova AZ:       amd-compute\n    Cinder AZ:     nvme-storage\n    Neutron AZ:    comcast-edge\n\nAlternatively, an operator may choose to use a common name such as\n`us-east-dc1` across all three services. That alignment is an operator\nconvention, not an OpenStack invariant.\n\nThis is also quite different from the AWS meaning of \"availability\nzone\". An AWS AZ is explicitly an isolated physical infrastructure\nlocation and fault-isolation boundary within a region. OpenStack AZs do\nnot have that guarantee.\n\nOperationally, an AWS AZ is therefore often closer to an independently\ndeployed OpenStack cloud or Keystone region than to a Nova, Cinder, or\nNeutron AZ, although the concepts are not API-equivalent.\n\nThis matters for Watcher because AZ awareness needs to be modeled\nseparately for each service. In particular, we cannot assume that:\n\n    compute_az \u003d\u003d storage_az \u003d\u003d network_az\n\nor that all volumes attached to an instance are in the same Cinder AZ.\n\nFor example, if an instance has:\n\n    volume-a -\u003e storage_az_1\n    volume-b -\u003e storage_az_2\n\nthen draining `storage_az_1` should allow Watcher to migrate only\n`volume-a` to a backend in, for example, `storage_az_3`, without moving\nthe instance or `volume-b`.\n\nLikewise, draining a Nova AZ should not implicitly mean draining a\nCinder or Neutron AZ with the same name.\n\nSo I think the spec should avoid referring to \"an OpenStack\navailability zone\" as though it were one cross-service object. It\nwould be clearer to talk explicitly about Nova/compute AZs,\nCinder/storage AZs, and, where relevant, Neutron/network AZs.","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"282700bdb3b7a5286ece1974a914a8b42f5523fd","unresolved":true,"context_lines":[{"line_number":14,"context_line":"every workload out of it — both instances and their volumes — before the zone"},{"line_number":15,"context_line":"can be taken down. Watcher\u0027s ``zone_migration`` strategy already drains"},{"line_number":16,"context_line":"operator-named compute nodes and storage pools, but it has no concept of an"},{"line_number":17,"context_line":"OpenStack availability zone: the operator must enumerate every source host and"},{"line_number":18,"context_line":"every source pool by hand, and nothing keeps the workload inside the intended"},{"line_number":19,"context_line":"destination zone. This spec adds an AZ-to-AZ mode to ``zone_migration``."},{"line_number":20,"context_line":""}],"source_content_type":"text/x-rst","patch_set":1,"id":"95f97bb7_4341a9da","line":17,"range":{"start_line":17,"start_character":0,"end_line":17,"end_character":27},"in_reply_to":"11fc6bec_1bc8ccd7","updated":"2026-10-01 17:50:39.000000000","message":"Ack, it needs to be clear about that point (differences between AZs  from services pov and that there is no unique OpenStack AZ). I would say that next PS will move towards nova/compute AZs while storage continue to be pool/type oriented (looks more aligned with current implementation and usage).","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"77b0d7124ce6d8897ce66bd09ff7eadd3dbf7c69","unresolved":true,"context_lines":[{"line_number":34,"context_line":""},{"line_number":35,"context_line":"No AZ awareness anywhere"},{"line_number":36,"context_line":"------------------------"},{"line_number":37,"context_line":""},{"line_number":38,"context_line":"* The compute cluster data model has no ``availability_zone`` on"},{"line_number":39,"context_line":"  ``ComputeNode``. Nova\u0027s host-to-zone data is already fetched during model"},{"line_number":40,"context_line":"  build via ``nova_helper.get_service_list()`` (``Service.zone``) and then"},{"line_number":41,"context_line":"  discarded — the zone is used to select hostnames for AZ-scoped audits and"},{"line_number":42,"context_line":"  never stored."},{"line_number":43,"context_line":"* The storage model is better off: ``StorageNode`` already carries ``zone``,"},{"line_number":44,"context_line":"  populated from ``StorageService.availability_zone``. But ``Volume`` has no"},{"line_number":45,"context_line":"  AZ field, and nothing correlates a Cinder AZ with a Nova AZ."}],"source_content_type":"text/x-rst","patch_set":1,"id":"a372b0a6_9faf36cb","line":42,"range":{"start_line":37,"start_character":0,"end_line":42,"end_character":15},"updated":"2026-09-30 22:57:10.000000000","message":"This is also where we start running into problems with drivers such as\nIronic, and potentially VMware.\n\nWith the Ironic virt driver there is a 1:N relationship between a\n`nova-compute` service and the `ComputeNode` records it manages. In\nfact, Ironic is currently the only Nova driver where one compute\nservice can represent multiple compute nodes.\n\nHistorically those Ironic nodes could also move between compute\nservices. More generally, Nova AZs are defined in terms of hosts/host\naggregates, while Ironic\u0027s own resource partitioning is based on\nconcepts such as conductor groups and shards. Nova\u0027s AZ model therefore\ndoes not map particularly cleanly onto individual Ironic bare metal\nnodes.\n\nWe should probably call this out explicitly. Either AZ migration is\nunsupported for compute nodes whose `hypervisor_type` is not one of the\ndrivers we know can support the required move operation, or we need to\ndefine what the expected behaviour is for those drivers.\n\nIronic is particularly interesting here because an Ironic-backed server\ncannot be live migrated, but it can have Cinder-backed storage. So even\nif the compute part of an AZ evacuation is unsupported, the storage\nportion may still be actionable independently.\n\nThere is a second issue on the Nova side: the AZ of the compute host is\nonly half of the information we need.\n\nNova exposes both:\n```\n    availability_zone\n        -\u003e the AZ of the host where the instance currently resides\n\n    pinned_availability_zone\n        -\u003e the AZ constraint applied to the instance\n```\nThese are deliberately separate. Since microversion 2.96 Nova exposes\n`pinned_availability_zone`, and from microversion 2.104 the pin can also\nbe explicitly changed or removed.\n\nAn instance can therefore currently reside on a compute host in an AZ\nwithout necessarily being pinned to that AZ. Conversely, an instance\ncan be pinned because:\n\n* it was created with an explicit AZ;\n* `default_schedule_zone` applied;\n* it was unshelved into a specified AZ; or\n* Nova pinned it to a volume AZ when `cinder.cross_az_attach\u003dFalse`.\n\n\nSo checking only the compute node/service AZ is not sufficient when\nbuilding an AZ migration action plan. We also need to inspect\n`pinned_availability_zone` for each instance.\n\nFor example, if Watcher is draining `az1` and wants to move an instance\nto `az2`:\n```\n    host AZ                  \u003d az1\n    pinned_availability_zone \u003d null\n```\nthen moving it to `az2` is compatible with the instance\u0027s current\nplacement policy.\n\nHowever:\n```\n    host AZ                  \u003d az1\n    pinned_availability_zone \u003d az1\n```\nmeans that moving it to `az2` would require overriding an explicit or\nimplicit placement constraint.\n\nI think we need to define that behaviour in the spec.\n\nThe two obvious choices are:\n\n1. Exclude pinned instances from the action plan when the destination\n   AZ differs from `pinned_availability_zone`.\n\n2. Explicitly unpin the instance as part of the action plan and then\n   move it, changing the placement policy originally requested for that\n   workload.\n\nMy initial preference would be (1). It is the safer default because\nWatcher should not silently override an end user\u0027s AZ constraint, which\nmay encode HA, locality, compliance, or some other placement\nrequirement.\n\nIf we want to support (2), I think it should be an explicit,\nconfigurable policy rather than an implicit side effect of AZ\nmigration.\n\nThis also means that retaining only `Service.zone` during model\nconstruction is insufficient. We need both the placement AZ of the\ncompute resource and the instance-level `pinned_availability_zone`\nconstraint in the model used by the strategy.","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"282700bdb3b7a5286ece1974a914a8b42f5523fd","unresolved":true,"context_lines":[{"line_number":34,"context_line":""},{"line_number":35,"context_line":"No AZ awareness anywhere"},{"line_number":36,"context_line":"------------------------"},{"line_number":37,"context_line":""},{"line_number":38,"context_line":"* The compute cluster data model has no ``availability_zone`` on"},{"line_number":39,"context_line":"  ``ComputeNode``. Nova\u0027s host-to-zone data is already fetched during model"},{"line_number":40,"context_line":"  build via ``nova_helper.get_service_list()`` (``Service.zone``) and then"},{"line_number":41,"context_line":"  discarded — the zone is used to select hostnames for AZ-scoped audits and"},{"line_number":42,"context_line":"  never stored."},{"line_number":43,"context_line":"* The storage model is better off: ``StorageNode`` already carries ``zone``,"},{"line_number":44,"context_line":"  populated from ``StorageService.availability_zone``. But ``Volume`` has no"},{"line_number":45,"context_line":"  AZ field, and nothing correlates a Cinder AZ with a Nova AZ."}],"source_content_type":"text/x-rst","patch_set":1,"id":"c5dc8ecb_66680218","line":42,"range":{"start_line":37,"start_character":0,"end_line":42,"end_character":15},"in_reply_to":"a372b0a6_9faf36cb","updated":"2026-10-01 17:50:39.000000000","message":"ACK, so the hypervisor_type part using ironic, we may want to discuss more, may at PTG.\nWRT pinned_availability_zone, the model already supports it (extended attributes).\nSo we can go with 1 or 2. The spec mentions bellow the approch 2 already, but i would say that can be a different spec and an isolated functionallity added in this cycle or in the following one. I agree that this should require a configuration so users would be able to choose between migrating them or not.","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"77b0d7124ce6d8897ce66bd09ff7eadd3dbf7c69","unresolved":true,"context_lines":[{"line_number":42,"context_line":"  never stored."},{"line_number":43,"context_line":"* The storage model is better off: ``StorageNode`` already carries ``zone``,"},{"line_number":44,"context_line":"  populated from ``StorageService.availability_zone``. But ``Volume`` has no"},{"line_number":45,"context_line":"  AZ field, and nothing correlates a Cinder AZ with a Nova AZ."},{"line_number":46,"context_line":"* Consequently an operator cannot say \"drain az-a into az-b\". They must"},{"line_number":47,"context_line":"  enumerate hosts, and there is no validation that the hosts they name are"},{"line_number":48,"context_line":"  actually in the zones they think."}],"source_content_type":"text/x-rst","patch_set":1,"id":"f4dd03d8_a13da86f","line":45,"range":{"start_line":45,"start_character":16,"end_line":45,"end_character":62},"updated":"2026-09-30 22:57:10.000000000","message":"right because the are not corralated\n\nthe may share the saem name but even then that is not a guarentee that that storage systrem is usabel by hosts in that nova az.\n\nits likely but they are not genrally the saem.","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"adeb8dbebe14aa2cd3f2d44e1ad37d5491561eeb","unresolved":false,"context_lines":[{"line_number":42,"context_line":"  never stored."},{"line_number":43,"context_line":"* The storage model is better off: ``StorageNode`` already carries ``zone``,"},{"line_number":44,"context_line":"  populated from ``StorageService.availability_zone``. But ``Volume`` has no"},{"line_number":45,"context_line":"  AZ field, and nothing correlates a Cinder AZ with a Nova AZ."},{"line_number":46,"context_line":"* Consequently an operator cannot say \"drain az-a into az-b\". They must"},{"line_number":47,"context_line":"  enumerate hosts, and there is no validation that the hosts they name are"},{"line_number":48,"context_line":"  actually in the zones they think."}],"source_content_type":"text/x-rst","patch_set":1,"id":"b638cd91_6edd30f9","line":45,"range":{"start_line":45,"start_character":16,"end_line":45,"end_character":62},"in_reply_to":"f4dd03d8_a13da86f","updated":"2026-10-02 17:57:50.000000000","message":"Acknowledged","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":16312,"name":"Alfredo Moralejo","email":"amoralej@redhat.com","username":"amoralej"},"change_message_id":"086f6c27b0f6c775700f27587c73e7d9bcdbf3ee","unresolved":true,"context_lines":[{"line_number":55,"context_line":"  zone, with the source compute services disabled so the scheduler does not"},{"line_number":56,"context_line":"  refill them mid-drain."},{"line_number":57,"context_line":"* **Deployer** migrates only the block storage of a zone — retyping volumes"},{"line_number":58,"context_line":"  onto backends in the destination zone — while leaving compute in place, or"},{"line_number":59,"context_line":"  the reverse."},{"line_number":60,"context_line":""},{"line_number":61,"context_line":"Proposed Change"},{"line_number":62,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"},{"line_number":63,"context_line":""}],"source_content_type":"text/x-rst","patch_set":1,"id":"f92099c6_af362b15","line":60,"range":{"start_line":58,"start_character":75,"end_line":60,"end_character":1},"updated":"2026-09-29 15:52:23.000000000","message":"To avoid any missunderstanding, \"or the reverse\" in this context means \"migrating only the instances while leaving volumes in the original availability zone\", right?","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"adeb8dbebe14aa2cd3f2d44e1ad37d5491561eeb","unresolved":true,"context_lines":[{"line_number":55,"context_line":"  zone, with the source compute services disabled so the scheduler does not"},{"line_number":56,"context_line":"  refill them mid-drain."},{"line_number":57,"context_line":"* **Deployer** migrates only the block storage of a zone — retyping volumes"},{"line_number":58,"context_line":"  onto backends in the destination zone — while leaving compute in place, or"},{"line_number":59,"context_line":"  the reverse."},{"line_number":60,"context_line":""},{"line_number":61,"context_line":"Proposed Change"},{"line_number":62,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"},{"line_number":63,"context_line":""}],"source_content_type":"text/x-rst","patch_set":1,"id":"f1295fcc_a379af8b","line":60,"range":{"start_line":58,"start_character":75,"end_line":60,"end_character":1},"in_reply_to":"230ff1de_3bf069e4","updated":"2026-10-02 17:57:50.000000000","message":"The new PS now handles volumes as volume migrations to different pools or retypes, so there is no correlation with compute or storage AZs. Checking storage AZ is out of the scope for now, since Cinder has no/and may have no plans to accept destination az as a migrations option.","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"77b0d7124ce6d8897ce66bd09ff7eadd3dbf7c69","unresolved":true,"context_lines":[{"line_number":55,"context_line":"  zone, with the source compute services disabled so the scheduler does not"},{"line_number":56,"context_line":"  refill them mid-drain."},{"line_number":57,"context_line":"* **Deployer** migrates only the block storage of a zone — retyping volumes"},{"line_number":58,"context_line":"  onto backends in the destination zone — while leaving compute in place, or"},{"line_number":59,"context_line":"  the reverse."},{"line_number":60,"context_line":""},{"line_number":61,"context_line":"Proposed Change"},{"line_number":62,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"},{"line_number":63,"context_line":""}],"source_content_type":"text/x-rst","patch_set":1,"id":"230ff1de_3bf069e4","line":60,"range":{"start_line":58,"start_character":75,"end_line":60,"end_character":1},"in_reply_to":"ac1b1abf_afb1bd38","updated":"2026-09-30 22:57:10.000000000","message":"`retyping volumes onto backends in the destination zone`\n\nis not quite correct.\n\nWe need to distinguish between a Cinder volume\u0027s volume type, the\nstorage backend on which it is currently placed, and the availability\nzone of that backend. These are related, but they do not have a 1:1:1\nmapping.\n\nVolume types are roughly analogous to Nova flavors. A volume has a\nvolume type, and that type can be supported by multiple storage\nbackends, potentially across multiple Cinder AZs. Cinder also allows a\nvolume type to constrain the AZs in which it is valid using\n`RESKEY:availability_zones`.\n\nFor example, a `prod` volume type could be available in both:\n\n    mass_storage_replica_2\n        -\u003e Ceph backend\n\n    performance_replica_3\n        -\u003e Fibre Channel NVMe array\n\nThe physical storage implementation and performance characteristics\ncan therefore differ between backends while the user-visible volume\ntype remains `prod`.\n\nSimilarly, a single backend can be exposed through multiple volume\ntypes. For example, the same Ceph backend might support:\n\n    ceph_fast -\u003e QoS policy allowing 1000 IOPS\n    ceph_slow -\u003e QoS policy allowing 100 IOPS\n\nThe volume type is therefore not an identifier for either a backend or\nan AZ.\n\nThere are also two different Cinder operations that matter here.\n\nA volume migration moves a volume to a specified storage backend or\npool. This can be done while retaining the same volume type.\n\nA retype changes the volume type. The driver may be able to perform the\nretype on the existing backend. If satisfying the new type requires a\nmigration, Cinder can perform one as part of the retype operation.\nRetyping therefore does not inherently mean moving the volume to a\ndifferent backend or AZ.\n\nWatcher reflects this distinction in its existing `volume_migrate`\naction:\n\n    migration_type\u003dmigrate\n        -\u003e destination_node\n        -\u003e move to another backend/pool with the same volume type\n\n    migration_type\u003dretype\n        -\u003e destination_type\n        -\u003e change the volume type\n\n\nFor the AZ use case we therefore need to be able to express at least\nthese independently:\n```\n1. Move the VM from one Nova AZ to another while leaving its volumes\n   in place.\n\n2. Move a volume from a backend in one Cinder AZ to a backend in\n   another Cinder AZ while retaining its existing volume type.\n\n3. Move both, for example:\n\n       VM:\n           az_ups_backup\n               -\u003e az_diesel_backup\n\n       volume:\n           mass_storage_replica_2\n               -\u003e performance_replica_3\n\n4. Potentially migrate the volume to a different backend/AZ and also\n   change its volume type.\n```\nThe important point for Watcher is that it cannot infer a destination\nvolume type from the destination AZ. A volume type may be valid in\nmultiple AZs, and multiple backends in an AZ may support that same\ntype.\n\nSo I think we should describe this as migrating the volume to a\nsuitable backend in the destination Cinder AZ, preserving the existing\nvolume type unless a separate retype is explicitly requested.\n\nThat keeps backend/AZ migration and volume-type changes as independent\ndecisions instead of assuming that crossing an AZ boundary implies a\nretype.","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"4c4d921219c2022d940e5f5e7e7a7703e87e26da","unresolved":true,"context_lines":[{"line_number":55,"context_line":"  zone, with the source compute services disabled so the scheduler does not"},{"line_number":56,"context_line":"  refill them mid-drain."},{"line_number":57,"context_line":"* **Deployer** migrates only the block storage of a zone — retyping volumes"},{"line_number":58,"context_line":"  onto backends in the destination zone — while leaving compute in place, or"},{"line_number":59,"context_line":"  the reverse."},{"line_number":60,"context_line":""},{"line_number":61,"context_line":"Proposed Change"},{"line_number":62,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"},{"line_number":63,"context_line":""}],"source_content_type":"text/x-rst","patch_set":1,"id":"ac1b1abf_afb1bd38","line":60,"range":{"start_line":58,"start_character":75,"end_line":60,"end_character":1},"in_reply_to":"f92099c6_af362b15","updated":"2026-09-29 20:37:58.000000000","message":"Correct, it can be improved in the next ps.","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":34452,"name":"Joan Gilabert","display_name":"jgilaber","email":"jgilaber@redhat.com","username":"jgilaber"},"change_message_id":"4f879a777d2dd912827f1b41b2e5c8e9b216139b","unresolved":true,"context_lines":[{"line_number":61,"context_line":"Proposed Change"},{"line_number":62,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"},{"line_number":63,"context_line":""},{"line_number":64,"context_line":"Add two optional input parameters to ``zone_migration`` that, together,"},{"line_number":65,"context_line":"express an AZ drain."},{"line_number":66,"context_line":""},{"line_number":67,"context_line":"``availability_zones`` is **mutually exclusive** with the existing"}],"source_content_type":"text/x-rst","patch_set":1,"id":"2bce5d39_68b05b7d","line":64,"updated":"2026-10-01 15:15:38.000000000","message":"wondering what are everyone thoughts on the possibility of adding this functionality to a new strategy instead of adding more complexity to the existing zone migration. The new strategy could ideally share most of the code with zone migration, with the advantage of having a much simpler user interface","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"282700bdb3b7a5286ece1974a914a8b42f5523fd","unresolved":true,"context_lines":[{"line_number":61,"context_line":"Proposed Change"},{"line_number":62,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"},{"line_number":63,"context_line":""},{"line_number":64,"context_line":"Add two optional input parameters to ``zone_migration`` that, together,"},{"line_number":65,"context_line":"express an AZ drain."},{"line_number":66,"context_line":""},{"line_number":67,"context_line":"``availability_zones`` is **mutually exclusive** with the existing"}],"source_content_type":"text/x-rst","patch_set":1,"id":"aac49df8_bc717d41","line":64,"in_reply_to":"2bce5d39_68b05b7d","updated":"2026-10-01 17:50:39.000000000","message":"I think that after we agreed on a workflow we can decide about that, but it seems that the current storage approach fits well for our proposal, so I would still keep with zone_migration.","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":16312,"name":"Alfredo Moralejo","email":"amoralej@redhat.com","username":"amoralej"},"change_message_id":"086f6c27b0f6c775700f27587c73e7d9bcdbf3ee","unresolved":true,"context_lines":[{"line_number":92,"context_line":""},{"line_number":93,"context_line":"Two new top-level properties, both optional. The schema already sets"},{"line_number":94,"context_line":"``additionalProperties: False`` at the top level::"},{"line_number":95,"context_line":""},{"line_number":96,"context_line":"    {"},{"line_number":97,"context_line":"      \"availability_zones\": ["},{"line_number":98,"context_line":"        {\"src_az\": \"az-a\","},{"line_number":99,"context_line":"         \"dst_az\": \"az-b\","},{"line_number":100,"context_line":"         \"resource_types\": [\"instance\", \"volume\"],"},{"line_number":101,"context_line":"         \"volume_types\": ["},{"line_number":102,"context_line":"           {\"src_type\": \"ceph-a\", \"dst_type\": \"ceph-b\"}"},{"line_number":103,"context_line":"         ]}"},{"line_number":104,"context_line":"      ],"},{"line_number":105,"context_line":"      \"disable_source_nodes\": false"},{"line_number":106,"context_line":"    }"},{"line_number":107,"context_line":""},{"line_number":108,"context_line":"``availability_zones``"},{"line_number":109,"context_line":"  Array of ``{src_az, dst_az, resource_types, volume_types}``,"}],"source_content_type":"text/x-rst","patch_set":1,"id":"cfaddd16_3dda6625","line":106,"range":{"start_line":95,"start_character":1,"end_line":106,"end_character":5},"updated":"2026-09-29 15:52:23.000000000","message":"Why not something like:\n\n```\n{\n    \"compute_nodes\": [{\"src_az\": \"az-a\", \"dst_az\": \"az-b\"}],\n    \"storage_pools\": [{\"src_type\": \"ceph-a\", \"dst_type\": \"ceph-b\"}]\n}\n```\n\nIMO this is more aligned to the fact that we are not filtering volumes by AZ and would be simpler.\n\nnote we are currently always requiring src_pool in storage_pools, so we\u0027d need to discuss that. Actually, given that a pool is tied to a availability_zone, we may be able to restrict volumes in a type by using it (as a type may have volumes in multiple AZs iiuc).","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"4c4d921219c2022d940e5f5e7e7a7703e87e26da","unresolved":true,"context_lines":[{"line_number":92,"context_line":""},{"line_number":93,"context_line":"Two new top-level properties, both optional. The schema already sets"},{"line_number":94,"context_line":"``additionalProperties: False`` at the top level::"},{"line_number":95,"context_line":""},{"line_number":96,"context_line":"    {"},{"line_number":97,"context_line":"      \"availability_zones\": ["},{"line_number":98,"context_line":"        {\"src_az\": \"az-a\","},{"line_number":99,"context_line":"         \"dst_az\": \"az-b\","},{"line_number":100,"context_line":"         \"resource_types\": [\"instance\", \"volume\"],"},{"line_number":101,"context_line":"         \"volume_types\": ["},{"line_number":102,"context_line":"           {\"src_type\": \"ceph-a\", \"dst_type\": \"ceph-b\"}"},{"line_number":103,"context_line":"         ]}"},{"line_number":104,"context_line":"      ],"},{"line_number":105,"context_line":"      \"disable_source_nodes\": false"},{"line_number":106,"context_line":"    }"},{"line_number":107,"context_line":""},{"line_number":108,"context_line":"``availability_zones``"},{"line_number":109,"context_line":"  Array of ``{src_az, dst_az, resource_types, volume_types}``,"}],"source_content_type":"text/x-rst","patch_set":1,"id":"ab1f1f8d_6b1e8d66","line":106,"range":{"start_line":95,"start_character":1,"end_line":106,"end_character":5},"in_reply_to":"07008d4d_98b872d3","updated":"2026-09-29 20:37:58.000000000","message":"s/\u0027while dest_pool will always be\u0027/\u0027while dest_type will always be\u0027","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"039df4a026370beb929eb7b52d0e576208c2c1d8","unresolved":true,"context_lines":[{"line_number":92,"context_line":""},{"line_number":93,"context_line":"Two new top-level properties, both optional. The schema already sets"},{"line_number":94,"context_line":"``additionalProperties: False`` at the top level::"},{"line_number":95,"context_line":""},{"line_number":96,"context_line":"    {"},{"line_number":97,"context_line":"      \"availability_zones\": ["},{"line_number":98,"context_line":"        {\"src_az\": \"az-a\","},{"line_number":99,"context_line":"         \"dst_az\": \"az-b\","},{"line_number":100,"context_line":"         \"resource_types\": [\"instance\", \"volume\"],"},{"line_number":101,"context_line":"         \"volume_types\": ["},{"line_number":102,"context_line":"           {\"src_type\": \"ceph-a\", \"dst_type\": \"ceph-b\"}"},{"line_number":103,"context_line":"         ]}"},{"line_number":104,"context_line":"      ],"},{"line_number":105,"context_line":"      \"disable_source_nodes\": false"},{"line_number":106,"context_line":"    }"},{"line_number":107,"context_line":""},{"line_number":108,"context_line":"``availability_zones``"},{"line_number":109,"context_line":"  Array of ``{src_az, dst_az, resource_types, volume_types}``,"}],"source_content_type":"text/x-rst","patch_set":1,"id":"ff3ede39_70d09367","line":106,"range":{"start_line":95,"start_character":1,"end_line":106,"end_character":5},"in_reply_to":"4516842e_db37075f","updated":"2026-09-30 12:19:11.000000000","message":"Yeah, I am starting to think that would be better like that too. The original idea on keeping a top-level \"availability_zones\" property was to allow exclusive properties for this kind of migration, but it may not be needed in the end","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":16312,"name":"Alfredo Moralejo","email":"amoralej@redhat.com","username":"amoralej"},"change_message_id":"598241d080a8dd767860c48abaf29230c51c7dbe","unresolved":true,"context_lines":[{"line_number":92,"context_line":""},{"line_number":93,"context_line":"Two new top-level properties, both optional. The schema already sets"},{"line_number":94,"context_line":"``additionalProperties: False`` at the top level::"},{"line_number":95,"context_line":""},{"line_number":96,"context_line":"    {"},{"line_number":97,"context_line":"      \"availability_zones\": ["},{"line_number":98,"context_line":"        {\"src_az\": \"az-a\","},{"line_number":99,"context_line":"         \"dst_az\": \"az-b\","},{"line_number":100,"context_line":"         \"resource_types\": [\"instance\", \"volume\"],"},{"line_number":101,"context_line":"         \"volume_types\": ["},{"line_number":102,"context_line":"           {\"src_type\": \"ceph-a\", \"dst_type\": \"ceph-b\"}"},{"line_number":103,"context_line":"         ]}"},{"line_number":104,"context_line":"      ],"},{"line_number":105,"context_line":"      \"disable_source_nodes\": false"},{"line_number":106,"context_line":"    }"},{"line_number":107,"context_line":""},{"line_number":108,"context_line":"``availability_zones``"},{"line_number":109,"context_line":"  Array of ``{src_az, dst_az, resource_types, volume_types}``,"}],"source_content_type":"text/x-rst","patch_set":1,"id":"4516842e_db37075f","line":106,"range":{"start_line":95,"start_character":1,"end_line":106,"end_character":5},"in_reply_to":"ab1f1f8d_6b1e8d66","updated":"2026-09-30 09:41:51.000000000","message":"In my proposal, there is not `resource_types` parameters at all. Presence of `storage_pools` means volume migrations is required as defined by the parameters, while no `storage_pools`\u003d\u003d no volumes_migration at all.","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":34452,"name":"Joan Gilabert","display_name":"jgilaber","email":"jgilaber@redhat.com","username":"jgilaber"},"change_message_id":"4f879a777d2dd912827f1b41b2e5c8e9b216139b","unresolved":true,"context_lines":[{"line_number":92,"context_line":""},{"line_number":93,"context_line":"Two new top-level properties, both optional. The schema already sets"},{"line_number":94,"context_line":"``additionalProperties: False`` at the top level::"},{"line_number":95,"context_line":""},{"line_number":96,"context_line":"    {"},{"line_number":97,"context_line":"      \"availability_zones\": ["},{"line_number":98,"context_line":"        {\"src_az\": \"az-a\","},{"line_number":99,"context_line":"         \"dst_az\": \"az-b\","},{"line_number":100,"context_line":"         \"resource_types\": [\"instance\", \"volume\"],"},{"line_number":101,"context_line":"         \"volume_types\": ["},{"line_number":102,"context_line":"           {\"src_type\": \"ceph-a\", \"dst_type\": \"ceph-b\"}"},{"line_number":103,"context_line":"         ]}"},{"line_number":104,"context_line":"      ],"},{"line_number":105,"context_line":"      \"disable_source_nodes\": false"},{"line_number":106,"context_line":"    }"},{"line_number":107,"context_line":""},{"line_number":108,"context_line":"``availability_zones``"},{"line_number":109,"context_line":"  Array of ``{src_az, dst_az, resource_types, volume_types}``,"}],"source_content_type":"text/x-rst","patch_set":1,"id":"f9bc816c_459b1134","line":106,"range":{"start_line":95,"start_character":1,"end_line":106,"end_character":5},"in_reply_to":"ab1f1f8d_6b1e8d66","updated":"2026-10-01 15:15:38.000000000","message":"at first glance I think I prefer a separate `availability_zones` parameter. It seems simpler to reason about. With this addition, I think we\u0027re past the point where schema validation is feasible and we should move to validate using python code instead. Even if it\u0027s technically possible to use shcema validation it\u0027ll be too hard imo.","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"137046ab661eb7609883e3f39736a4df042749c8","unresolved":true,"context_lines":[{"line_number":92,"context_line":""},{"line_number":93,"context_line":"Two new top-level properties, both optional. The schema already sets"},{"line_number":94,"context_line":"``additionalProperties: False`` at the top level::"},{"line_number":95,"context_line":""},{"line_number":96,"context_line":"    {"},{"line_number":97,"context_line":"      \"availability_zones\": ["},{"line_number":98,"context_line":"        {\"src_az\": \"az-a\","},{"line_number":99,"context_line":"         \"dst_az\": \"az-b\","},{"line_number":100,"context_line":"         \"resource_types\": [\"instance\", \"volume\"],"},{"line_number":101,"context_line":"         \"volume_types\": ["},{"line_number":102,"context_line":"           {\"src_type\": \"ceph-a\", \"dst_type\": \"ceph-b\"}"},{"line_number":103,"context_line":"         ]}"},{"line_number":104,"context_line":"      ],"},{"line_number":105,"context_line":"      \"disable_source_nodes\": false"},{"line_number":106,"context_line":"    }"},{"line_number":107,"context_line":""},{"line_number":108,"context_line":"``availability_zones``"},{"line_number":109,"context_line":"  Array of ``{src_az, dst_az, resource_types, volume_types}``,"}],"source_content_type":"text/x-rst","patch_set":1,"id":"07008d4d_98b872d3","line":106,"range":{"start_line":95,"start_character":1,"end_line":106,"end_character":5},"in_reply_to":"cfaddd16_3dda6625","updated":"2026-09-29 17:11:58.000000000","message":"It is an option. The complexity that I see will be in the schema. When providing a src_az and dst_az, the optional and mandatory parameters changes: src_pool is not mandatory, while dest_pool will always be if resource_types has [\u0027volumes\u0027], dst_node turns an invalid option, etc. In my understanding it adds more logic to existing parameters that increases its complexity and to know what would be the right combination, and which ones are valid/supported. Below I mention the usage of scope in order to restrict resources, which seems to be the right way (outside the strategy).","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"282700bdb3b7a5286ece1974a914a8b42f5523fd","unresolved":true,"context_lines":[{"line_number":92,"context_line":""},{"line_number":93,"context_line":"Two new top-level properties, both optional. The schema already sets"},{"line_number":94,"context_line":"``additionalProperties: False`` at the top level::"},{"line_number":95,"context_line":""},{"line_number":96,"context_line":"    {"},{"line_number":97,"context_line":"      \"availability_zones\": ["},{"line_number":98,"context_line":"        {\"src_az\": \"az-a\","},{"line_number":99,"context_line":"         \"dst_az\": \"az-b\","},{"line_number":100,"context_line":"         \"resource_types\": [\"instance\", \"volume\"],"},{"line_number":101,"context_line":"         \"volume_types\": ["},{"line_number":102,"context_line":"           {\"src_type\": \"ceph-a\", \"dst_type\": \"ceph-b\"}"},{"line_number":103,"context_line":"         ]}"},{"line_number":104,"context_line":"      ],"},{"line_number":105,"context_line":"      \"disable_source_nodes\": false"},{"line_number":106,"context_line":"    }"},{"line_number":107,"context_line":""},{"line_number":108,"context_line":"``availability_zones``"},{"line_number":109,"context_line":"  Array of ``{src_az, dst_az, resource_types, volume_types}``,"}],"source_content_type":"text/x-rst","patch_set":1,"id":"f33de0eb_bb4debb1","line":106,"range":{"start_line":95,"start_character":1,"end_line":106,"end_character":5},"in_reply_to":"f9bc816c_459b1134","updated":"2026-10-01 17:50:39.000000000","message":"It could be separated parameter but now I see that it makes more sense to be inside `compute_nodes` since we plan to use destination_az only when migrating instances. For volumes, user will still need to provide src_pools/dest_pools/dest_types mapping. If we decide go with a `availability_zones` it would be a compute_src_az and compute_dest_az parameters.\nAbout the validation, IITC today we only have schema validation at the API, so users get a earlier error when creating an audit, and we have some validations at strategy pre_execute which is too late from my pov (only the ones that are not possible to validate with an schema).","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"77b0d7124ce6d8897ce66bd09ff7eadd3dbf7c69","unresolved":true,"context_lines":[{"line_number":92,"context_line":""},{"line_number":93,"context_line":"Two new top-level properties, both optional. The schema already sets"},{"line_number":94,"context_line":"``additionalProperties: False`` at the top level::"},{"line_number":95,"context_line":""},{"line_number":96,"context_line":"    {"},{"line_number":97,"context_line":"      \"availability_zones\": ["},{"line_number":98,"context_line":"        {\"src_az\": \"az-a\","},{"line_number":99,"context_line":"         \"dst_az\": \"az-b\","},{"line_number":100,"context_line":"         \"resource_types\": [\"instance\", \"volume\"],"},{"line_number":101,"context_line":"         \"volume_types\": ["},{"line_number":102,"context_line":"           {\"src_type\": \"ceph-a\", \"dst_type\": \"ceph-b\"}"},{"line_number":103,"context_line":"         ]}"},{"line_number":104,"context_line":"      ],"},{"line_number":105,"context_line":"      \"disable_source_nodes\": false"},{"line_number":106,"context_line":"    }"},{"line_number":107,"context_line":""},{"line_number":108,"context_line":"``availability_zones``"},{"line_number":109,"context_line":"  Array of ``{src_az, dst_az, resource_types, volume_types}``,"}],"source_content_type":"text/x-rst","patch_set":1,"id":"0640bbb9_cca1b427","line":106,"range":{"start_line":95,"start_character":1,"end_line":106,"end_character":5},"in_reply_to":"ff3ede39_70d09367","updated":"2026-09-30 22:57:10.000000000","message":"Fundamentally, you cannot and should not assume that an AZ name is\naligned between different OpenStack services.\n\nYou also should not assume that volume types, storage backends, and\nAZs have a 1:1:1 relationship.\n\nFor example, the same volume type can be available in multiple AZs,\nand multiple storage backends can satisfy the same volume type within\nthe same or different AZs.\n\nThe mapping between Nova, Cinder, and Neutron is roughly:\n```\nNova\n-----------------------------------------------------------------------\nprovider resource        compute node\n\nscheduling policy        flavor\n                         + extra specs\n\ntenant resource          server\n\nAZ placement domain      host aggregate\n                         with AZ metadata\n\nAZ selected on           server\n                         availability_zone\n\n\nCinder\n-----------------------------------------------------------------------\nprovider resource        storage backend\n\nscheduling policy        volume type\n                         + extra specs\n\ntenant resource          volume\n\nAZ placement domain      backend AZ\n                         configuration\n\nAZ selected on           volume\n                         availability_zone\n\n\nNeutron\n-----------------------------------------------------------------------\nprovider resource        network node / agent / chassis\n\nscheduling policy        network/router attributes\n                         + AZ hints / flavor\n\ntenant resource          network / router\n                         (ports indirectly)\n\nAZ placement domain      agent/chassis AZ\n\nAZ selected on           network / router\n                         availability_zone_hints\n\n```\nNeutron also has a flavor framework:\nhttps://wiki.openstack.org/wiki/Neutron/FlavorFramework\n\n\nConceptually:\n```\nNova:\n    AZ primarily constrains WHERE a server is placed.\n    Flavor primarily constrains WHAT compute capabilities can\n    satisfy it.\n\nCinder:\n    AZ primarily constrains WHERE a volume is placed.\n    Volume type primarily constrains WHAT storage capabilities\n    can satisfy it, but a volume type can additionally constrain\n    WHERE via RESKEY:availability_zones.\n\nNeutron:\n    AZ constrains WHERE service functions for a network or router\n    are placed.\n```\n\nFor Nova:\n```\nhost aggregate\n    |\n    +-- metadata: availability_zone\u003daz1\n    |\n    +-- compute-01\n    +-- compute-02\n\nserver --availability-zone az1\n           |\n           v\nNova scheduler chooses one of those compute nodes\n```\n\nFor Neutron:\n```\nDHCP agent / L3 agent\n      |\n      +-- availability_zone\u003daz1\n      |\nnetwork / router\n      |\n      +-- availability_zone_hints\u003d[az1]\n```\n\nFor Cinder:\n```\n                         explicit AZ\nvolume create ------------------------------------+\n  --availability-zone az1                        |\n                                                  v\n                                           requested AZ set\n                                                  |\nvolume type                                       |\n  +-- RESKEY:availability_zones\u003daz1,az2 ----------+\n                                                  |\n                                                  v\n                                      AvailabilityZoneFilter\n                                                  |\n                                                  v\n                                  candidate storage backends\n                                                  |\n                                                  v\n                                  other filters and weighers\n                                                  |\n                                                  v\n                                       selected backend\n\n\nFor example:\n\nvolume type: fast\n    |\n    +-- RESKEY:availability_zones\u003daz1,az2\n    |\n    +-----------------------------+\n                                  |\nvolume --availability-zone az1    |\n    |                             |\n    +-------------+---------------+\n                  |\n                  v\n        acceptable AZ \u003d az1\n                  |\n                  v\n        backend-a  az1\n        backend-b  az1\n        backend-c  az2\n                  |\n                  v\n      scheduler selects an az1\n      backend that also satisfies\n      the volume type and other\n      scheduler constraints\n```\n\n\nThe important point is that an availability zone is a service-local\nscheduling domain.\n\nAn AZ called \"az1\" in Nova is not inherently the same thing as \"az1\"\nin Cinder or Neutron. Operators may deliberately align the names and\nunderlying failure domains, but OpenStack does not require that\nalignment.\n\nthat a very long way to say this shoudl looks more like this\n```\n{\n  \"compute\": [\n    {\n      \"src_az\": \"compute-a\",\n      \"dst_az\": \"compute-b\",\n      \"pinned_instances\": \"exclude\"\n    }\n  ],\n\n  \"storage\": [\n    {\n      \"src_az\": \"storage-a\",\n      \"dst_az\": \"storage-b\",\n      \"volume_type_mappings\": [\n        {\n          \"src_type\": \"ceph-fast\",\n          \"dst_type\": \"nvme-fast\"\n        },\n        {\n          \"src_type\": \"ceph-slow\",\n          \"dst_type\": \"nvme-slow\"\n        }\n      ]\n    }\n  ],\n\n  \"disable_source_nodes\": false\n}\n```\n\nstorage AZ migration always means:\n\n    move volumes from a backend in src_az\n    to a suitable backend in dst_az\n\nvolume_type_mappings optionally means:\n\n    if the volume\u0027s current type matches src_type,\n    also retype it to dst_type\n\nif no mapping matches:\n\n    preserve the existing volume type","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"77b0d7124ce6d8897ce66bd09ff7eadd3dbf7c69","unresolved":true,"context_lines":[{"line_number":105,"context_line":"      \"disable_source_nodes\": false"},{"line_number":106,"context_line":"    }"},{"line_number":107,"context_line":""},{"line_number":108,"context_line":"``availability_zones``"},{"line_number":109,"context_line":"  Array of ``{src_az, dst_az, resource_types, volume_types}``,"},{"line_number":110,"context_line":"  ``additionalProperties: False``. Everything one zone pair needs is"},{"line_number":111,"context_line":"  self-contained in its own entry, so a single audit can drain several pairs"}],"source_content_type":"text/x-rst","patch_set":1,"id":"0e30b432_4509ea38","line":108,"updated":"2026-09-30 22:57:10.000000000","message":"i got as far as here tonight.\n\nalso if it snot obviousl i had ai rewrote/spellehck my commetn above and create the diagrams.\n\nteh feed back is still ming but the amoutn of typos was excessive even for me\nso i got it to clean it up a bit.","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"282700bdb3b7a5286ece1974a914a8b42f5523fd","unresolved":true,"context_lines":[{"line_number":105,"context_line":"      \"disable_source_nodes\": false"},{"line_number":106,"context_line":"    }"},{"line_number":107,"context_line":""},{"line_number":108,"context_line":"``availability_zones``"},{"line_number":109,"context_line":"  Array of ``{src_az, dst_az, resource_types, volume_types}``,"},{"line_number":110,"context_line":"  ``additionalProperties: False``. Everything one zone pair needs is"},{"line_number":111,"context_line":"  self-contained in its own entry, so a single audit can drain several pairs"}],"source_content_type":"text/x-rst","patch_set":1,"id":"9baf2690_38a94e07","line":108,"in_reply_to":"0e30b432_4509ea38","updated":"2026-10-01 17:50:39.000000000","message":"ack, you didn\u0027t reach the \u0027AZ-pinned instances\u0027 section, but mentioned that case above. I will likely rewrite it too, and maybe you get a new version.","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":16312,"name":"Alfredo Moralejo","email":"amoralej@redhat.com","username":"amoralej"},"change_message_id":"086f6c27b0f6c775700f27587c73e7d9bcdbf3ee","unresolved":true,"context_lines":[{"line_number":119,"context_line":"  \"volume\"]``, ``uniqueItems: true``, ``minItems: 1``, default"},{"line_number":120,"context_line":"  ``[\"instance\", \"volume\"]``. It scopes what a single AZ entry drains."},{"line_number":121,"context_line":""},{"line_number":122,"context_line":"  ``[\"instance\"]`` does *not* suppress retyping of volumes attached to a"},{"line_number":123,"context_line":"  migrating instance. A cross-AZ instance move without the retype leaves the"},{"line_number":124,"context_line":"  instance reading from a source-zone backend, so the coupled retype is a"},{"line_number":125,"context_line":"  correctness requirement, not a user preference. This asymmetry must be"},{"line_number":126,"context_line":"  documented prominently."},{"line_number":127,"context_line":""},{"line_number":128,"context_line":"  ``volume_types`` is an array of ``{src_type, dst_type}``, both required,"},{"line_number":129,"context_line":"  ``additionalProperties: False``. It serves two purposes within its entry:"}],"source_content_type":"text/x-rst","patch_set":1,"id":"b595f890_90b78085","line":126,"range":{"start_line":122,"start_character":0,"end_line":126,"end_character":25},"updated":"2026-09-29 15:52:23.000000000","message":"I think that\u0027s not always true. Cloud operators may have unaligned cinder and nova availability zones and enable cross-AZ in some cases. IMO, a cloud operator setting `\"resource_types\": [\"instance\"]` should only get the instances migrated and volumes shouldn keep as-is. While the 1:1 for AZs between nova and cinder may be common or even recommended there are cases where that may not be the case iiuc.\n\nIf the cloud admin wants to move the volumes, they should also add it to `resources_types` explicitely imo.","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":16312,"name":"Alfredo Moralejo","email":"amoralej@redhat.com","username":"amoralej"},"change_message_id":"de20bbd143d1674ff9ab75378b94212f4987dc6d","unresolved":true,"context_lines":[{"line_number":119,"context_line":"  \"volume\"]``, ``uniqueItems: true``, ``minItems: 1``, default"},{"line_number":120,"context_line":"  ``[\"instance\", \"volume\"]``. It scopes what a single AZ entry drains."},{"line_number":121,"context_line":""},{"line_number":122,"context_line":"  ``[\"instance\"]`` does *not* suppress retyping of volumes attached to a"},{"line_number":123,"context_line":"  migrating instance. A cross-AZ instance move without the retype leaves the"},{"line_number":124,"context_line":"  instance reading from a source-zone backend, so the coupled retype is a"},{"line_number":125,"context_line":"  correctness requirement, not a user preference. This asymmetry must be"},{"line_number":126,"context_line":"  documented prominently."},{"line_number":127,"context_line":""},{"line_number":128,"context_line":"  ``volume_types`` is an array of ``{src_type, dst_type}``, both required,"},{"line_number":129,"context_line":"  ``additionalProperties: False``. It serves two purposes within its entry:"}],"source_content_type":"text/x-rst","patch_set":1,"id":"d5a32960_811d58b4","line":126,"range":{"start_line":122,"start_character":0,"end_line":126,"end_character":25},"in_reply_to":"276dec08_4b0ccb46","updated":"2026-09-30 13:10:22.000000000","message":"I fully agree, the actual behaviour of the existing `with_attached_volume` is missleading and I even have doubts if it\u0027s useful. We may reconsider if it\u0027s good to maintain, remove or rename. I\u0027m not sure how useful it is, tbh.","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"adeb8dbebe14aa2cd3f2d44e1ad37d5491561eeb","unresolved":true,"context_lines":[{"line_number":119,"context_line":"  \"volume\"]``, ``uniqueItems: true``, ``minItems: 1``, default"},{"line_number":120,"context_line":"  ``[\"instance\", \"volume\"]``. It scopes what a single AZ entry drains."},{"line_number":121,"context_line":""},{"line_number":122,"context_line":"  ``[\"instance\"]`` does *not* suppress retyping of volumes attached to a"},{"line_number":123,"context_line":"  migrating instance. A cross-AZ instance move without the retype leaves the"},{"line_number":124,"context_line":"  instance reading from a source-zone backend, so the coupled retype is a"},{"line_number":125,"context_line":"  correctness requirement, not a user preference. This asymmetry must be"},{"line_number":126,"context_line":"  documented prominently."},{"line_number":127,"context_line":""},{"line_number":128,"context_line":"  ``volume_types`` is an array of ``{src_type, dst_type}``, both required,"},{"line_number":129,"context_line":"  ``additionalProperties: False``. It serves two purposes within its entry:"}],"source_content_type":"text/x-rst","patch_set":1,"id":"d93c2738_6af4b5e4","line":126,"range":{"start_line":122,"start_character":0,"end_line":126,"end_character":25},"in_reply_to":"76be45fe_7cc62d74","updated":"2026-10-02 17:57:50.000000000","message":"`with_attached_volume` should be deprecated IMHO, it changes only the order of the actions, which can afterwards changed again in the planner phase, so it is confusing","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"137046ab661eb7609883e3f39736a4df042749c8","unresolved":true,"context_lines":[{"line_number":119,"context_line":"  \"volume\"]``, ``uniqueItems: true``, ``minItems: 1``, default"},{"line_number":120,"context_line":"  ``[\"instance\", \"volume\"]``. It scopes what a single AZ entry drains."},{"line_number":121,"context_line":""},{"line_number":122,"context_line":"  ``[\"instance\"]`` does *not* suppress retyping of volumes attached to a"},{"line_number":123,"context_line":"  migrating instance. A cross-AZ instance move without the retype leaves the"},{"line_number":124,"context_line":"  instance reading from a source-zone backend, so the coupled retype is a"},{"line_number":125,"context_line":"  correctness requirement, not a user preference. This asymmetry must be"},{"line_number":126,"context_line":"  documented prominently."},{"line_number":127,"context_line":""},{"line_number":128,"context_line":"  ``volume_types`` is an array of ``{src_type, dst_type}``, both required,"},{"line_number":129,"context_line":"  ``additionalProperties: False``. It serves two purposes within its entry:"}],"source_content_type":"text/x-rst","patch_set":1,"id":"bb949d55_944cdbe2","line":126,"range":{"start_line":122,"start_character":0,"end_line":126,"end_character":25},"in_reply_to":"b595f890_90b78085","updated":"2026-09-29 17:11:58.000000000","message":"So there are 3 possibilities and 2 configurations proposed. 1) instances only, 2) instances + attached volumes and 3) available volumes. So in the end, ideally we could have those 3. So we could extend the resource_typesto volumes an attached_volumes_only. But I agree that looks weird that volumes are migrates when \"volumes\" is removed from resource_types. But, it should be possible to have the option to only migrate \"instances with attached volumes\" and skip the \"available\"volumes. I always see that scope could be helpfull here instead of new configurations, but it is today limited to projects/volumes(uuids)/pools (we could exclude volumes per status for example, but that is another discussion I guess)","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":34452,"name":"Joan Gilabert","display_name":"jgilaber","email":"jgilaber@redhat.com","username":"jgilaber"},"change_message_id":"4f879a777d2dd912827f1b41b2e5c8e9b216139b","unresolved":true,"context_lines":[{"line_number":119,"context_line":"  \"volume\"]``, ``uniqueItems: true``, ``minItems: 1``, default"},{"line_number":120,"context_line":"  ``[\"instance\", \"volume\"]``. It scopes what a single AZ entry drains."},{"line_number":121,"context_line":""},{"line_number":122,"context_line":"  ``[\"instance\"]`` does *not* suppress retyping of volumes attached to a"},{"line_number":123,"context_line":"  migrating instance. A cross-AZ instance move without the retype leaves the"},{"line_number":124,"context_line":"  instance reading from a source-zone backend, so the coupled retype is a"},{"line_number":125,"context_line":"  correctness requirement, not a user preference. This asymmetry must be"},{"line_number":126,"context_line":"  documented prominently."},{"line_number":127,"context_line":""},{"line_number":128,"context_line":"  ``volume_types`` is an array of ``{src_type, dst_type}``, both required,"},{"line_number":129,"context_line":"  ``additionalProperties: False``. It serves two purposes within its entry:"}],"source_content_type":"text/x-rst","patch_set":1,"id":"76be45fe_7cc62d74","line":126,"range":{"start_line":122,"start_character":0,"end_line":126,"end_character":25},"in_reply_to":"bb949d55_944cdbe2","updated":"2026-10-01 15:15:38.000000000","message":"I agree with Alfredo here, from UX, migrating volumes when the user has apparently requested not to seems unexpected. What I\u0027m not sure, is what could happen if we do not touch the volumes after migrating  the attached instances. Would that always work? Would it cause any problem for Nova and fail the action?","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":16312,"name":"Alfredo Moralejo","email":"amoralej@redhat.com","username":"amoralej"},"change_message_id":"598241d080a8dd767860c48abaf29230c51c7dbe","unresolved":true,"context_lines":[{"line_number":119,"context_line":"  \"volume\"]``, ``uniqueItems: true``, ``minItems: 1``, default"},{"line_number":120,"context_line":"  ``[\"instance\", \"volume\"]``. It scopes what a single AZ entry drains."},{"line_number":121,"context_line":""},{"line_number":122,"context_line":"  ``[\"instance\"]`` does *not* suppress retyping of volumes attached to a"},{"line_number":123,"context_line":"  migrating instance. A cross-AZ instance move without the retype leaves the"},{"line_number":124,"context_line":"  instance reading from a source-zone backend, so the coupled retype is a"},{"line_number":125,"context_line":"  correctness requirement, not a user preference. This asymmetry must be"},{"line_number":126,"context_line":"  documented prominently."},{"line_number":127,"context_line":""},{"line_number":128,"context_line":"  ``volume_types`` is an array of ``{src_type, dst_type}``, both required,"},{"line_number":129,"context_line":"  ``additionalProperties: False``. It serves two purposes within its entry:"}],"source_content_type":"text/x-rst","patch_set":1,"id":"f8a875c8_a75c624c","line":126,"range":{"start_line":122,"start_character":0,"end_line":126,"end_character":25},"in_reply_to":"bb949d55_944cdbe2","updated":"2026-09-30 09:41:51.000000000","message":"I don\u0027t think we need to cover the `instances + attached volumes only` case. We currently don\u0027t support it. As my understanding the cases to cover are:\n1. instances only (as defined in `compute_nodes` parameter)\n2. volumes only (as defined in `storage_pools` parameter)\n3. instances + *all* volumens (as defined in `compute_nodes` + `storage_pools` parameter)\n\nMy understanding is that `instances + attached volumes only` has not been requested and I\u0027m not sure if it\u0027s a critical case to cover (there may be cases but if a cloud admin is wanting to totally drain an AZ or a storage pool, i think that includes unattached volumes in most cases, as they may want to attach them at a later time). If we want to cover that case, we may add a new top level parameter or even a parameter on each element in  storage_pools.\n\n```\n{\n    \"compute_nodes\": [{\"src_az\": \"az-a\", \"dst_az\": \"az-b\"}],\n    \"storage_pools\": [{\"src_type\": \"ceph-a\", \"dst_type\": \"ceph-b\", \"attached_only\": true}]\n}\n```\n\nIn that case we\u0027d need to define if attach means \"volumes with any attachment\" or \"volumes with an attachment to a vm that is going to be migrated\"","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"039df4a026370beb929eb7b52d0e576208c2c1d8","unresolved":true,"context_lines":[{"line_number":119,"context_line":"  \"volume\"]``, ``uniqueItems: true``, ``minItems: 1``, default"},{"line_number":120,"context_line":"  ``[\"instance\", \"volume\"]``. It scopes what a single AZ entry drains."},{"line_number":121,"context_line":""},{"line_number":122,"context_line":"  ``[\"instance\"]`` does *not* suppress retyping of volumes attached to a"},{"line_number":123,"context_line":"  migrating instance. A cross-AZ instance move without the retype leaves the"},{"line_number":124,"context_line":"  instance reading from a source-zone backend, so the coupled retype is a"},{"line_number":125,"context_line":"  correctness requirement, not a user preference. This asymmetry must be"},{"line_number":126,"context_line":"  documented prominently."},{"line_number":127,"context_line":""},{"line_number":128,"context_line":"  ``volume_types`` is an array of ``{src_type, dst_type}``, both required,"},{"line_number":129,"context_line":"  ``additionalProperties: False``. It serves two purposes within its entry:"}],"source_content_type":"text/x-rst","patch_set":1,"id":"276dec08_4b0ccb46","line":126,"range":{"start_line":122,"start_character":0,"end_line":126,"end_character":25},"in_reply_to":"f8a875c8_a75c624c","updated":"2026-09-30 12:19:11.000000000","message":"I think that since we are here, we could cover the 3, even without a clear requirement for it, it may be useful. I don\u0027t see this stratetegy usage as a single audit run, instead I think that it would be used to Drain workloads in multiple steps for big deployments, and having different options might help on that.\nThe issue that I see is with `with_attached_volume` top level property which is confusing and we may need to rename it.","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":16312,"name":"Alfredo Moralejo","email":"amoralej@redhat.com","username":"amoralej"},"change_message_id":"086f6c27b0f6c775700f27587c73e7d9bcdbf3ee","unresolved":true,"context_lines":[{"line_number":127,"context_line":""},{"line_number":128,"context_line":"  ``volume_types`` is an array of ``{src_type, dst_type}``, both required,"},{"line_number":129,"context_line":"  ``additionalProperties: False``. It serves two purposes within its entry:"},{"line_number":130,"context_line":"  it selects standalone volumes to retype, and it is the lookup table used to"},{"line_number":131,"context_line":"  retype volumes attached to a migrating instance. ``dst_type`` is required"},{"line_number":132,"context_line":"  because crossing an AZ boundary always implies a retype, and a retype has"},{"line_number":133,"context_line":"  no meaning without a target type. It is required whenever"}],"source_content_type":"text/x-rst","patch_set":1,"id":"5ae7a563_ef84cd4c","line":130,"range":{"start_line":130,"start_character":13,"end_line":130,"end_character":23},"updated":"2026-09-29 15:52:23.000000000","message":"in this context, standalone means \"unattached\"?","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"adeb8dbebe14aa2cd3f2d44e1ad37d5491561eeb","unresolved":false,"context_lines":[{"line_number":127,"context_line":""},{"line_number":128,"context_line":"  ``volume_types`` is an array of ``{src_type, dst_type}``, both required,"},{"line_number":129,"context_line":"  ``additionalProperties: False``. It serves two purposes within its entry:"},{"line_number":130,"context_line":"  it selects standalone volumes to retype, and it is the lookup table used to"},{"line_number":131,"context_line":"  retype volumes attached to a migrating instance. ``dst_type`` is required"},{"line_number":132,"context_line":"  because crossing an AZ boundary always implies a retype, and a retype has"},{"line_number":133,"context_line":"  no meaning without a target type. It is required whenever"}],"source_content_type":"text/x-rst","patch_set":1,"id":"618f0369_7003800b","line":130,"range":{"start_line":130,"start_character":13,"end_line":130,"end_character":23},"in_reply_to":"3ceea12a_ddf33787","updated":"2026-10-02 17:57:50.000000000","message":"this is now ommited. There is only a mention to attached volumes selection, if the team agree with that option too. It should be possible to migrate available volumes when providing only the storage_pools entries.","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"137046ab661eb7609883e3f39736a4df042749c8","unresolved":true,"context_lines":[{"line_number":127,"context_line":""},{"line_number":128,"context_line":"  ``volume_types`` is an array of ``{src_type, dst_type}``, both required,"},{"line_number":129,"context_line":"  ``additionalProperties: False``. It serves two purposes within its entry:"},{"line_number":130,"context_line":"  it selects standalone volumes to retype, and it is the lookup table used to"},{"line_number":131,"context_line":"  retype volumes attached to a migrating instance. ``dst_type`` is required"},{"line_number":132,"context_line":"  because crossing an AZ boundary always implies a retype, and a retype has"},{"line_number":133,"context_line":"  no meaning without a target type. It is required whenever"}],"source_content_type":"text/x-rst","patch_set":1,"id":"3ceea12a_ddf33787","line":130,"range":{"start_line":130,"start_character":13,"end_line":130,"end_character":23},"in_reply_to":"5ae7a563_ef84cd4c","updated":"2026-09-29 17:11:58.000000000","message":"yeah, the correct status is \"available\" IIRC. Needs update","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":16312,"name":"Alfredo Moralejo","email":"amoralej@redhat.com","username":"amoralej"},"change_message_id":"086f6c27b0f6c775700f27587c73e7d9bcdbf3ee","unresolved":true,"context_lines":[{"line_number":135,"context_line":"  expresses; the attached-volume case is enforced at run time by the skip"},{"line_number":136,"context_line":"  rule below."},{"line_number":137,"context_line":""},{"line_number":138,"context_line":"  Selection is purely by volume type. The strategy queries no external"},{"line_number":139,"context_line":"  service and does not consult ``StorageNode.zone``; the operator\u0027s mapping"},{"line_number":140,"context_line":"  *is* the declaration of which type belongs to which zone. This is"},{"line_number":141,"context_line":"  deliberate — it keeps the decision engine\u0027s inputs explicit and auditable."},{"line_number":142,"context_line":""},{"line_number":143,"context_line":"``disable_source_nodes``"},{"line_number":144,"context_line":"  Boolean, default ``false``."}],"source_content_type":"text/x-rst","patch_set":1,"id":"df7394f7_da1e4216","line":141,"range":{"start_line":138,"start_character":0,"end_line":141,"end_character":76},"updated":"2026-09-29 15:52:23.000000000","message":"This makes having the volumes_types inside availability_zones confusing IMO. I think this schema seems to say \"migrate the volumes which are in the AZ az-a *and* type ceph-a to be retype to ceph-b\". But as you said, this is actually not filtering by zone, only by types. Otherwise, i think we should apply the filter based on the zone of the StorageNode where the volume is running.","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"adeb8dbebe14aa2cd3f2d44e1ad37d5491561eeb","unresolved":true,"context_lines":[{"line_number":135,"context_line":"  expresses; the attached-volume case is enforced at run time by the skip"},{"line_number":136,"context_line":"  rule below."},{"line_number":137,"context_line":""},{"line_number":138,"context_line":"  Selection is purely by volume type. The strategy queries no external"},{"line_number":139,"context_line":"  service and does not consult ``StorageNode.zone``; the operator\u0027s mapping"},{"line_number":140,"context_line":"  *is* the declaration of which type belongs to which zone. This is"},{"line_number":141,"context_line":"  deliberate — it keeps the decision engine\u0027s inputs explicit and auditable."},{"line_number":142,"context_line":""},{"line_number":143,"context_line":"``disable_source_nodes``"},{"line_number":144,"context_line":"  Boolean, default ``false``."}],"source_content_type":"text/x-rst","patch_set":1,"id":"87135e91_892e446b","line":141,"range":{"start_line":138,"start_character":0,"end_line":141,"end_character":76},"in_reply_to":"7581f3c5_3bdc223b","updated":"2026-10-02 17:57:50.000000000","message":"So for now, we keep the storage part similar to current implementation, we would extend to also filter by src_type -\u003e dest_type (which can be combined with scope today)","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"137046ab661eb7609883e3f39736a4df042749c8","unresolved":true,"context_lines":[{"line_number":135,"context_line":"  expresses; the attached-volume case is enforced at run time by the skip"},{"line_number":136,"context_line":"  rule below."},{"line_number":137,"context_line":""},{"line_number":138,"context_line":"  Selection is purely by volume type. The strategy queries no external"},{"line_number":139,"context_line":"  service and does not consult ``StorageNode.zone``; the operator\u0027s mapping"},{"line_number":140,"context_line":"  *is* the declaration of which type belongs to which zone. This is"},{"line_number":141,"context_line":"  deliberate — it keeps the decision engine\u0027s inputs explicit and auditable."},{"line_number":142,"context_line":""},{"line_number":143,"context_line":"``disable_source_nodes``"},{"line_number":144,"context_line":"  Boolean, default ``false``."}],"source_content_type":"text/x-rst","patch_set":1,"id":"7581f3c5_3bdc223b","line":141,"range":{"start_line":138,"start_character":0,"end_line":141,"end_character":76},"in_reply_to":"df7394f7_da1e4216","updated":"2026-09-29 17:11:58.000000000","message":"Right, for the \"available\" volumes we can filter per availability zone yes, but it would still require the mapping src_type -\u003e dest_type, unless we allow user to provide a fallback/default volume type.","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":16312,"name":"Alfredo Moralejo","email":"amoralej@redhat.com","username":"amoralej"},"change_message_id":"086f6c27b0f6c775700f27587c73e7d9bcdbf3ee","unresolved":true,"context_lines":[{"line_number":174,"context_line":"``microversion_parse``."},{"line_number":175,"context_line":""},{"line_number":176,"context_line":"The ``Migrate`` action gains a ``destination_az`` input parameter, mutually"},{"line_number":177,"context_line":"exclusive with ``destination_node``. Its ``pre_condition`` already guards the"},{"line_number":178,"context_line":"destination-node existence and enabled checks behind ``if"},{"line_number":179,"context_line":"self.destination_node:``, so the AZ path bypasses them naturally."},{"line_number":180,"context_line":""},{"line_number":181,"context_line":"Volume flow"},{"line_number":182,"context_line":"-----------"}],"source_content_type":"text/x-rst","patch_set":1,"id":"779fc3a0_805b532c","line":179,"range":{"start_line":177,"start_character":36,"end_line":179,"end_character":65},"updated":"2026-09-29 15:52:23.000000000","message":"we should add another check to pre_condition to check that destination_az exists (fail otherwise) and that the instance is not running in it (skip).","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"137046ab661eb7609883e3f39736a4df042749c8","unresolved":true,"context_lines":[{"line_number":174,"context_line":"``microversion_parse``."},{"line_number":175,"context_line":""},{"line_number":176,"context_line":"The ``Migrate`` action gains a ``destination_az`` input parameter, mutually"},{"line_number":177,"context_line":"exclusive with ``destination_node``. Its ``pre_condition`` already guards the"},{"line_number":178,"context_line":"destination-node existence and enabled checks behind ``if"},{"line_number":179,"context_line":"self.destination_node:``, so the AZ path bypasses them naturally."},{"line_number":180,"context_line":""},{"line_number":181,"context_line":"Volume flow"},{"line_number":182,"context_line":"-----------"}],"source_content_type":"text/x-rst","patch_set":1,"id":"c56ef142_fd8c83c1","line":179,"range":{"start_line":177,"start_character":36,"end_line":179,"end_character":65},"in_reply_to":"779fc3a0_805b532c","updated":"2026-09-29 17:11:58.000000000","message":"+1 agree","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"adeb8dbebe14aa2cd3f2d44e1ad37d5491561eeb","unresolved":false,"context_lines":[{"line_number":174,"context_line":"``microversion_parse``."},{"line_number":175,"context_line":""},{"line_number":176,"context_line":"The ``Migrate`` action gains a ``destination_az`` input parameter, mutually"},{"line_number":177,"context_line":"exclusive with ``destination_node``. Its ``pre_condition`` already guards the"},{"line_number":178,"context_line":"destination-node existence and enabled checks behind ``if"},{"line_number":179,"context_line":"self.destination_node:``, so the AZ path bypasses them naturally."},{"line_number":180,"context_line":""},{"line_number":181,"context_line":"Volume flow"},{"line_number":182,"context_line":"-----------"}],"source_content_type":"text/x-rst","patch_set":1,"id":"4021625c_4ec53c81","line":179,"range":{"start_line":177,"start_character":36,"end_line":179,"end_character":65},"in_reply_to":"c56ef142_fd8c83c1","updated":"2026-10-02 17:57:50.000000000","message":"Added","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":16312,"name":"Alfredo Moralejo","email":"amoralej@redhat.com","username":"amoralej"},"change_message_id":"086f6c27b0f6c775700f27587c73e7d9bcdbf3ee","unresolved":true,"context_lines":[{"line_number":181,"context_line":"Volume flow"},{"line_number":182,"context_line":"-----------"},{"line_number":183,"context_line":""},{"line_number":184,"context_line":"Both paths below emit the existing ``volume_migrate`` action with"},{"line_number":185,"context_line":"``migration_type: \"retype\"``, which routes to ``cinder_helper.retype()`` with"},{"line_number":186,"context_line":"``migration_policy\u003d\"on-demand\"``."},{"line_number":187,"context_line":""},{"line_number":188,"context_line":"**Standalone volumes**, gated by the entry\u0027s ``resource_types`` containing"},{"line_number":189,"context_line":"``\"volume\"``: a volume is a target when it has no attachments and its"}],"source_content_type":"text/x-rst","patch_set":1,"id":"3d7ed605_130bc01a","line":186,"range":{"start_line":184,"start_character":0,"end_line":186,"end_character":33},"updated":"2026-09-29 15:52:23.000000000","message":"while this is the usual case, zone_migrate currently supports the option to use the os  os-migrate_volume cinder api (https://docs.openstack.org/api-ref/block-storage/v3/#migrate-a-volume), and i think we can keep it as an option (currently it\u0027s used when a user uses `{\"storage_pools\": [{\"src_pool\": \"pool-a\", \"src_type\": \"type-a\", \"dst_pool\": \"pool-b\"}]]` i.e.","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":16312,"name":"Alfredo Moralejo","email":"amoralej@redhat.com","username":"amoralej"},"change_message_id":"598241d080a8dd767860c48abaf29230c51c7dbe","unresolved":true,"context_lines":[{"line_number":181,"context_line":"Volume flow"},{"line_number":182,"context_line":"-----------"},{"line_number":183,"context_line":""},{"line_number":184,"context_line":"Both paths below emit the existing ``volume_migrate`` action with"},{"line_number":185,"context_line":"``migration_type: \"retype\"``, which routes to ``cinder_helper.retype()`` with"},{"line_number":186,"context_line":"``migration_policy\u003d\"on-demand\"``."},{"line_number":187,"context_line":""},{"line_number":188,"context_line":"**Standalone volumes**, gated by the entry\u0027s ``resource_types`` containing"},{"line_number":189,"context_line":"``\"volume\"``: a volume is a target when it has no attachments and its"}],"source_content_type":"text/x-rst","patch_set":1,"id":"db856548_a09fbc42","line":186,"range":{"start_line":184,"start_character":0,"end_line":186,"end_character":33},"in_reply_to":"119d5346_db56edb8","updated":"2026-09-30 09:41:51.000000000","message":"The need of a retype is a convention (and maybe good practice, that\u0027d be question for cinder sme) but afaik, cinder supports this topology:\n\n- AZ-1: has a pool `pool-az-1` which has volume_backend_name `multiaz`\n- AZ-2: has a pool `pool-az-2` which has volume_backend_name `multiaz`\n- volume type `volumes` with volume_backend_name `multiaz`\n\nIn that case user would create the volumes with parameters `volume_type\u003dmultiaz` and `availability_zone\u003d[AZ1|AZ2]` so that volumes would be created in the right AZ. In that case, moving data from AZ1 to AZ2 could be done currently with zone_migration config `{\"storage_pools\": [{\"src_pool\": \"pool-az-1\", \"src_type\": \"multiaz\", \"dst_pool\": \"pool-az-2\"}]]`. While this is not the case described by the user, this is a case currently supported in zone_migration and can be useful for some cases.","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"adeb8dbebe14aa2cd3f2d44e1ad37d5491561eeb","unresolved":true,"context_lines":[{"line_number":181,"context_line":"Volume flow"},{"line_number":182,"context_line":"-----------"},{"line_number":183,"context_line":""},{"line_number":184,"context_line":"Both paths below emit the existing ``volume_migrate`` action with"},{"line_number":185,"context_line":"``migration_type: \"retype\"``, which routes to ``cinder_helper.retype()`` with"},{"line_number":186,"context_line":"``migration_policy\u003d\"on-demand\"``."},{"line_number":187,"context_line":""},{"line_number":188,"context_line":"**Standalone volumes**, gated by the entry\u0027s ``resource_types`` containing"},{"line_number":189,"context_line":"``\"volume\"``: a volume is a target when it has no attachments and its"}],"source_content_type":"text/x-rst","patch_set":1,"id":"35784bc0_14ce2380","line":186,"range":{"start_line":184,"start_character":0,"end_line":186,"end_character":33},"in_reply_to":"3ad5de15_39829d17","updated":"2026-10-02 17:57:50.000000000","message":"So for now we will stop correlate Compute AZs with storage AZs. It seems more viable to keep pools and types as options for migrating them from different compute zones, when needed.","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"137046ab661eb7609883e3f39736a4df042749c8","unresolved":true,"context_lines":[{"line_number":181,"context_line":"Volume flow"},{"line_number":182,"context_line":"-----------"},{"line_number":183,"context_line":""},{"line_number":184,"context_line":"Both paths below emit the existing ``volume_migrate`` action with"},{"line_number":185,"context_line":"``migration_type: \"retype\"``, which routes to ``cinder_helper.retype()`` with"},{"line_number":186,"context_line":"``migration_policy\u003d\"on-demand\"``."},{"line_number":187,"context_line":""},{"line_number":188,"context_line":"**Standalone volumes**, gated by the entry\u0027s ``resource_types`` containing"},{"line_number":189,"context_line":"``\"volume\"``: a volume is a target when it has no attachments and its"}],"source_content_type":"text/x-rst","patch_set":1,"id":"119d5346_db56edb8","line":186,"range":{"start_line":184,"start_character":0,"end_line":186,"end_character":33},"in_reply_to":"3d7ed605_130bc01a","updated":"2026-09-29 17:11:58.000000000","message":"The volume flow in this spec is covering only the AZs move, from an AZ-a to an AZ-b, which for volumes will always be a retype (unless they are already in the destination AZ - but that would not match the src_type:dest_type mapping and will be ignored?)","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":16312,"name":"Alfredo Moralejo","email":"amoralej@redhat.com","username":"amoralej"},"change_message_id":"795634ee4a80674f3a0972d3bfabcd255551c394","unresolved":true,"context_lines":[{"line_number":181,"context_line":"Volume flow"},{"line_number":182,"context_line":"-----------"},{"line_number":183,"context_line":""},{"line_number":184,"context_line":"Both paths below emit the existing ``volume_migrate`` action with"},{"line_number":185,"context_line":"``migration_type: \"retype\"``, which routes to ``cinder_helper.retype()`` with"},{"line_number":186,"context_line":"``migration_policy\u003d\"on-demand\"``."},{"line_number":187,"context_line":""},{"line_number":188,"context_line":"**Standalone volumes**, gated by the entry\u0027s ``resource_types`` containing"},{"line_number":189,"context_line":"``\"volume\"``: a volume is a target when it has no attachments and its"}],"source_content_type":"text/x-rst","patch_set":1,"id":"eb2ed4d6_606e301c","line":186,"range":{"start_line":184,"start_character":0,"end_line":186,"end_character":33},"in_reply_to":"db856548_a09fbc42","updated":"2026-09-30 09:56:24.000000000","message":"Correcting myself:\n\nThe need of a retype is a convention (and maybe good practice, that\u0027d be question for cinder sme) but afaik, cinder supports this topology:\n\n- AZ-1: has a pool `pool-az-1` which has volume_backend_name `multiaz`\n- AZ-2: has a pool `pool-az-2` which has volume_backend_name `multiaz`\n- volume type `multiaz` with volume_backend_name `multiaz`\n\nIn that case user would create the volumes with parameters `volume_type\u003dmultiaz` and `availability_zone\u003d[AZ1|AZ2]` so that volumes would be created in the right AZ. In that case, moving data from AZ1 to AZ2 could be done currently with zone_migration config `{\"storage_pools\": [{\"src_pool\": \"pool-az-1\", \"src_type\": \"multiaz\", \"dst_pool\": \"pool-az-2\"}]}`.\nWhile this is not the case described by the user, this is a case currently supported in zone_migration and can be useful for some cases.","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"039df4a026370beb929eb7b52d0e576208c2c1d8","unresolved":true,"context_lines":[{"line_number":181,"context_line":"Volume flow"},{"line_number":182,"context_line":"-----------"},{"line_number":183,"context_line":""},{"line_number":184,"context_line":"Both paths below emit the existing ``volume_migrate`` action with"},{"line_number":185,"context_line":"``migration_type: \"retype\"``, which routes to ``cinder_helper.retype()`` with"},{"line_number":186,"context_line":"``migration_policy\u003d\"on-demand\"``."},{"line_number":187,"context_line":""},{"line_number":188,"context_line":"**Standalone volumes**, gated by the entry\u0027s ``resource_types`` containing"},{"line_number":189,"context_line":"``\"volume\"``: a volume is a target when it has no attachments and its"}],"source_content_type":"text/x-rst","patch_set":1,"id":"3ad5de15_39829d17","line":186,"range":{"start_line":184,"start_character":0,"end_line":186,"end_character":33},"in_reply_to":"eb2ed4d6_606e301c","updated":"2026-09-30 12:19:11.000000000","message":"I think that you are correct, the current evaluated scenario is that cross-AZ would always trigger a rytype, but in case that the same volume-type is used in multiple AZs it may require just the move.\nFor this scenarios would be good to rely in the src_pool/dest_pool.","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":34452,"name":"Joan Gilabert","display_name":"jgilaber","email":"jgilaber@redhat.com","username":"jgilaber"},"change_message_id":"4f879a777d2dd912827f1b41b2e5c8e9b216139b","unresolved":true,"context_lines":[{"line_number":185,"context_line":"``migration_type: \"retype\"``, which routes to ``cinder_helper.retype()`` with"},{"line_number":186,"context_line":"``migration_policy\u003d\"on-demand\"``."},{"line_number":187,"context_line":""},{"line_number":188,"context_line":"**Standalone volumes**, gated by the entry\u0027s ``resource_types`` containing"},{"line_number":189,"context_line":"``\"volume\"``: a volume is a target when it has no attachments and its"},{"line_number":190,"context_line":"``volume_type`` equals some ``src_type`` in that entry\u0027s ``volume_types``."},{"line_number":191,"context_line":"Emit a retype to the mapped ``dst_type``. Restricting this pass to"}],"source_content_type":"text/x-rst","patch_set":1,"id":"bcad3e70_5b99619e","line":188,"updated":"2026-10-01 15:15:38.000000000","message":"I don\u0027t have any experience working with AZs, just want to make sure my understanding is correct. This assumes that Cinder\u0027s and Nova\u0027s AZ names are equal and match `src_az` right? I\u0027m not sure that is guaranteed, if not we should document well this assumption","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"282700bdb3b7a5286ece1974a914a8b42f5523fd","unresolved":true,"context_lines":[{"line_number":185,"context_line":"``migration_type: \"retype\"``, which routes to ``cinder_helper.retype()`` with"},{"line_number":186,"context_line":"``migration_policy\u003d\"on-demand\"``."},{"line_number":187,"context_line":""},{"line_number":188,"context_line":"**Standalone volumes**, gated by the entry\u0027s ``resource_types`` containing"},{"line_number":189,"context_line":"``\"volume\"``: a volume is a target when it has no attachments and its"},{"line_number":190,"context_line":"``volume_type`` equals some ``src_type`` in that entry\u0027s ``volume_types``."},{"line_number":191,"context_line":"Emit a retype to the mapped ``dst_type``. Restricting this pass to"}],"source_content_type":"text/x-rst","patch_set":1,"id":"6d8d198e_3fc4fef1","line":188,"in_reply_to":"bcad3e70_5b99619e","updated":"2026-10-01 17:50:39.000000000","message":"Not really, it would still rely on parameters provided by user: src_pool, src_type and migrate them, without matching any Cinder AZ I think.","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":16312,"name":"Alfredo Moralejo","email":"amoralej@redhat.com","username":"amoralej"},"change_message_id":"086f6c27b0f6c775700f27587c73e7d9bcdbf3ee","unresolved":true,"context_lines":[{"line_number":194,"context_line":"that is not moving — either because it lives outside the drained zone or"},{"line_number":195,"context_line":"because it was skipped by the rule below."},{"line_number":196,"context_line":""},{"line_number":197,"context_line":"**Volumes attached to a migrating instance**: for each instance selected"},{"line_number":198,"context_line":"for an AZ-targeted move, find its attached volumes and retype each to the"},{"line_number":199,"context_line":"``dst_type`` mapped by the same AZ entry that selected the instance."},{"line_number":200,"context_line":""},{"line_number":201,"context_line":"The cluster data model has no instance-to-volume edge. The only link is"},{"line_number":202,"context_line":"``Volume.attachments[].server_id``, and the collector prunes each attachment"}],"source_content_type":"text/x-rst","patch_set":1,"id":"39376410_39ca820a","line":199,"range":{"start_line":197,"start_character":0,"end_line":199,"end_character":68},"updated":"2026-09-29 15:52:23.000000000","message":"As mentioned before, i don\u0027t think there is a reason to *always* force volume retypes for attached instances. That should be up to the cluster admin.","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"adeb8dbebe14aa2cd3f2d44e1ad37d5491561eeb","unresolved":true,"context_lines":[{"line_number":194,"context_line":"that is not moving — either because it lives outside the drained zone or"},{"line_number":195,"context_line":"because it was skipped by the rule below."},{"line_number":196,"context_line":""},{"line_number":197,"context_line":"**Volumes attached to a migrating instance**: for each instance selected"},{"line_number":198,"context_line":"for an AZ-targeted move, find its attached volumes and retype each to the"},{"line_number":199,"context_line":"``dst_type`` mapped by the same AZ entry that selected the instance."},{"line_number":200,"context_line":""},{"line_number":201,"context_line":"The cluster data model has no instance-to-volume edge. The only link is"},{"line_number":202,"context_line":"``Volume.attachments[].server_id``, and the collector prunes each attachment"}],"source_content_type":"text/x-rst","patch_set":1,"id":"2e6e64f0_cd78fd23","line":199,"range":{"start_line":197,"start_character":0,"end_line":199,"end_character":68},"in_reply_to":"1ce16fc9_1e9dc92a","updated":"2026-10-02 17:57:50.000000000","message":"That was the initial assumption based on the use case provided, where volumes types would be mapped to a single AZ, an the retype would: update their AZ and move to another compatible backend. I am removing this part and we would keep the operator\u0027s driven migration between pools and retype based on input parameters.","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":16312,"name":"Alfredo Moralejo","email":"amoralej@redhat.com","username":"amoralej"},"change_message_id":"598241d080a8dd767860c48abaf29230c51c7dbe","unresolved":true,"context_lines":[{"line_number":194,"context_line":"that is not moving — either because it lives outside the drained zone or"},{"line_number":195,"context_line":"because it was skipped by the rule below."},{"line_number":196,"context_line":""},{"line_number":197,"context_line":"**Volumes attached to a migrating instance**: for each instance selected"},{"line_number":198,"context_line":"for an AZ-targeted move, find its attached volumes and retype each to the"},{"line_number":199,"context_line":"``dst_type`` mapped by the same AZ entry that selected the instance."},{"line_number":200,"context_line":""},{"line_number":201,"context_line":"The cluster data model has no instance-to-volume edge. The only link is"},{"line_number":202,"context_line":"``Volume.attachments[].server_id``, and the collector prunes each attachment"}],"source_content_type":"text/x-rst","patch_set":1,"id":"1ce16fc9_1e9dc92a","line":199,"range":{"start_line":197,"start_character":0,"end_line":199,"end_character":68},"in_reply_to":"1d4ee2d1_a0cba4e2","updated":"2026-09-30 09:41:51.000000000","message":"see my previous comment for potential non-retype cases (that we support today).","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"137046ab661eb7609883e3f39736a4df042749c8","unresolved":true,"context_lines":[{"line_number":194,"context_line":"that is not moving — either because it lives outside the drained zone or"},{"line_number":195,"context_line":"because it was skipped by the rule below."},{"line_number":196,"context_line":""},{"line_number":197,"context_line":"**Volumes attached to a migrating instance**: for each instance selected"},{"line_number":198,"context_line":"for an AZ-targeted move, find its attached volumes and retype each to the"},{"line_number":199,"context_line":"``dst_type`` mapped by the same AZ entry that selected the instance."},{"line_number":200,"context_line":""},{"line_number":201,"context_line":"The cluster data model has no instance-to-volume edge. The only link is"},{"line_number":202,"context_line":"``Volume.attachments[].server_id``, and the collector prunes each attachment"}],"source_content_type":"text/x-rst","patch_set":1,"id":"1d4ee2d1_a0cba4e2","line":199,"range":{"start_line":197,"start_character":0,"end_line":199,"end_character":68},"in_reply_to":"39376410_39ca820a","updated":"2026-09-29 17:11:58.000000000","message":"If the volume is going to be moved together with the instance, it must be a retype. I think htat you are mentioning the case that volumes stay in their original backend/pool/zone, but this is not covered here.","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":34452,"name":"Joan Gilabert","display_name":"jgilaber","email":"jgilaber@redhat.com","username":"jgilaber"},"change_message_id":"4f879a777d2dd912827f1b41b2e5c8e9b216139b","unresolved":true,"context_lines":[{"line_number":217,"context_line":"Disabling source nodes"},{"line_number":218,"context_line":"----------------------"},{"line_number":219,"context_line":""},{"line_number":220,"context_line":"When ``disable_source_nodes`` is true, emit one"},{"line_number":221,"context_line":"``change_nova_service_state`` action per source node, ordered before the"},{"line_number":222,"context_line":"migrations, with the same parameters ``host_maintenance`` already uses::"},{"line_number":223,"context_line":""}],"source_content_type":"text/x-rst","patch_set":1,"id":"da6e4826_bd30f972","line":220,"updated":"2026-10-01 15:15:38.000000000","message":"I think we might need a bit more detail here. My understanding of the current version is that all the nodes which have at least one instance being migrated will be migrated, correct?\n\nThat seems right to me for the no AZ use case, but when draining an AZ, should we disable all the nodes belonging to it? For example, when draining an AZ with 3 nodes that only has instances in nodes 1 and 2, should we also disable node 3?","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":16312,"name":"Alfredo Moralejo","email":"amoralej@redhat.com","username":"amoralej"},"change_message_id":"a16771b88453a05fd0f1403b7f3795dc25ad1536","unresolved":true,"context_lines":[{"line_number":217,"context_line":"Disabling source nodes"},{"line_number":218,"context_line":"----------------------"},{"line_number":219,"context_line":""},{"line_number":220,"context_line":"When ``disable_source_nodes`` is true, emit one"},{"line_number":221,"context_line":"``change_nova_service_state`` action per source node, ordered before the"},{"line_number":222,"context_line":"migrations, with the same parameters ``host_maintenance`` already uses::"},{"line_number":223,"context_line":""}],"source_content_type":"text/x-rst","patch_set":1,"id":"2f791506_ad443ff0","line":220,"in_reply_to":"29714c77_d56d7d7f","updated":"2026-10-02 09:39:15.000000000","message":"There is a detail to be considered wrt disabling nodes. The zone_migration strategy has parameters to set the max number of actions executed in an audit execution. That means, that not all the hosts may be drained in an audit execution. i.e. we have a cluster with 10 nodes and 200 vms, but only 20 vms are migrated from 4 hosts. Which hosts should be disabled in that run? all of them (10) or only the ones where the 20 vms were running (4)?. I\u0027m not sure tbh, but i think it\u0027s fair to consider.","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"adeb8dbebe14aa2cd3f2d44e1ad37d5491561eeb","unresolved":true,"context_lines":[{"line_number":217,"context_line":"Disabling source nodes"},{"line_number":218,"context_line":"----------------------"},{"line_number":219,"context_line":""},{"line_number":220,"context_line":"When ``disable_source_nodes`` is true, emit one"},{"line_number":221,"context_line":"``change_nova_service_state`` action per source node, ordered before the"},{"line_number":222,"context_line":"migrations, with the same parameters ``host_maintenance`` already uses::"},{"line_number":223,"context_line":""}],"source_content_type":"text/x-rst","patch_set":1,"id":"cf59c2e7_f0c06a6e","line":220,"in_reply_to":"2f791506_ad443ff0","updated":"2026-10-02 17:57:50.000000000","message":"The idea behind the source disabling nodes is that no new instances would be scheduled to these nodes, since they are being drained. So in theory this would be the step 0 for any az-drain, in all nodes, no? I would still keep disabling all source nodes that belong to the src_az. Operators can still do: filter nodes using audit scope (if they plan to drain a set of nodes first) or skip disabling a node in the resulted action plan. By having alternatives to not disable the node makes me think that is better to consider all. The opposite is not possible, unless the operator uses another strategy just to disable the, then, skipped nodes.","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"282700bdb3b7a5286ece1974a914a8b42f5523fd","unresolved":true,"context_lines":[{"line_number":217,"context_line":"Disabling source nodes"},{"line_number":218,"context_line":"----------------------"},{"line_number":219,"context_line":""},{"line_number":220,"context_line":"When ``disable_source_nodes`` is true, emit one"},{"line_number":221,"context_line":"``change_nova_service_state`` action per source node, ordered before the"},{"line_number":222,"context_line":"migrations, with the same parameters ``host_maintenance`` already uses::"},{"line_number":223,"context_line":""}],"source_content_type":"text/x-rst","patch_set":1,"id":"29714c77_d56d7d7f","line":220,"in_reply_to":"da6e4826_bd30f972","updated":"2026-10-01 17:50:39.000000000","message":"I do think so, if the idea is to drain the AZ, all nodes should be disabled there, including the empty ones, so no more instances are scheduled in any. Note that we also have some tools that help us here: audit scope (to exclude nodes) and Skip Actions, which gives operators more flexibility.","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":16312,"name":"Alfredo Moralejo","email":"amoralej@redhat.com","username":"amoralej"},"change_message_id":"086f6c27b0f6c775700f27587c73e7d9bcdbf3ee","unresolved":true,"context_lines":[{"line_number":243,"context_line":"into a different zone, and Nova rejects it. The pin must therefore be cleared"},{"line_number":244,"context_line":"before the migrate and set after it, using Nova\u0027s unpin-az API."},{"line_number":245,"context_line":""},{"line_number":246,"context_line":"Since the weight planner layers strictly by action *type*, a single type"},{"line_number":247,"context_line":"cannot sit both before and after ``migrate``. This needs two action types:"},{"line_number":248,"context_line":""},{"line_number":249,"context_line":"``unpin_instance_az``"}],"source_content_type":"text/x-rst","patch_set":1,"id":"72bc91e8_21f47f96","line":246,"range":{"start_line":246,"start_character":0,"end_line":246,"end_character":2},"updated":"2026-09-29 15:52:23.000000000","message":"ftr, i was planning to add the option to set the order based in action parameter in addition to type in https://review.opendev.org/c/openstack/watcher-specs/+/994607 but there is not point in depending on it.","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"137046ab661eb7609883e3f39736a4df042749c8","unresolved":true,"context_lines":[{"line_number":243,"context_line":"into a different zone, and Nova rejects it. The pin must therefore be cleared"},{"line_number":244,"context_line":"before the migrate and set after it, using Nova\u0027s unpin-az API."},{"line_number":245,"context_line":""},{"line_number":246,"context_line":"Since the weight planner layers strictly by action *type*, a single type"},{"line_number":247,"context_line":"cannot sit both before and after ``migrate``. This needs two action types:"},{"line_number":248,"context_line":""},{"line_number":249,"context_line":"``unpin_instance_az``"}],"source_content_type":"text/x-rst","patch_set":1,"id":"b35d90e6_78cc91e2","line":246,"range":{"start_line":246,"start_character":0,"end_line":246,"end_character":2},"in_reply_to":"72bc91e8_21f47f96","updated":"2026-09-29 17:11:58.000000000","message":"Yeah, the planner piece still needs more brainstorm and we shold sync about that. This is a simple extension of the existing behavior.","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"adeb8dbebe14aa2cd3f2d44e1ad37d5491561eeb","unresolved":true,"context_lines":[{"line_number":243,"context_line":"into a different zone, and Nova rejects it. The pin must therefore be cleared"},{"line_number":244,"context_line":"before the migrate and set after it, using Nova\u0027s unpin-az API."},{"line_number":245,"context_line":""},{"line_number":246,"context_line":"Since the weight planner layers strictly by action *type*, a single type"},{"line_number":247,"context_line":"cannot sit both before and after ``migrate``. This needs two action types:"},{"line_number":248,"context_line":""},{"line_number":249,"context_line":"``unpin_instance_az``"}],"source_content_type":"text/x-rst","patch_set":1,"id":"4d7212e5_c36a2cc2","line":246,"range":{"start_line":246,"start_character":0,"end_line":246,"end_character":2},"in_reply_to":"b35d90e6_78cc91e2","updated":"2026-10-02 17:57:50.000000000","message":"Note that by adding pin and unpin to the existing Migrate action would not touch anything on planner side. This will be the next approach proposed here.","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":16312,"name":"Alfredo Moralejo","email":"amoralej@redhat.com","username":"amoralej"},"change_message_id":"086f6c27b0f6c775700f27587c73e7d9bcdbf3ee","unresolved":true,"context_lines":[{"line_number":246,"context_line":"Since the weight planner layers strictly by action *type*, a single type"},{"line_number":247,"context_line":"cannot sit both before and after ``migrate``. This needs two action types:"},{"line_number":248,"context_line":""},{"line_number":249,"context_line":"``unpin_instance_az``"},{"line_number":250,"context_line":"  Parameters ``{resource_id, resource_name}``; clears the pin."},{"line_number":251,"context_line":""},{"line_number":252,"context_line":"``pin_instance_az``"},{"line_number":253,"context_line":"  Parameters ``{resource_id, resource_name, availability_zone}``; sets the"},{"line_number":254,"context_line":"  pin to the destination zone."},{"line_number":255,"context_line":""},{"line_number":256,"context_line":"Both live in one new module sharing a base class. ``revert()`` is"},{"line_number":257,"context_line":"unsupported; ``pre_condition`` skips when the pin already holds the target"}],"source_content_type":"text/x-rst","patch_set":1,"id":"2fe18cdb_f463b669","line":254,"range":{"start_line":249,"start_character":0,"end_line":254,"end_character":30},"updated":"2026-09-29 15:52:23.000000000","message":"May we include this as part of the migrate actions when `destination_az` is passed instead of adding new action types? I think migrations are the only use case for unpin/pìn.","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"137046ab661eb7609883e3f39736a4df042749c8","unresolved":true,"context_lines":[{"line_number":246,"context_line":"Since the weight planner layers strictly by action *type*, a single type"},{"line_number":247,"context_line":"cannot sit both before and after ``migrate``. This needs two action types:"},{"line_number":248,"context_line":""},{"line_number":249,"context_line":"``unpin_instance_az``"},{"line_number":250,"context_line":"  Parameters ``{resource_id, resource_name}``; clears the pin."},{"line_number":251,"context_line":""},{"line_number":252,"context_line":"``pin_instance_az``"},{"line_number":253,"context_line":"  Parameters ``{resource_id, resource_name, availability_zone}``; sets the"},{"line_number":254,"context_line":"  pin to the destination zone."},{"line_number":255,"context_line":""},{"line_number":256,"context_line":"Both live in one new module sharing a base class. ``revert()`` is"},{"line_number":257,"context_line":"unsupported; ``pre_condition`` skips when the pin already holds the target"}],"source_content_type":"text/x-rst","patch_set":1,"id":"8d9e630f_d648ad15","line":254,"range":{"start_line":249,"start_character":0,"end_line":254,"end_character":30},"in_reply_to":"2fe18cdb_f463b669","updated":"2026-09-29 17:11:58.000000000","message":"I thought about that too! I was considering make this part of the Migrate Action too + do the rollback of the unpin in case the migration fails. In the current proposal, if the migration fails, the instance will remain unpinned.","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"adeb8dbebe14aa2cd3f2d44e1ad37d5491561eeb","unresolved":true,"context_lines":[{"line_number":246,"context_line":"Since the weight planner layers strictly by action *type*, a single type"},{"line_number":247,"context_line":"cannot sit both before and after ``migrate``. This needs two action types:"},{"line_number":248,"context_line":""},{"line_number":249,"context_line":"``unpin_instance_az``"},{"line_number":250,"context_line":"  Parameters ``{resource_id, resource_name}``; clears the pin."},{"line_number":251,"context_line":""},{"line_number":252,"context_line":"``pin_instance_az``"},{"line_number":253,"context_line":"  Parameters ``{resource_id, resource_name, availability_zone}``; sets the"},{"line_number":254,"context_line":"  pin to the destination zone."},{"line_number":255,"context_line":""},{"line_number":256,"context_line":"Both live in one new module sharing a base class. ``revert()`` is"},{"line_number":257,"context_line":"unsupported; ``pre_condition`` skips when the pin already holds the target"}],"source_content_type":"text/x-rst","patch_set":1,"id":"abffff14_85833e85","line":254,"range":{"start_line":249,"start_character":0,"end_line":254,"end_character":30},"in_reply_to":"7bef2366_1ae6078f","updated":"2026-10-02 17:57:50.000000000","message":"It adds more logic to a single action, and doesn\u0027t allow strategies to only use the pin/unpin (not a requirement for now). But I also think that it would increase the number of actions and make it harder for users to skip and correlated with a specific migration. There are pros and cons in either proposals. I would stick with all inside Migrate for now, not because we would rollback the pin, but because they should be executed together. If a planner order the actions to unpin all instances, then start migrating them and one fails, we will end up in a worst scenario: lots of unpinned instances, some instances migrated but not pinned again..\nThe rollback of a pin, after a migrations fails is also questionable, since the operator may want to force/fix the migration instead of get it pinned again, or we may even fail to unpin depending on the current state of the instance..","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":16312,"name":"Alfredo Moralejo","email":"amoralej@redhat.com","username":"amoralej"},"change_message_id":"598241d080a8dd767860c48abaf29230c51c7dbe","unresolved":true,"context_lines":[{"line_number":246,"context_line":"Since the weight planner layers strictly by action *type*, a single type"},{"line_number":247,"context_line":"cannot sit both before and after ``migrate``. This needs two action types:"},{"line_number":248,"context_line":""},{"line_number":249,"context_line":"``unpin_instance_az``"},{"line_number":250,"context_line":"  Parameters ``{resource_id, resource_name}``; clears the pin."},{"line_number":251,"context_line":""},{"line_number":252,"context_line":"``pin_instance_az``"},{"line_number":253,"context_line":"  Parameters ``{resource_id, resource_name, availability_zone}``; sets the"},{"line_number":254,"context_line":"  pin to the destination zone."},{"line_number":255,"context_line":""},{"line_number":256,"context_line":"Both live in one new module sharing a base class. ``revert()`` is"},{"line_number":257,"context_line":"unsupported; ``pre_condition`` skips when the pin already holds the target"}],"source_content_type":"text/x-rst","patch_set":1,"id":"7bef2366_1ae6078f","line":254,"range":{"start_line":249,"start_character":0,"end_line":254,"end_character":30},"in_reply_to":"8d9e630f_d648ad15","updated":"2026-09-30 09:41:51.000000000","message":"actually, that seems a valid reason to incorporate in the migrate action, right?","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":16312,"name":"Alfredo Moralejo","email":"amoralej@redhat.com","username":"amoralej"},"change_message_id":"086f6c27b0f6c775700f27587c73e7d9bcdbf3ee","unresolved":true,"context_lines":[{"line_number":394,"context_line":"placement constraing that could produce migrations that are likely to fail at"},{"line_number":395,"context_line":"execution time."},{"line_number":396,"context_line":""},{"line_number":397,"context_line":"**Keep ``availability_zones`` but reuse the existing parameters for the"},{"line_number":398,"context_line":"rest.** ``storage_pools`` would carry the ``src_type``/``dst_type`` mapping"},{"line_number":399,"context_line":"it already accepts, and ``compute_nodes`` would narrow the drain to an"},{"line_number":400,"context_line":"include or exclude list of nodes within the source zone, so no nested"},{"line_number":401,"context_line":"``volume_types`` or ``resource_types`` would be needed. Rejected on"},{"line_number":402,"context_line":"complexity: the allowed combinations across the three lists become the"},{"line_number":403,"context_line":"interface, with nothing tying a given type mapping to a given zone pair, and"},{"line_number":404,"context_line":"each combination is another precedence rule to implement and test."},{"line_number":405,"context_line":""},{"line_number":406,"context_line":"**Derive the volume type mapping from Cinder.** Watcher could inspect volume"},{"line_number":407,"context_line":"types and their backends to work out which type belongs to which zone. This"}],"source_content_type":"text/x-rst","patch_set":1,"id":"2ece7a09_640b373d","line":404,"range":{"start_line":397,"start_character":0,"end_line":404,"end_character":66},"updated":"2026-09-29 15:52:23.000000000","message":"I don\u0027t think this adds complexity *if* we untied instance and volume migrations (see my comments before), and acutally allows more cases that we currently support.","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"adeb8dbebe14aa2cd3f2d44e1ad37d5491561eeb","unresolved":false,"context_lines":[{"line_number":394,"context_line":"placement constraing that could produce migrations that are likely to fail at"},{"line_number":395,"context_line":"execution time."},{"line_number":396,"context_line":""},{"line_number":397,"context_line":"**Keep ``availability_zones`` but reuse the existing parameters for the"},{"line_number":398,"context_line":"rest.** ``storage_pools`` would carry the ``src_type``/``dst_type`` mapping"},{"line_number":399,"context_line":"it already accepts, and ``compute_nodes`` would narrow the drain to an"},{"line_number":400,"context_line":"include or exclude list of nodes within the source zone, so no nested"},{"line_number":401,"context_line":"``volume_types`` or ``resource_types`` would be needed. Rejected on"},{"line_number":402,"context_line":"complexity: the allowed combinations across the three lists become the"},{"line_number":403,"context_line":"interface, with nothing tying a given type mapping to a given zone pair, and"},{"line_number":404,"context_line":"each combination is another precedence rule to implement and test."},{"line_number":405,"context_line":""},{"line_number":406,"context_line":"**Derive the volume type mapping from Cinder.** Watcher could inspect volume"},{"line_number":407,"context_line":"types and their backends to work out which type belongs to which zone. This"}],"source_content_type":"text/x-rst","patch_set":1,"id":"ccf1c2bf_0951dd1d","line":404,"range":{"start_line":397,"start_character":0,"end_line":404,"end_character":66},"in_reply_to":"2211fe05_b6920ea7","updated":"2026-10-02 17:57:50.000000000","message":"this is now removed.","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"137046ab661eb7609883e3f39736a4df042749c8","unresolved":true,"context_lines":[{"line_number":394,"context_line":"placement constraing that could produce migrations that are likely to fail at"},{"line_number":395,"context_line":"execution time."},{"line_number":396,"context_line":""},{"line_number":397,"context_line":"**Keep ``availability_zones`` but reuse the existing parameters for the"},{"line_number":398,"context_line":"rest.** ``storage_pools`` would carry the ``src_type``/``dst_type`` mapping"},{"line_number":399,"context_line":"it already accepts, and ``compute_nodes`` would narrow the drain to an"},{"line_number":400,"context_line":"include or exclude list of nodes within the source zone, so no nested"},{"line_number":401,"context_line":"``volume_types`` or ``resource_types`` would be needed. Rejected on"},{"line_number":402,"context_line":"complexity: the allowed combinations across the three lists become the"},{"line_number":403,"context_line":"interface, with nothing tying a given type mapping to a given zone pair, and"},{"line_number":404,"context_line":"each combination is another precedence rule to implement and test."},{"line_number":405,"context_line":""},{"line_number":406,"context_line":"**Derive the volume type mapping from Cinder.** Watcher could inspect volume"},{"line_number":407,"context_line":"types and their backends to work out which type belongs to which zone. This"}],"source_content_type":"text/x-rst","patch_set":1,"id":"2211fe05_b6920ea7","line":404,"range":{"start_line":397,"start_character":0,"end_line":404,"end_character":66},"in_reply_to":"2ece7a09_640b373d","updated":"2026-09-29 17:11:58.000000000","message":"Yeah, I already answered that there.","commit_id":"f46153f34e924f5b2bc4ffc866d54d00b5e141b5"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"27e936244f2d2c0654b4e0384b24e19393cbfc9a","unresolved":true,"context_lines":[{"line_number":267,"context_line":""},{"line_number":268,"context_line":"``attached_only`` narrows an entry to volumes attached to an instance this"},{"line_number":269,"context_line":"audit is migrating. ``attached_only`` and the existing"},{"line_number":270,"context_line":"``with_attached_volume`` read the same information in opposite directions,"},{"line_number":271,"context_line":"and the documentation must contrast them directly:"},{"line_number":272,"context_line":""},{"line_number":273,"context_line":".. list-table:: Two attachment-driven options"},{"line_number":274,"context_line":"   :header-rows: 1"}],"source_content_type":"text/x-rst","patch_set":2,"id":"9dc413d3_77b28f62","line":271,"range":{"start_line":270,"start_character":0,"end_line":271,"end_character":50},"updated":"2026-10-02 19:10:15.000000000","message":"This is a candidate for deprecation, this existing option doesn\u0027t guarantee the action order that is going to be defined in the planner, so it is a noop operation today.","commit_id":"36285d83869bff8bbde88675ee1d698347d15869"}]}
