Browse Source

pull out put_allocation call from _heal_*

Both allocation healing steps calls the placement API. This patch pulls
out the placement updating code to a single place. To do that it change
the healing steps to only generate / update the allocation individually
and then at the end of the healing there will be a single placement
update with this allocation.

This will help us to include the port related allocation into the instance
allocation by modifying a single place in the code.

Related-Bug: #1819923

Change-Id: I0e9f9a488141da599c10af8cabb4f6a5d111104f
tags/20.0.0.0rc1
Balazs Gibizer 5 months ago
parent
commit
e2866609bb
3 changed files with 51 additions and 57 deletions
  1. 43
    51
      nova/cmd/manage.py
  2. 7
    5
      nova/tests/functional/test_nova_manage.py
  3. 1
    1
      nova/tests/unit/test_nova_manage.py

+ 43
- 51
nova/cmd/manage.py View File

@@ -1658,9 +1658,7 @@ class PlacementCommands(object):
1658 1658
         node_cache[instance.node] = node_uuid
1659 1659
         return node_uuid
1660 1660
 
1661
-    def _heal_missing_alloc(
1662
-            self, ctxt, instance, node_cache, dry_run, output, placement):
1663
-
1661
+    def _heal_missing_alloc(self, ctxt, instance, node_cache):
1664 1662
         node_uuid = self._get_compute_node_uuid(
1665 1663
             ctxt, instance, node_cache)
1666 1664
 
@@ -1668,49 +1666,21 @@ class PlacementCommands(object):
1668 1666
         # on its embedded flavor.
1669 1667
         resources = scheduler_utils.resources_from_flavor(
1670 1668
             instance, instance.flavor)
1671
-        if dry_run:
1672
-            output(_('[dry-run] Create allocations for instance %(instance)s '
1673
-                     'on provider %(node_uuid)s: %(resources)s') %
1674
-                   {'instance': instance.uuid, 'node_uuid': node_uuid,
1675
-                    'resources': resources})
1676
-        else:
1677
-            payload = {
1678
-                'allocations': {
1679
-                    node_uuid: {'resources': resources},
1680
-                },
1681
-                'project_id': instance.project_id,
1682
-                'user_id': instance.user_id,
1683
-                'consumer_generation': None
1684
-            }
1685
-            resp = placement.put_allocations(ctxt, instance.uuid, payload)
1686
-            if resp:
1687
-                output(_('Successfully created allocations for '
1688
-                         'instance %(instance)s against resource '
1689
-                         'provider %(provider)s.') %
1690
-                       {'instance': instance.uuid, 'provider': node_uuid})
1691
-                return True
1692
-            else:
1693
-                raise exception.AllocationCreateFailed(
1694
-                    instance=instance.uuid, provider=node_uuid)
1695
-
1696
-    def _heal_missing_project_and_user_id(
1697
-            self, ctxt, allocations, instance, dry_run, output, placement):
1698 1669
 
1670
+        payload = {
1671
+            'allocations': {
1672
+                node_uuid: {'resources': resources},
1673
+            },
1674
+            'project_id': instance.project_id,
1675
+            'user_id': instance.user_id,
1676
+            'consumer_generation': None
1677
+        }
1678
+        return payload
1679
+
1680
+    def _heal_missing_project_and_user_id(self, allocations, instance):
1699 1681
         allocations['project_id'] = instance.project_id
1700 1682
         allocations['user_id'] = instance.user_id
1701
-        if dry_run:
1702
-            output(_('[dry-run] Update allocations for instance '
1703
-                     '%(instance)s: %(allocations)s') %
1704
-                   {'instance': instance.uuid, 'allocations': allocations})
1705
-        else:
1706
-            resp = placement.put_allocations(ctxt, instance.uuid, allocations)
1707
-            if resp:
1708
-                output(_('Successfully updated allocations for '
1709
-                         'instance %s.') % instance.uuid)
1710
-                return True
1711
-            else:
1712
-                raise exception.AllocationUpdateFailed(
1713
-                    consumer_uuid=instance.uuid, error=resp.text)
1683
+        return allocations
1714 1684
 
1715 1685
     def _heal_allocations_for_instance(self, ctxt, instance, node_cache,
1716 1686
                                        output, placement, dry_run):
@@ -1756,14 +1726,15 @@ class PlacementCommands(object):
1756 1726
             output(_("Allocation retrieval failed: %s") % e)
1757 1727
             allocations = None
1758 1728
 
1729
+        need_healing = False
1759 1730
         # get_allocations_for_consumer uses safe_connect which will
1760 1731
         # return None if we can't communicate with Placement, and the
1761 1732
         # response can have an empty {'allocations': {}} response if
1762 1733
         # there are no allocations for the instance so handle both
1763 1734
         if not allocations or not allocations.get('allocations'):
1764 1735
             # This instance doesn't have allocations
