Skip to content

conductor: Cross-HV resize preflight checks#625

Open
grandchild wants to merge 2 commits into
cross-hv-reqspec-early-commitfrom
crosshv_resize_detection
Open

conductor: Cross-HV resize preflight checks#625
grandchild wants to merge 2 commits into
cross-hv-reqspec-early-commitfrom
crosshv_resize_detection

Conversation

@grandchild

@grandchild grandchild commented Jun 1, 2026

Copy link
Copy Markdown

We allow it only if it's:

  • a BFV instance, that
  • is powered on.
    And only from VMware to CH, not backwards.

The image properties are now sanitized and saved, only on vmware->ch hv transition, inside the new _prep_cross_hv_resize() step.

Sanitize VMware-specific image properties directly on the canonical
RequestSpec before scheduling, matching how request_spec.flavor is
already handled in the cold migrate flow.

The sanitizer mutates request_spec.image.properties in place and
returns a dict of original values. After task.execute() succeeds,
the conductor persists this into
MigrationContext.old_image_properties (via instance.save()) before
calling request_spec.save(). This ordering ensures the rollback
copy is always available if request_spec has been rewritten.

Changes:
- nova/compute/utils.py: add sanitize_image_props_for_kvm()
- nova/conductor/tasks/migrate.py: call sanitizer in _execute()
- nova/conductor/manager.py: persist old_image_properties to
  MigrationContext before request_spec.save()

Change-Id: I4f7035358a9a7f46d942bfad07d748d1d333f8c5
@grandchild grandchild changed the base branch from stable/2023.2-m3 to cross-hv-reqspec-early-commit June 1, 2026 15:35
@grandchild grandchild marked this pull request as ready for review June 1, 2026 15:35
@grandchild grandchild marked this pull request as draft June 1, 2026 15:36
@grandchild grandchild force-pushed the crosshv_resize_detection branch 2 times, most recently from 91eb9fa to 41d1d06 Compare June 2, 2026 08:44
Comment thread nova/tests/unit/conductor/tasks/test_migrate.py Outdated
Comment thread nova/conductor/tasks/migrate.py Outdated
Comment thread nova/conductor/tasks/migrate.py Outdated
Comment thread nova/conductor/tasks/migrate.py Outdated
self.context, self.instance.uuid)
volume_ids = {bdm.volume_id for bdm in bdms if bdm.volume_id}
if volume_ids:
snapshots = volume_api.get_all_snapshots(self.context)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This iterates through all the snapshots of a project as far as I can tell. Is there maybe a way to filter for the volume id below at the cinder API level already?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment thread nova/conductor/tasks/migrate.py Outdated
self.context, self.instance.uuid)
volume_ids = {bdm.volume_id for bdm in bdms if bdm.volume_id}
if volume_ids:
snapshots = volume_api.get_all_snapshots(self.context)

@anokfireball anokfireball Jun 2, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know it is still specified in the ticket to have this snapshot check. But since we are not doing volume retyping for BFV during the resize (anymore), it's probably not required (anymore).

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hm, right... I'll remove it altogether.

@grandchild grandchild force-pushed the crosshv_resize_detection branch 3 times, most recently from 251f927 to 4116348 Compare June 3, 2026 19:46
@grandchild

Copy link
Copy Markdown
Author

Added unit tests.
Removed volume snapshots check, which removed a few hunks altogether, since the volume_api doesn't need to be passed through anymore now.

@grandchild grandchild force-pushed the crosshv_resize_detection branch from 4116348 to 78d8199 Compare June 3, 2026 19:56
We allow it only if it's:
- a BFV instance, that
- is powered on.
And only from VMware to CH, not backwards.

The image properties are now sanitized and saved, only on vmware->ch
hv transition, inside the new _prep_cross_hv_resize() step.

Change-Id: I50dedca220e70f51811c0f9b9327ca3ae7ea9e12
@grandchild grandchild force-pushed the crosshv_resize_detection branch from 78d8199 to 72706db Compare June 4, 2026 12:52
@grandchild

Copy link
Copy Markdown
Author

Integrated on top of #623 .

@grandchild grandchild marked this pull request as ready for review June 5, 2026 14:08
and extra_specs_ops.match("CH", dest_hv):
if not self.request_spec.is_bfv:
raise exception.InvalidCrossHvResizePrecondition(
'Must be BFV instance')

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
'Must be BFV instance')
reason='Must be BFV instance')

'Must be BFV instance')
if self.instance.power_state != power_state.RUNNING:
raise exception.InvalidCrossHvResizePrecondition(
'Instance must be running for cross-hypervisor resize. '

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
'Instance must be running for cross-hypervisor resize. '
reason='Instance must be running for cross-hypervisor resize. '

Comment thread nova/exception.py
msg_fmt = _('Resize from hypervisor type %(src_hv_type)s to '
'%(dest_hv_type)s is not allowed')

class InvalidCrossHvResizePrecondition(NovaException):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
class InvalidCrossHvResizePrecondition(NovaException):
class InvalidCrossHvResizePrecondition(NovaException):

to make PEP8 happy I guess.

self.request_spec))
src_hv = self._source_cn.hypervisor_type
dest_hv = self.flavor.extra_specs.get('capabilities:hypervisor_type')
if dest_hv and not extra_specs_ops.match(src_hv, dest_hv):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no test where dest_hv is set but is identical to src_hv (so both are VMware or both CH). It think it would be nice to have a test that we don't break the existing same-HV resize flow: It should confirm that _prep_cross_hv_resize is not called when source and destination are same-HV.

Comment thread nova/conductor/manager.py
exception.InvalidCrossHvResizePrecondition) as ex:
vm_state = instance.vm_state
if not vm_state:
vm_state = vm_states.ACTIVE

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding a test for this branch would also be nice: Verify the instance state is properly restored (not set to ERROR) when the exception fires and resets to the ACTIVE fallback.

self._old_image_properties = (
compute_utils.sanitize_image_props_for_kvm(
self.request_spec))
src_hv = self._source_cn.hypervisor_type

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could src_hv somehow also be None? It's properly handled for dest_hv below, just feels like we could do the same for src_hv?

@anokfireball anokfireball force-pushed the cross-hv-reqspec-early-commit branch from a9d7726 to 6eb48d6 Compare June 10, 2026 08:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants