Change update_host_allocations() for new affinity

The update_host_allocations() function, called for update instance
reservation, assumes that there are no duplicate host ids in the
given arguments and it removes *all* the allocations for the given
host id.

However, this is not the only case when affinity=True/None policy is
in play. This patch changes the function to be aware of how many
allocations should be removed.

Blueprint: no-affinity-instance-reservation
Change-Id: Ia0398543e0a8224b981ec7a515698d3e6d533248
This commit is contained in:
Tetsuro Nakamura 2018-12-24 10:19:49 +00:00 committed by Pierre Riteau
parent a21f88e28b
commit c9cb33d632
2 changed files with 26 additions and 13 deletions

View File

@ -432,10 +432,18 @@ class VirtualInstancePlugin(base.BasePlugin, nova.NovaClientWrapper):
allocations = db_api.host_allocation_get_all_by_values(
reservation_id=reservation_id)
removed_allocs = [a for a in allocations
if a['compute_host_id'] in removed]
for alloc in removed_allocs:
db_api.host_allocation_destroy(alloc['id'])
removed_allocs = []
for host_id in removed:
for allocation in allocations:
if allocation['compute_host_id'] == host_id:
removed_allocs.append(allocation['id'])
break
# TODO(tetsuro): It would be nice to have something like
# db_api.host_allocation_replace() to process the following
# deletion and addition in *one* DB transaction.
for alloc_id in removed_allocs:
db_api.host_allocation_destroy(alloc_id)
for added_host in added:
db_api.host_allocation_create({'compute_host_id': added_host,

View File

@ -1019,28 +1019,33 @@ class TestVirtualInstancePlugin(tests.TestCase):
mock_alloc_get.return_value = [
{'id': 'id10', 'compute_host_id': 'host-id10'},
{'id': 'id11', 'compute_host_id': 'host-id11'},
{'id': 'id12', 'compute_host_id': 'host-id12'}]
{'id': 'id12', 'compute_host_id': 'host-id11'},
{'id': 'id13', 'compute_host_id': 'host-id11'},
{'id': 'id14', 'compute_host_id': 'host-id12'}]
mock_alloc_destroy = self.patch(db_api, 'host_allocation_destroy')
mock_alloc_create = self.patch(db_api, 'host_allocation_create')
plugin = instance_plugin.VirtualInstancePlugin()
added_host = ['host-id1', 'host-id2']
removed_host = ['host-id10', 'host-id11']
added_host = ['host-id1', 'host-id1', 'host-id2']
removed_host = ['host-id10', 'host-id11', 'host-id11']
plugin.update_host_allocations(added_host, removed_host,
'reservation-id1')
removed_calls = [
mock.call('id10'), mock.call('id11')]
mock_alloc_destroy.assert_has_calls(removed_calls)
self.assertEqual(3, mock_alloc_destroy.call_count)
removed_calls = [mock.call('id10'), mock.call('id11')]
added_calls = [
mock.call({'compute_host_id': 'host-id1',
'reservation_id': 'reservation-id1'}),
mock.call({'compute_host_id': 'host-id2',
'reservation_id': 'reservation-id1'})]
plugin.update_host_allocations(added_host, removed_host,
'reservation-id1')
mock_alloc_destroy.assert_has_calls(removed_calls)
mock_alloc_create.assert_has_calls(added_calls)
self.assertEqual(3, mock_alloc_create.call_count)
def test_on_start(self):
def fake_host_get(host_id):