1765
-            return self._heal_missing_alloc(
1766
-                ctxt, instance, node_cache, dry_run, output, placement)
1736
+            need_healing = 'Create'
1737
+            allocations = self._heal_missing_alloc(ctxt, instance, node_cache)
1767 1738
 
1768 1739
         if (allocations.get('project_id') != instance.project_id or
1769 1740
                 allocations.get('user_id') != instance.user_id):
@@ -1772,12 +1743,33 @@ class PlacementCommands(object):
1772 1743
             # and re-put them. We don't use put_allocations here
1773 1744
             # because we don't want to mess up shared or nested
1774 1745
             # provider allocations.
1775
-            return self._heal_missing_project_and_user_id(
1776
-                ctxt, allocations, instance, dry_run, output, placement)
1777
-
1778
-        output(_('Instance %s already has allocations with '
1779
-                 'matching consumer project/user.') % instance.uuid)
1780
-        return
1746
+            need_healing = 'Update'
1747
+            allocations = self._heal_missing_project_and_user_id(
1748
+                allocations, instance)
1749
+
1750
+        if need_healing:
1751
+            if dry_run:
1752
+                output(_('[dry-run] %(operation)s allocations for instance '
1753
+                         '%(instance)s: %(allocations)s') %
1754
+                       {'operation': need_healing,
1755
+                        'instance': instance.uuid,
1756
+                        'allocations': allocations})
1757
+            else:
1758
+                resp = placement.put_allocations(ctxt, instance.uuid,
1759
+                                                 allocations)
1760
+                if resp:
1761
+                    output(_('Successfully %(operation)sd allocations for '
1762
+                             'instance %(instance)s.') %
1763
+                           {'operation': need_healing.lower(),
1764
+                            'instance': instance.uuid})
1765
+                    return True
1766
+                else:
1767
+                    raise exception.AllocationUpdateFailed(
1768
+                        consumer_uuid=instance.uuid, error='')
1769
+        else:
1770
+            output(_('Instance %s already has allocations with '
1771
+                     'matching consumer project/user.') % instance.uuid)
1772
+            return
1781 1773
 
1782 1774
     def _heal_instances_in_cell(self, ctxt, max_count, unlimited, output,
1783 1775
                                 placement, dry_run, instance_uuid):

+ 7
- 5
nova/tests/functional/test_nova_manage.py View File

@@ -652,13 +652,14 @@ class TestNovaManagePlacementHealAllocations(
652 652
         self.assertEqual(4, result, self.output.getvalue())
653 653
         output = self.output.getvalue()
654 654
         self.assertIn('Processed 0 instances.', output)
655
-        self.assertIn('[dry-run] Update allocations for instance %s' %
656
-                      server['id'], output)
655
+        self.assertIn('[dry-run] Update allocations for instance %s'
656
+                      % server['id'], output)
657 657
         # Now run heal_allocations which should update the consumer info.
658 658
         result = self.cli.heal_allocations(verbose=True)
659 659
         self.assertEqual(0, result, self.output.getvalue())
660 660
         output = self.output.getvalue()
661
-        self.assertIn('Successfully updated allocations for instance', output)
661
+        self.assertIn(
662
+            'Successfully updated allocations for', output)
662 663
         self.assertIn('Processed 1 instances.', output)
663 664
         # Now assert that the consumer was actually updated.
664 665
         allocations = self.placement_api.get(
@@ -676,8 +677,9 @@ class TestNovaManagePlacementHealAllocations(
676 677
         self.assertEqual(4, result, self.output.getvalue())
677 678
         output = self.output.getvalue()
678 679
         self.assertIn('Processed 0 instances.', output)
679
-        self.assertIn('[dry-run] Create allocations for instance %s on '
680
-                      'provider %s' % (server['id'], rp_uuid), output)
680
+        self.assertIn('[dry-run] Create allocations for instance '
681
+                      '%s' % server['id'], output)
682
+        self.assertIn(rp_uuid, output)
681 683
 
682 684
     def test_heal_allocations_specific_instance(self):
683 685
         """Tests the case that a specific instance is processed and only that

+ 1
- 1
nova/tests/unit/test_nova_manage.py View File

@@ -2478,7 +2478,7 @@ class TestNovaManagePlacement(test.NoDBTestCase):
2478 2478
             mock_get_compute_node, mock_get_allocs, mock_get_instances,
2479 2479
             mock_get_all_cells):
2480 2480
         self.assertEqual(3, self.cli.heal_allocations())
2481
-        self.assertIn('Failed to create allocations for instance',
2481
+        self.assertIn('Failed to update allocations for consumer',
2482 2482
                       self.output.getvalue())
2483 2483
         instance = mock_get_instances.return_value[0]
2484 2484
         mock_res_from_flavor.assert_called_once_with(

Loading…
Cancel
Save