Browse Source

[stable-only] Delete allocations even if _confirm_resize raises (part 2)

The backport 37ac54a42e to fix
bug 1821594 did not account for how the _delete_allocation_after_move
method before Stein is tightly coupled to the migration status
being set to "confirmed" which is what the _confirm_resize method
does after self.driver.confirm_migration returns.

However, if self.driver.confirm_migration raises an exception
we still want to cleanup the allocations held on the source node
and for that we call _delete_allocation_after_move. But because
of that tight coupling before Stein, we need to temporarily
mutate the migration status to "confirmed" to get the cleanup
method to do what we want.

This isn't a problem starting in Stein because change
I0851e2d54a1fdc82fe3291fb7e286e790f121e92 removed that
tight coupling on the migration status, so this is a stable
branch only change.

Note that we don't call self.reportclient.delete_allocation_for_instance
directly since before Stein we still need to account for a
migration that does not move the source node allocations to the
migration record, and that logic is in _delete_allocation_after_move.

A simple unit test assertion is added here but the functional
test added in change I9d6478f492351b58aa87b8f56e907ee633d6d1c6
will assert the bug is fixed properly before Stein.

Change-Id: I933687891abef4878de09481937d576ce5899511
Closes-Bug: #1821594
tags/18.2.1
Matt Riedemann 4 months ago
parent
commit
dac3239e92
2 changed files with 18 additions and 4 deletions
  1. 10
    3
      nova/compute/manager.py
  2. 8
    1
      nova/tests/unit/compute/test_compute_mgr.py

+ 10
- 3
nova/compute/manager.py View File

@@ -3897,9 +3897,16 @@ class ComputeManager(manager.Manager):
3897 3897
                     # Whether an error occurred or not, at this point the
3898 3898
                     # instance is on the dest host so to avoid leaking
3899 3899
                     # allocations in placement, delete them here.
3900
-                    self._delete_allocation_after_move(
3901
-                        context, instance, migration, old_instance_type,
3902
-                        migration.source_node)
3900
+                    # NOTE(mriedem): _delete_allocation_after_move is tightly
3901
+                    # coupled to the migration status on the confirm step so
3902
+                    # we unfortunately have to mutate the migration status to
3903
+                    # have _delete_allocation_after_move cleanup the allocation
3904
+                    # held by the migration consumer.
3905
+                    with utils.temporary_mutation(
3906
+                            migration, status='confirmed'):
3907
+                        self._delete_allocation_after_move(
3908
+                            context, instance, migration, old_instance_type,
3909
+                            migration.source_node)
3903 3910
 
3904 3911
         do_confirm_resize(context, instance, migration.id)
3905 3912
 

+ 8
- 1
nova/tests/unit/compute/test_compute_mgr.py View File

@@ -7070,13 +7070,20 @@ class ComputeManagerMigrationTestCase(test.NoDBTestCase):
7070 7070
         migration_get_by_id.return_value = self.migration
7071 7071
         instance_get_by_uuid.return_value = self.instance
7072 7072
 
7073
+        def fake_delete_allocation_after_move(_context, instance, migration,
7074
+                                              flavor, nodename):
7075
+            # The migration.status must be 'confirmed' for the method to
7076
+            # properly cleanup the allocation held by the migration.
7077
+            self.assertEqual('confirmed', migration.status)
7078
+
7073 7079
         error = exception.HypervisorUnavailable(
7074 7080
             host=self.migration.source_compute)
7075 7081
         with test.nested(
7076 7082
             mock.patch.object(self.compute, 'network_api'),
7077 7083
             mock.patch.object(self.compute.driver, 'confirm_migration',
7078 7084
                               side_effect=error),
7079
-            mock.patch.object(self.compute, '_delete_allocation_after_move')
7085
+            mock.patch.object(self.compute, '_delete_allocation_after_move',
7086
+                              side_effect=fake_delete_allocation_after_move)
7080 7087
         ) as (
7081 7088
             network_api, confirm_migration, delete_allocation
7082 7089
         ):

Loading…
Cancel
Save