Skip to content

Commit 42df3ea

Browse files
Zuulopenstack-gerrit
authored andcommitted
Merge "Prepare _heal_allocations_for_instance for nested allocations"
2 parents 5352c68 + 307999c commit 42df3ea

File tree

5 files changed

+119
-120
lines changed

5 files changed

+119
-120
lines changed

nova/cmd/manage.py

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1674,10 +1674,16 @@ def _heal_missing_alloc(
16741674
{'instance': instance.uuid, 'node_uuid': node_uuid,
16751675
'resources': resources})
16761676
else:
1677-
if placement.put_allocations(
1678-
ctxt, node_uuid, instance.uuid, resources,
1679-
instance.project_id, instance.user_id,
1680-
consumer_generation=None):
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:
16811687
output(_('Successfully created allocations for '
16821688
'instance %(instance)s against resource '
16831689
'provider %(provider)s.') %
@@ -1688,21 +1694,16 @@ def _heal_missing_alloc(
16881694
instance=instance.uuid, provider=node_uuid)
16891695

16901696
def _heal_missing_project_and_user_id(
1691-
self, allocations, instance, dry_run, output, placement):
1697+
self, ctxt, allocations, instance, dry_run, output, placement):
16921698

16931699
allocations['project_id'] = instance.project_id
16941700
allocations['user_id'] = instance.user_id
1695-
# We use CONSUMER_GENERATION_VERSION for PUT
1696-
# /allocations/{consumer_id} to mirror the body structure from
1697-
# get_allocs_for_consumer.
16981701
if dry_run:
16991702
output(_('[dry-run] Update allocations for instance '
17001703
'%(instance)s: %(allocations)s') %
17011704
{'instance': instance.uuid, 'allocations': allocations})
17021705
else:
1703-
resp = placement.put(
1704-
'/allocations/%s' % instance.uuid,
1705-
allocations, version=report.CONSUMER_GENERATION_VERSION)
1706+
resp = placement.put_allocations(ctxt, instance.uuid, allocations)
17061707
if resp:
17071708
output(_('Successfully updated allocations for '
17081709
'instance %s.') % instance.uuid)
@@ -1772,7 +1773,7 @@ def _heal_allocations_for_instance(self, ctxt, instance, node_cache,
17721773
# because we don't want to mess up shared or nested
17731774
# provider allocations.
17741775
return self._heal_missing_project_and_user_id(
1775-
allocations, instance, dry_run, output, placement)
1776+
ctxt, allocations, instance, dry_run, output, placement)
17761777

17771778
output(_('Instance %s already has allocations with '
17781779
'matching consumer project/user.') % instance.uuid)

nova/scheduler/client/report.py

Lines changed: 6 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1930,42 +1930,24 @@ def move_allocations(self, context, source_consumer_uuid,
19301930
'text': r.text})
19311931
return r.status_code == 204
19321932

