Add "--resource-class" to allocation unset
The ``openstack resource provider allocation unset`` command now supports ``--resource-class`` option, which accepts string of a resource class. This will remove allocations for the given resource class from all the providers. If ``--provider`` option is also specified, allocations to remove will be limited to the given resource class of the given resource provider. example1:: # remove VGPU allocation from provider P for this consumer. allocation unset <consumer_uuid> --provider P --resource-class VGPU example2:: # remove VGPU allocations from all providers for this consumer. allocation unset <consumer_uuid> --resource-class VGPU Change-Id: I91baf9de5205ec15023706a1646556850302d3d9 Story: #2006779 Task: #37304
This commit is contained in:
parent
05ca1ee2e1
commit
a4ac717a48
|
@ -155,8 +155,8 @@ class SetAllocation(command.Lister, version.CheckerMixin):
|
|||
class UnsetAllocation(command.Lister, version.CheckerMixin):
|
||||
"""Removes one or more sets of provider allocations for a consumer.
|
||||
|
||||
Note that omitting the ``--provider`` option is equivalent to removing
|
||||
all allocations for the given consumer.
|
||||
Note that omitting both the ``--provider`` and the ``--resource-class``
|
||||
option is equivalent to removing all allocations for the given consumer.
|
||||
|
||||
This command requires ``--os-placement-api-version 1.12`` or greater. Use
|
||||
``openstack resource provider allocation set`` for older versions.
|
||||
|
@ -168,7 +168,10 @@ class UnsetAllocation(command.Lister, version.CheckerMixin):
|
|||
parser.add_argument(
|
||||
'uuid',
|
||||
metavar='<consumer_uuid>',
|
||||
help='UUID of the consumer'
|
||||
help='UUID of the consumer. It is strongly recommended to use '
|
||||
'``--os-placement-api-version 1.28`` or greater when using '
|
||||
'this option to ensure the other allocation information is '
|
||||
'retained. '
|
||||
)
|
||||
parser.add_argument(
|
||||
'--provider',
|
||||
|
@ -180,22 +183,27 @@ class UnsetAllocation(command.Lister, version.CheckerMixin):
|
|||
'consumer has allocations on more than one provider, for '
|
||||
'example after evacuating a server to another compute node '
|
||||
'and you want to cleanup allocations on the source compute '
|
||||
'node resource provider in order to delete it. It is '
|
||||
'strongly recommended to use '
|
||||
'``--os-placement-api-version 1.28`` or greater when using '
|
||||
'this option to ensure the other allocation information is '
|
||||
'retained. Specify multiple times to remove allocations '
|
||||
'against multiple resource providers. Omit this option to '
|
||||
'remove all allocations for the consumer.'
|
||||
'node resource provider in order to delete it. Specify '
|
||||
'multiple times to remove allocations against multiple '
|
||||
'resource providers. Omit this option to remove all '
|
||||
'allocations for the consumer, or to remove all allocations'
|
||||
'of a specific resource class from all the resource provider '
|
||||
'with the ``--resource_class`` option. '
|
||||
)
|
||||
parser.add_argument(
|
||||
'--resource-class',
|
||||
metavar='resource_class',
|
||||
action='append',
|
||||
default=[],
|
||||
help='Name of a resource class from which to remove allocations '
|
||||
'for the given consumer. This is useful when the consumer '
|
||||
'has allocations on more than one resource class. '
|
||||
'By default, this will remove allocations for the given '
|
||||
'resource class from all the providers. If ``--provider`` '
|
||||
'option is also specified, allocations to remove will be '
|
||||
'limited to that resource class of the given resource '
|
||||
'provider.'
|
||||
)
|
||||
# TODO(mriedem): Add a --resource-class option which can be used with
|
||||
# or without --provider, e.g.:
|
||||
# 1. allocation unset --provider P --resource-class VGPU = remove
|
||||
# VGPU allocation from provider P for this consumer.
|
||||
# 2. allocation unset --resource-class VGPU = remove VGPU allocations
|
||||
# from all providers for this consumer.
|
||||
# Make sure to update the note about omitting --provider in the
|
||||
# command description above (due to example 2).
|
||||
return parser
|
||||
|
||||
# NOTE(mriedem): We require >= 1.12 because PUT requires project_id/user_id
|
||||
|
@ -210,19 +218,35 @@ class UnsetAllocation(command.Lister, version.CheckerMixin):
|
|||
|
||||
# Get the current allocations.
|
||||
payload = http.request('GET', url).json()
|
||||
allocations = payload['allocations']
|
||||
|
||||
if parsed_args.provider:
|
||||
allocations = payload['allocations']
|
||||
# Remove the given provider(s) from the allocations if it exists.
|
||||
# Do not error out if the consumer does not have allocations
|
||||
# against a provider in case we lost a race since the allocations
|
||||
# are in the state the user wants them in anyway.
|
||||
for rp_uuid in parsed_args.provider:
|
||||
allocations.pop(rp_uuid, None)
|
||||
if parsed_args.resource_class:
|
||||
# Remove the given resource class. Do not error out if the
|
||||
# consumer does not have allocations against that resource
|
||||
# class.
|
||||
rp_uuids = set(allocations)
|
||||
if parsed_args.provider:
|
||||
# If providers are also specified, we limit to remove
|
||||
# allocations only from those providers
|
||||
rp_uuids &= set(parsed_args.provider)
|
||||
for rp_uuid in rp_uuids:
|
||||
for rc in parsed_args.resource_class:
|
||||
allocations[rp_uuid]['resources'].pop(rc, None)
|
||||
if not allocations[rp_uuid]['resources']:
|
||||
allocations.pop(rp_uuid, None)
|
||||
else:
|
||||
# No --provider(s) specified so remove allocations from all
|
||||
# providers.
|
||||
allocations = {}
|
||||
if parsed_args.provider:
|
||||
# Remove the given provider(s) from the allocations if it
|
||||
# exists. Do not error out if the consumer does not have
|
||||
# allocations against a provider in case we lost a race since
|
||||
# the allocations are in the state the user wants them in
|
||||
# anyway.
|
||||
for rp_uuid in parsed_args.provider:
|
||||
allocations.pop(rp_uuid, None)
|
||||
else:
|
||||
# No --provider(s) specified so remove allocations from all
|
||||
# providers.
|
||||
allocations = {}
|
||||
|
||||
supports_consumer_generation = self.compare_version(version.ge('1.28'))
|
||||
# 1.28+ allows PUTing an empty allocations dict as long as a
|
||||
|
|
|
@ -260,19 +260,18 @@ class BaseTestCase(base.BaseTestCase):
|
|||
return result
|
||||
|
||||
def resource_allocation_unset(self, consumer_uuid, provider=None,
|
||||
use_json=True):
|
||||
resource_class=None, use_json=True):
|
||||
cmd = 'resource provider allocation unset %s' % consumer_uuid
|
||||
if resource_class:
|
||||
cmd += ' ' + ' '.join(
|
||||
'--resource-class %s' % rc for rc in resource_class)
|
||||
if provider:
|
||||
# --provider can be specified multiple times so if we only get
|
||||
# a single string value convert to a list.
|
||||
if isinstance(provider, six.string_types):
|
||||
provider = [provider]
|
||||
cmd = 'resource provider allocation unset %s %s' % (
|
||||
' '.join('--provider %s' %
|
||||
rp_uuid for rp_uuid in provider),
|
||||
consumer_uuid
|
||||
)
|
||||
else:
|
||||
cmd = 'resource provider allocation unset %s' % consumer_uuid
|
||||
cmd += ' ' + ' '.join(
|
||||
'--provider %s' % rp_uuid for rp_uuid in provider)
|
||||
result = self.openstack(cmd, use_json=use_json)
|
||||
|
||||
def cleanup(uuid):
|
||||
|
|
|
@ -22,12 +22,8 @@ class TestAllocation(base.BaseTestCase):
|
|||
super(TestAllocation, self).setUp()
|
||||
|
||||
self.rp1 = self.resource_provider_create()
|
||||
self.inv_cpu1 = self.resource_inventory_set(
|
||||
self.rp1['uuid'],
|
||||
'VCPU=4',
|
||||
'VCPU:max_unit=4',
|
||||
'MEMORY_MB=1024',
|
||||
'MEMORY_MB:max_unit=1024')
|
||||
self.resource_inventory_set(
|
||||
self.rp1['uuid'], 'VCPU=4', 'MEMORY_MB=1024')
|
||||
|
||||
def test_allocation_show_not_found(self):
|
||||
consumer_uuid = str(uuid.uuid4())
|
||||
|
@ -141,12 +137,8 @@ class TestAllocation112(base.BaseTestCase):
|
|||
super(TestAllocation112, self).setUp()
|
||||
|
||||
self.rp1 = self.resource_provider_create()
|
||||
self.inv_cpu1 = self.resource_inventory_set(
|
||||
self.rp1['uuid'],
|
||||
'VCPU=4',
|
||||
'VCPU:max_unit=4',
|
||||
'MEMORY_MB=1024',
|
||||
'MEMORY_MB:max_unit=1024')
|
||||
self.resource_inventory_set(
|
||||
self.rp1['uuid'], 'VCPU=4', 'MEMORY_MB=1024')
|
||||
|
||||
def test_allocation_update(self):
|
||||
consumer_uuid = str(uuid.uuid4())
|
||||
|
@ -230,32 +222,49 @@ class TestAllocationUnset112(base.BaseTestCase):
|
|||
|
||||
def setUp(self):
|
||||
super(TestAllocationUnset112, self).setUp()
|
||||
# Create two providers with inventory.
|
||||
# Create four providers with inventory.
|
||||
self.rp1 = self.resource_provider_create()
|
||||
self.inv_cpu1 = self.resource_inventory_set(
|
||||
self.rp1['uuid'],
|
||||
'VCPU=4',
|
||||
'VCPU:max_unit=4',
|
||||
'MEMORY_MB=1024',
|
||||
'MEMORY_MB:max_unit=1024')
|
||||
self.rp2 = self.resource_provider_create()
|
||||
self.resource_inventory_set(self.rp2['uuid'], 'VGPU=1')
|
||||
# Create allocations against both providers for the same consumer.
|
||||
self.consumer_uuid = str(uuid.uuid4())
|
||||
self.rp3 = self.resource_provider_create()
|
||||
self.rp4 = self.resource_provider_create()
|
||||
|
||||
self.resource_inventory_set(
|
||||
self.rp1['uuid'], 'VCPU=4', 'MEMORY_MB=1024')
|
||||
self.resource_inventory_set(
|
||||
self.rp2['uuid'], 'VGPU=1')
|
||||
self.resource_inventory_set(
|
||||
self.rp3['uuid'], 'VCPU=4', 'MEMORY_MB=1024', 'VGPU=1')
|
||||
self.resource_inventory_set(
|
||||
self.rp4['uuid'], 'VCPU=4', 'MEMORY_MB=1024', 'VGPU=1')
|
||||
|
||||
self.consumer_uuid1 = str(uuid.uuid4())
|
||||
self.consumer_uuid2 = str(uuid.uuid4())
|
||||
self.project_uuid = str(uuid.uuid4())
|
||||
self.user_uuid = str(uuid.uuid4())
|
||||
|
||||
# Create allocations against rp1 and rp2 for consumer1.
|
||||
self.resource_allocation_set(
|
||||
self.consumer_uuid,
|
||||
self.consumer_uuid1,
|
||||
['rp={},VCPU=2'.format(self.rp1['uuid']),
|
||||
'rp={},MEMORY_MB=512'.format(self.rp1['uuid']),
|
||||
'rp={},VGPU=1'.format(self.rp2['uuid'])],
|
||||
project_id=self.project_uuid, user_id=self.user_uuid)
|
||||
|
||||
# Create allocations against rp3 and rp4 for consumer1.
|
||||
self.resource_allocation_set(
|
||||
self.consumer_uuid2,
|
||||
['rp={},VCPU=1'.format(self.rp3['uuid']),
|
||||
'rp={},MEMORY_MB=256'.format(self.rp3['uuid']),
|
||||
'rp={},VGPU=1'.format(self.rp3['uuid']),
|
||||
'rp={},VCPU=1'.format(self.rp4['uuid']),
|
||||
'rp={},MEMORY_MB=256'.format(self.rp4['uuid'])],
|
||||
project_id=self.project_uuid, user_id=self.user_uuid)
|
||||
|
||||
def test_allocation_unset_one_provider(self):
|
||||
"""Tests removing allocations for one specific provider."""
|
||||
# Remove the allocation for rp1.
|
||||
updated_allocs = self.resource_allocation_unset(
|
||||
self.consumer_uuid, provider=self.rp1['uuid'])
|
||||
self.consumer_uuid1, provider=self.rp1['uuid'])
|
||||
expected = [
|
||||
{'resource_provider': self.rp2['uuid'],
|
||||
'generation': 3,
|
||||
|
@ -265,12 +274,62 @@ class TestAllocationUnset112(base.BaseTestCase):
|
|||
]
|
||||
self.assertEqual(expected, updated_allocs)
|
||||
|
||||
def test_allocation_unset_one_resource_class(self):
|
||||
"""Tests removing allocations for resource classes."""
|
||||
updated_allocs = self.resource_allocation_unset(
|
||||
self.consumer_uuid2, resource_class=['MEMORY_MB'])
|
||||
expected = [
|
||||
{'resource_provider': self.rp3['uuid'],
|
||||
'generation': 3,
|
||||
'project_id': self.project_uuid,
|
||||
'user_id': self.user_uuid,
|
||||
'resources': {'VCPU': 1, 'VGPU': 1}},
|
||||
{'resource_provider': self.rp4['uuid'],
|
||||
'generation': 3,
|
||||
'project_id': self.project_uuid,
|
||||
'user_id': self.user_uuid,
|
||||
'resources': {'VCPU': 1}}
|
||||
]
|
||||
self.assertEqual(expected, updated_allocs)
|
||||
|
||||
def test_allocation_unset_resource_classes(self):
|
||||
"""Tests removing allocations for resource classes."""
|
||||
updated_allocs = self.resource_allocation_unset(
|
||||
self.consumer_uuid2, resource_class=['VCPU', 'MEMORY_MB'])
|
||||
expected = [
|
||||
{'resource_provider': self.rp3['uuid'],
|
||||
'generation': 3,
|
||||
'project_id': self.project_uuid,
|
||||
'user_id': self.user_uuid,
|
||||
'resources': {'VGPU': 1}}
|
||||
]
|
||||
self.assertEqual(expected, updated_allocs)
|
||||
|
||||
def test_allocation_unset_provider_and_rc(self):
|
||||
"""Tests removing allocations of resource classes for a provider ."""
|
||||
updated_allocs = self.resource_allocation_unset(
|
||||
self.consumer_uuid2, provider=self.rp3['uuid'],
|
||||
resource_class=['VCPU', 'MEMORY_MB'])
|
||||
expected = [
|
||||
{'resource_provider': self.rp3['uuid'],
|
||||
'generation': 3,
|
||||
'project_id': self.project_uuid,
|
||||
'user_id': self.user_uuid,
|
||||
'resources': {'VGPU': 1}},
|
||||
{'resource_provider': self.rp4['uuid'],
|
||||
'generation': 3,
|
||||
'project_id': self.project_uuid,
|
||||
'user_id': self.user_uuid,
|
||||
'resources': {'VCPU': 1, 'MEMORY_MB': 256}},
|
||||
]
|
||||
self.assertEqual(expected, updated_allocs)
|
||||
|
||||
def test_allocation_unset_remove_all_providers(self):
|
||||
"""Tests removing all allocations by omitting the --provider option."""
|
||||
# For this test pass use_json=False to make sure we get nothing back
|
||||
# in the output since there are no more allocations.
|
||||
updated_allocs = self.resource_allocation_unset(
|
||||
self.consumer_uuid, use_json=False)
|
||||
self.consumer_uuid1, use_json=False)
|
||||
self.assertEqual('', updated_allocs.strip())
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
---
|
||||
features:
|
||||
- |
|
||||
The ``openstack resource provider allocation unset`` command now supports
|
||||
``--resource-class`` option, which accepts string of a resource class.
|
||||
This will remove allocations for the given resource class from all the
|
||||
providers. If ``--provider`` option is also specified, allocations to
|
||||
remove will be limited to the given resource class of the given resource
|
||||
provider.
|
||||
|
||||
example1::
|
||||
|
||||
# remove VGPU allocation from provider P for this consumer.
|
||||
allocation unset <consumer_uuid> --provider P --resource-class VGPU
|
||||
|
||||
example2::
|
||||
|
||||
# remove VGPU allocations from all providers for this consumer.
|
||||
allocation unset <consumer_uuid> --resource-class VGPU
|
Loading…
Reference in New Issue