Merge "Consumer gen: remove_provider_from_instance_allocation"
This commit is contained in:
commit
b79a21a03d
|
@ -1854,7 +1854,8 @@ class SchedulerReportClient(object):
|
|||
url = '/allocations/%s' % consumer_uuid
|
||||
|
||||
# Grab the "doubled-up" allocation that we will manipulate
|
||||
r = self.get(url, global_request_id=context.global_id)
|
||||
r = self.get(url, global_request_id=context.global_id,
|
||||
version=CONSUMER_GENERATION_VERSION)
|
||||
if r.status_code != 200:
|
||||
LOG.warning("Failed to retrieve allocations for %s. Got HTTP %s",
|
||||
consumer_uuid, r.status_code)
|
||||
|
@ -1865,6 +1866,8 @@ class SchedulerReportClient(object):
|
|||
LOG.error("Expected to find current allocations for %s, but "
|
||||
"found none.", consumer_uuid)
|
||||
return False
|
||||
else:
|
||||
current_consumer_generation = r.json()['consumer_generation']
|
||||
|
||||
# If the host isn't in the current allocation for the instance, don't
|
||||
# do anything
|
||||
|
@ -1880,27 +1883,20 @@ class SchedulerReportClient(object):
|
|||
instance_uuid=consumer_uuid)
|
||||
LOG.debug('Instance %s has resources on %i compute nodes',
|
||||
consumer_uuid, len(compute_providers))
|
||||
|
||||
new_allocs = [
|
||||
{
|
||||
'resource_provider': {
|
||||
'uuid': alloc_rp_uuid,
|
||||
},
|
||||
new_allocs = {
|
||||
alloc_rp_uuid: {
|
||||
'resources': alloc['resources'],
|
||||
}
|
||||
for alloc_rp_uuid, alloc in current_allocs.items()
|
||||
if alloc_rp_uuid != rp_uuid
|
||||
]
|
||||
}
|
||||
|
||||
if len(compute_providers) == 1:
|
||||
# NOTE(danms): We are in a resize to same host scenario. Since we
|
||||
# are the only provider then we need to merge back in the doubled
|
||||
# allocation with our part subtracted
|
||||
peer_alloc = {
|
||||
'resource_provider': {
|
||||
'uuid': rp_uuid,
|
||||
},
|
||||
'resources': current_allocs[rp_uuid]['resources']
|
||||
'resources': current_allocs[rp_uuid]['resources'],
|
||||
}
|
||||
LOG.debug('Original resources from same-host '
|
||||
'allocation: %s', peer_alloc['resources'])
|
||||
|
@ -1908,15 +1904,16 @@ class SchedulerReportClient(object):
|
|||
resources, -1)
|
||||
LOG.debug('Subtracting old resources from same-host '
|
||||
'allocation: %s', peer_alloc['resources'])
|
||||
new_allocs.append(peer_alloc)
|
||||
new_allocs[rp_uuid] = peer_alloc
|
||||
|
||||
payload = {'allocations': new_allocs}
|
||||
payload['project_id'] = project_id
|
||||
payload['user_id'] = user_id
|
||||
payload['consumer_generation'] = current_consumer_generation
|
||||
LOG.debug("Sending updated allocation %s for instance %s after "
|
||||
"removing resources for %s.",
|
||||
new_allocs, consumer_uuid, rp_uuid)
|
||||
r = self.put(url, payload, version='1.10',
|
||||
r = self.put(url, payload, version=CONSUMER_GENERATION_VERSION,
|
||||
global_request_id=context.global_id)
|
||||
if r.status_code != 204:
|
||||
LOG.warning("Failed to save allocation for %s. Got HTTP %s: %s",
|
||||
|
|
|
@ -902,6 +902,9 @@ class TestPutAllocations(SchedulerReportClientTestCase):
|
|||
},
|
||||
},
|
||||
},
|
||||
'consumer_generation': 1,
|
||||
'project_id': uuids.project_id,
|
||||
'user_id': uuids.user_id,
|
||||
}
|
||||
self.ks_adap_mock.get.return_value = get_resp_mock
|
||||
resp_mock = mock.Mock(status_code=204)
|
||||
|
@ -916,31 +919,24 @@ class TestPutAllocations(SchedulerReportClientTestCase):
|
|||
expected_url = "/allocations/%s" % consumer_uuid
|
||||
# New allocations should only include the destination...
|
||||
expected_payload = {
|
||||
'allocations': [
|
||||
{
|
||||
'resource_provider': {
|
||||
'uuid': uuids.destination,
|
||||
},
|
||||
'allocations': {
|
||||
uuids.destination: {
|
||||
'resources': {
|
||||
'VCPU': 1,
|
||||
'MEMORY_MB': 1024,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
'consumer_generation': 1,
|
||||
'project_id': project_id,
|
||||
'user_id': user_id
|
||||
}
|
||||
expected_payload['project_id'] = project_id
|
||||
expected_payload['user_id'] = user_id
|
||||
# We have to pull the json body from the mock call_args to validate
|
||||
# it separately otherwise hash seed issues get in the way.
|
||||
actual_payload = self.ks_adap_mock.put.call_args[1]['json']
|
||||
sort_by_uuid = lambda x: x['resource_provider']['uuid']
|
||||
expected_allocations = sorted(expected_payload['allocations'],
|
||||
key=sort_by_uuid)
|
||||
actual_allocations = sorted(actual_payload['allocations'],
|
||||
key=sort_by_uuid)
|
||||
self.assertEqual(expected_allocations, actual_allocations)
|
||||
self.assertEqual(expected_payload, actual_payload)
|
||||
self.ks_adap_mock.put.assert_called_once_with(
|
||||
expected_url, microversion='1.10', json=mock.ANY,
|
||||
expected_url, microversion='1.28', json=mock.ANY,
|
||||
headers={'X-Openstack-Request-Id': self.context.global_id})
|
||||
|
||||
self.assertTrue(res)
|
||||
|
@ -976,6 +972,9 @@ class TestPutAllocations(SchedulerReportClientTestCase):
|
|||
},
|
||||
},
|
||||
},
|
||||
'consumer_generation': 1,
|
||||
'project_id': uuids.project_id,
|
||||
'user_id': uuids.user_id,
|
||||
}
|
||||
self.ks_adap_mock.get.return_value = get_resp_mock
|
||||
resp_mock = mock.Mock(status_code=204)
|
||||
|
@ -990,39 +989,29 @@ class TestPutAllocations(SchedulerReportClientTestCase):
|
|||
expected_url = "/allocations/%s" % consumer_uuid
|
||||
# New allocations should only include the destination...
|
||||
expected_payload = {
|
||||
'allocations': [
|
||||
{
|
||||
'resource_provider': {
|
||||
'uuid': uuids.shared_storage,
|
||||
},
|
||||
'allocations': {
|
||||
uuids.shared_storage: {
|
||||
'resources': {
|
||||
'DISK_GB': 100,
|
||||
},
|
||||
},
|
||||
{
|
||||
'resource_provider': {
|
||||
'uuid': uuids.destination,
|
||||
},
|
||||
uuids.destination: {
|
||||
'resources': {
|
||||
'VCPU': 1,
|
||||
'MEMORY_MB': 1024,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
'consumer_generation': 1,
|
||||
'project_id': project_id,
|
||||
'user_id': user_id
|
||||
}
|
||||
expected_payload['project_id'] = project_id
|
||||
expected_payload['user_id'] = user_id
|
||||
# We have to pull the json body from the mock call_args to validate
|
||||
# it separately otherwise hash seed issues get in the way.
|
||||
actual_payload = self.ks_adap_mock.put.call_args[1]['json']
|
||||
sort_by_uuid = lambda x: x['resource_provider']['uuid']
|
||||
expected_allocations = sorted(expected_payload['allocations'],
|
||||
key=sort_by_uuid)
|
||||
actual_allocations = sorted(actual_payload['allocations'],
|
||||
key=sort_by_uuid)
|
||||
self.assertEqual(expected_allocations, actual_allocations)
|
||||
self.assertEqual(expected_payload, actual_payload)
|
||||
self.ks_adap_mock.put.assert_called_once_with(
|
||||
expected_url, microversion='1.10', json=mock.ANY,
|
||||
expected_url, microversion='1.28', json=mock.ANY,
|
||||
headers={'X-Openstack-Request-Id': self.context.global_id})
|
||||
|
||||
self.assertTrue(res)
|
||||
|
@ -1051,6 +1040,9 @@ class TestPutAllocations(SchedulerReportClientTestCase):
|
|||
},
|
||||
},
|
||||
},
|
||||
'consumer_generation': 1,
|
||||
'project_id': uuids.project_id,
|
||||
'user_id': uuids.user_id,
|
||||
}
|
||||
self.ks_adap_mock.get.return_value = get_resp_mock
|
||||
consumer_uuid = uuids.consumer_uuid
|
||||
|
@ -1084,6 +1076,41 @@ class TestPutAllocations(SchedulerReportClientTestCase):
|
|||
|
||||
self.assertFalse(res)
|
||||
|
||||
def test_remove_provider_from_inst_alloc_consumer_gen_conflict(self):
|
||||
get_resp_mock = mock.Mock(status_code=200)
|
||||
get_resp_mock.json.return_value = {
|
||||
'allocations': {
|
||||
uuids.source: {
|
||||
'resource_provider_generation': 42,
|
||||
'resources': {
|
||||
'VCPU': 1,
|
||||
'MEMORY_MB': 1024,
|
||||
},
|
||||
},
|
||||
uuids.destination: {
|
||||
'resource_provider_generation': 42,
|
||||
'resources': {
|
||||
'VCPU': 1,
|
||||
'MEMORY_MB': 1024,
|
||||
},
|
||||
},
|
||||
},
|
||||
'consumer_generation': 1,
|
||||
'project_id': uuids.project_id,
|
||||
'user_id': uuids.user_id,
|
||||
}
|
||||
self.ks_adap_mock.get.return_value = get_resp_mock
|
||||
resp_mock = mock.Mock(status_code=409)
|
||||
self.ks_adap_mock.put.return_value = resp_mock
|
||||
consumer_uuid = uuids.consumer_uuid
|
||||
project_id = uuids.project_id
|
||||
user_id = uuids.user_id
|
||||
res = self.client.remove_provider_from_instance_allocation(
|
||||
self.context, consumer_uuid, uuids.source, user_id, project_id,
|
||||
mock.Mock())
|
||||
|
||||
self.assertFalse(res)
|
||||
|
||||
|
||||
class TestSetAndClearAllocations(SchedulerReportClientTestCase):
|
||||
|
||||
|
|
Loading…
Reference in New Issue