1933+
# TODO(gibi): kill safe_connect
19331934
@safe_connect
19341935
@retries
1935-
def put_allocations(self, context, rp_uuid, consumer_uuid, alloc_data,
1936-
project_id, user_id, consumer_generation):
1937-
"""Creates allocation records for the supplied instance UUID against
1938-
the supplied resource provider.
1939-
1940-
:note Currently we only allocate against a single resource provider.
1941-
Once shared storage and things like NUMA allocations are a
1942-
reality, this will change to allocate against multiple providers.
1936+
def put_allocations(self, context, consumer_uuid, payload):
1937+
"""Creates allocation records for the supplied consumer UUID based on
1938+
the provided allocation dict
19431939
19441940
:param context: The security context
1945-
:param rp_uuid: The UUID of the resource provider to allocate against.
19461941
:param consumer_uuid: The instance's UUID.
1947-
:param alloc_data: Dict, keyed by resource class, of amounts to
1948-
consume.
1949-
:param project_id: The project_id associated with the allocations.
1950-
:param user_id: The user_id associated with the allocations.
1951-
:param consumer_generation: The current generation of the consumer or
1952-
None if this the initial allocation of the
1953-
consumer
1942+
:param payload: Dict in the format expected by the placement
1943+
PUT /allocations/{consumer_uuid} API
19541944
:returns: True if the allocations were created, False otherwise.
19551945
:raises: Retry if the operation should be retried due to a concurrent
19561946
resource provider update.
19571947
:raises: AllocationUpdateFailed if placement returns a consumer
19581948
generation conflict
19591949
"""
19601950

1961-
payload = {
1962-
'allocations': {
1963-
rp_uuid: {'resources': alloc_data},
1964-
},
1965-
'project_id': project_id,
1966-
'user_id': user_id,
1967-
'consumer_generation': consumer_generation
1968-
}
19691951
r = self._put_allocations(context, consumer_uuid, payload)
19701952
if r.status_code != 204:
19711953
err = r.json()['errors'][0]

nova/tests/functional/test_report_client.py

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -243,10 +243,16 @@ def test_client_report_smoke(self):
243243
# Update allocations with our instance
244244
alloc_dict = utils.resources_from_flavor(self.instance,
245245
self.instance.flavor)
246+
payload = {
247+
"allocations": {
248+
self.compute_uuid: {"resources": alloc_dict}
249+
},
250+
"project_id": self.instance.project_id,
251+
"user_id": self.instance.user_id,
252+
"consumer_generation": None
253+
}
246254
self.client.put_allocations(
247-
self.context, self.compute_uuid, self.instance_uuid,
248-
alloc_dict, self.instance.project_id, self.instance.user_id,
249-
None)
255+
self.context, self.instance_uuid, payload)
250256

251257
# Check that allocations were made
252258
resp = self.client.get('/allocations/%s' % self.instance_uuid)
@@ -685,13 +691,18 @@ def test_set_inventory_for_provider(self):
685691
inv,
686692
self.client._get_inventory(
687693
self.context, uuids.cn)['inventories'])
688-
694+
payload = {
695+
"allocations": {
696+
uuids.cn: {"resources": {orc.SRIOV_NET_VF: 1}}
697+
},
698+
"project_id": uuids.proj,
699+
"user_id": uuids.user,
700+
"consumer_generation": None
701+
}
689702
# Now set up an InventoryInUse case by creating a VF allocation...
690703
self.assertTrue(
691704
self.client.put_allocations(
692-
self.context, uuids.cn, uuids.consumer,
693-
{orc.SRIOV_NET_VF: 1},
694-
uuids.proj, uuids.user, None))
705+
self.context, uuids.consumer, payload))
695706
# ...and trying to delete the provider's VF inventory
696707
bad_inv = {
697708
'CUSTOM_BANDWIDTH': {

nova/tests/unit/scheduler/client/test_report.py

Lines changed: 54 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -269,14 +269,19 @@ def test_put_allocations(self, mock_put):
269269
consumer_uuid = mock.sentinel.consumer
270270
data = {"MEMORY_MB": 1024}
271271
expected_url = "/allocations/%s" % consumer_uuid
272-
resp = self.client.put_allocations(self.context, rp_uuid,
273-
consumer_uuid, data,
274-
mock.sentinel.project_id,
275-
mock.sentinel.user_id,
276-
mock.sentinel.consumer_generation)
272+
payload = {
273+
"allocations": {
274+
rp_uuid: {"resources": data}
275+
},
276+
"project_id": mock.sentinel.project_id,
277+
"user_id": mock.sentinel.user_id,
278+
"consumer_generation": mock.sentinel.consumer_generation
279+
}
280+
resp = self.client.put_allocations(
281+
self.context, consumer_uuid, payload)
277282
self.assertTrue(resp)
278283
mock_put.assert_called_once_with(
279-
expected_url, mock.ANY, version='1.28',
284+
expected_url, payload, version='1.28',
280285
global_request_id=self.context.global_id)
281286

282287
@mock.patch.object(report.LOG, 'warning')
@@ -288,14 +293,20 @@ def test_put_allocations_fail(self, mock_put, mock_warn):
288293
consumer_uuid = mock.sentinel.consumer
289294
data = {"MEMORY_MB": 1024}
290295
expected_url = "/allocations/%s" % consumer_uuid
291-
resp = self.client.put_allocations(self.context, rp_uuid,
292-
consumer_uuid, data,
293-
mock.sentinel.project_id,
294-
mock.sentinel.user_id,
295-
mock.sentinel.consumer_generation)
296+
payload = {
297+
"allocations": {
298+
rp_uuid: {"resources": data}
299+
},
300+
"project_id": mock.sentinel.project_id,
301+
"user_id": mock.sentinel.user_id,
302+
"consumer_generation": mock.sentinel.consumer_generation
303+
}
304+
resp = self.client.put_allocations(
305+
self.context, consumer_uuid, payload)
306+
296307
self.assertFalse(resp)
297308
mock_put.assert_called_once_with(
298-
expected_url, mock.ANY, version='1.28',
309+
expected_url, payload, version='1.28',
299310
global_request_id=self.context.global_id)
300311
log_msg = mock_warn.call_args[0][0]
301312
self.assertIn("Failed to save allocation for", log_msg)
@@ -313,13 +324,17 @@ def test_put_allocations_fail_due_to_consumer_generation_conflict(
313324
consumer_uuid = mock.sentinel.consumer
314325
data = {"MEMORY_MB": 1024}
315326
expected_url = "/allocations/%s" % consumer_uuid
327+
payload = {
328+
"allocations": {
329+
rp_uuid: {"resources": data}
330+
},
331+
"project_id": mock.sentinel.project_id,
332+
"user_id": mock.sentinel.user_id,
333+
"consumer_generation": mock.sentinel.consumer_generation
334+
}
316335
self.assertRaises(exception.AllocationUpdateFailed,
317336
self.client.put_allocations,
318-
self.context, rp_uuid,
319-
consumer_uuid, data,
320-
mock.sentinel.project_id,
321-
mock.sentinel.user_id,
322-
mock.sentinel.consumer_generation)
337+
self.context, consumer_uuid, payload)
323338

324339
mock_put.assert_called_once_with(
325340
expected_url, mock.ANY, version='1.28',
@@ -343,14 +358,19 @@ def test_put_allocations_retries_conflict(self, mock_put):
343358
consumer_uuid = mock.sentinel.consumer
344359
data = {"MEMORY_MB": 1024}
345360
expected_url = "/allocations/%s" % consumer_uuid
346-
resp = self.client.put_allocations(self.context, rp_uuid,
347-
consumer_uuid, data,
348-
mock.sentinel.project_id,
349-
mock.sentinel.user_id,
350-
mock.sentinel.consumer_generation)
361+
payload = {
362+
"allocations": {
363+
rp_uuid: {"resources": data}
364+
},
365+
"project_id": mock.sentinel.project_id,
366+
"user_id": mock.sentinel.user_id,
367+
"consumer_generation": mock.sentinel.consumer_generation
368+
}
369+
resp = self.client.put_allocations(
370+
self.context, consumer_uuid, payload)
351371
self.assertTrue(resp)
352372
mock_put.assert_has_calls([
353-
mock.call(expected_url, mock.ANY, version='1.28',
373+
mock.call(expected_url, payload, version='1.28',
354374
global_request_id=self.context.global_id)] * 2)
355375

356376
@mock.patch('time.sleep', new=mock.Mock())
@@ -369,14 +389,19 @@ def test_put_allocations_retry_gives_up(self, mock_put):
369389
consumer_uuid = mock.sentinel.consumer
370390
data = {"MEMORY_MB": 1024}
371391
expected_url = "/allocations/%s" % consumer_uuid
372-
resp = self.client.put_allocations(self.context, rp_uuid,
373-
consumer_uuid, data,
374-
mock.sentinel.project_id,
375-
mock.sentinel.user_id,
376-
mock.sentinel.consumer_generation)
392+
payload = {
393+
"allocations": {
394+
rp_uuid: {"resources": data}
395+
},
396+
"project_id": mock.sentinel.project_id,
397+
"user_id": mock.sentinel.user_id,
398+
"consumer_generation": mock.sentinel.consumer_generation
399+
}
400+
resp = self.client.put_allocations(
401+
self.context, consumer_uuid, payload)
377402
self.assertFalse(resp)
378403
mock_put.assert_has_calls([
379-
mock.call(expected_url, mock.ANY, version='1.28',
404+
mock.call(expected_url, payload, version='1.28',
380405
global_request_id=self.context.global_id)] * 3)
381406

382407
def test_claim_resources_success(self):

0 commit comments

Comments
 (0)