Merge "Support for nova-manage placement heal_allocations --cell"
This commit is contained in:
commit
ae39f0395f
@ -546,7 +546,7 @@ Placement
|
|||||||
|
|
||||||
.. _heal_allocations_cli:
|
.. _heal_allocations_cli:
|
||||||
|
|
||||||
``nova-manage placement heal_allocations [--max-count <max_count>] [--verbose] [--skip-port-allocations] [--dry-run] [--instance <instance_uuid>]``
|
``nova-manage placement heal_allocations [--max-count <max_count>] [--verbose] [--skip-port-allocations] [--dry-run] [--instance <instance_uuid>] [--cell <cell_uuid]``
|
||||||
Iterates over non-cell0 cells looking for instances which do not have
|
Iterates over non-cell0 cells looking for instances which do not have
|
||||||
allocations in the Placement service and which are not undergoing a task
|
allocations in the Placement service and which are not undergoing a task
|
||||||
state transition. For each instance found, allocations are created against
|
state transition. For each instance found, allocations are created against
|
||||||
@ -603,6 +603,9 @@ Placement
|
|||||||
ports for each instance can be avoided with this flag.
|
ports for each instance can be avoided with this flag.
|
||||||
*(Since 20.0.0 Train)*
|
*(Since 20.0.0 Train)*
|
||||||
|
|
||||||
|
Specify ``--cell`` to process heal allocations within a specific cell.
|
||||||
|
This is mutually exclusive with the ``--instance`` option.
|
||||||
|
|
||||||
This command requires that the
|
This command requires that the
|
||||||
:oslo.config:option:`api_database.connection` and
|
:oslo.config:option:`api_database.connection` and
|
||||||
:oslo.config:group:`placement` configuration options are set. Placement API
|
:oslo.config:group:`placement` configuration options are set. Placement API
|
||||||
|
@ -2090,7 +2090,8 @@ class PlacementCommands(object):
|
|||||||
'changes. The return code should be 4.')
|
'changes. The return code should be 4.')
|
||||||
@args('--instance', metavar='<instance_uuid>', dest='instance_uuid',
|
@args('--instance', metavar='<instance_uuid>', dest='instance_uuid',
|
||||||
help='UUID of a specific instance to process. If specified '
|
help='UUID of a specific instance to process. If specified '
|
||||||
'--max-count has no effect.')
|
'--max-count has no effect. '
|
||||||
|
'The --cell and --instance options are mutually exclusive.')
|
||||||
@args('--skip-port-allocations', action='store_true',
|
@args('--skip-port-allocations', action='store_true',
|
||||||
dest='skip_port_allocations', default=False,
|
dest='skip_port_allocations', default=False,
|
||||||
help='Skip the healing of the resource allocations of bound ports. '
|
help='Skip the healing of the resource allocations of bound ports. '
|
||||||
@ -2099,8 +2100,12 @@ class PlacementCommands(object):
|
|||||||
'not use such a feature then the performance impact of '
|
'not use such a feature then the performance impact of '
|
||||||
'querying neutron ports for each instance can be avoided with '
|
'querying neutron ports for each instance can be avoided with '
|
||||||
'this flag.')
|
'this flag.')
|
||||||
|
@args('--cell', metavar='<cell_uuid>', dest='cell_uuid',
|
||||||
|
help='Heal allocations within a specific cell. '
|
||||||
|
'The --cell and --instance options are mutually exclusive.')
|
||||||
def heal_allocations(self, max_count=None, verbose=False, dry_run=False,
|
def heal_allocations(self, max_count=None, verbose=False, dry_run=False,
|
||||||
instance_uuid=None, skip_port_allocations=False):
|
instance_uuid=None, skip_port_allocations=False,
|
||||||
|
cell_uuid=None):
|
||||||
"""Heals instance allocations in the Placement service
|
"""Heals instance allocations in the Placement service
|
||||||
|
|
||||||
Return codes:
|
Return codes:
|
||||||
@ -2117,7 +2122,6 @@ class PlacementCommands(object):
|
|||||||
* 127: Invalid input.
|
* 127: Invalid input.
|
||||||
"""
|
"""
|
||||||
# NOTE(mriedem): Thoughts on ways to expand this:
|
# NOTE(mriedem): Thoughts on ways to expand this:
|
||||||
# - allow passing a specific cell to heal
|
|
||||||
# - allow filtering on enabled/disabled cells
|
# - allow filtering on enabled/disabled cells
|
||||||
# - add a force option to force allocations for instances which have
|
# - add a force option to force allocations for instances which have
|
||||||
# task_state is not None (would get complicated during a migration);
|
# task_state is not None (would get complicated during a migration);
|
||||||
@ -2135,6 +2139,13 @@ class PlacementCommands(object):
|
|||||||
if verbose:
|
if verbose:
|
||||||
output = lambda msg: print(msg)
|
output = lambda msg: print(msg)
|
||||||
|
|
||||||
|
# If user has provided both cell and instance
|
||||||
|
# Throw an error
|
||||||
|
if instance_uuid and cell_uuid:
|
||||||
|
print(_('The --cell and --instance options '
|
||||||
|
'are mutually exclusive.'))
|
||||||
|
return 127
|
||||||
|
|
||||||
# TODO(mriedem): Rather than --max-count being both a total and batch
|
# TODO(mriedem): Rather than --max-count being both a total and batch
|
||||||
# count, should we have separate options to be specific, i.e. --total
|
# count, should we have separate options to be specific, i.e. --total
|
||||||
# and --batch-size? Then --batch-size defaults to 50 and --total
|
# and --batch-size? Then --batch-size defaults to 50 and --total
|
||||||
@ -2170,6 +2181,15 @@ class PlacementCommands(object):
|
|||||||
'"nova-manage cell_v2 map_instances".' %
|
'"nova-manage cell_v2 map_instances".' %
|
||||||
instance_uuid)
|
instance_uuid)
|
||||||
return 127
|
return 127
|
||||||
|
elif cell_uuid:
|
||||||
|
try:
|
||||||
|
# validate cell_uuid
|
||||||
|
cell = objects.CellMapping.get_by_uuid(ctxt, cell_uuid)
|
||||||
|
# create CellMappingList
|
||||||
|
cells = objects.CellMappingList(objects=[cell])
|
||||||
|
except exception.CellMappingNotFound:
|
||||||
|
print(_('Cell with uuid %s was not found.') % cell_uuid)
|
||||||
|
return 127
|
||||||
else:
|
else:
|
||||||
cells = objects.CellMappingList.get_all(ctxt)
|
cells = objects.CellMappingList.get_all(ctxt)
|
||||||
if not cells:
|
if not cells:
|
||||||
|
@ -746,6 +746,45 @@ class TestNovaManagePlacementHealAllocations(
|
|||||||
self.assertIn('Unable to find cell for instance %s, is it mapped?' %
|
self.assertIn('Unable to find cell for instance %s, is it mapped?' %
|
||||||
server['id'], output)
|
server['id'], output)
|
||||||
|
|
||||||
|
def test_heal_allocations_specific_cell(self):
|
||||||
|
"""Tests the case that a specific cell is processed and only that
|
||||||
|
cell even though there are two which require processing.
|
||||||
|
"""
|
||||||
|
# Create one that we won't process.
|
||||||
|
server1, rp_uuid1 = self._boot_and_assert_no_allocations(
|
||||||
|
self.flavor, 'cell1')
|
||||||
|
# Create another that we will process specifically.
|
||||||
|
server2, rp_uuid2 = self._boot_and_assert_no_allocations(
|
||||||
|
self.flavor, 'cell2')
|
||||||
|
|
||||||
|
# Get Cell_id of cell2
|
||||||
|
cell2_id = self.cell_mappings['cell2'].uuid
|
||||||
|
|
||||||
|
# First do a dry run to make sure two instances need processing.
|
||||||
|
result = self.cli.heal_allocations(
|
||||||
|
max_count=2, verbose=True, dry_run=True)
|
||||||
|
# Nothing changed so the return code should be 4.
|
||||||
|
self.assertEqual(4, result, self.output.getvalue())
|
||||||
|
output = self.output.getvalue()
|
||||||
|
self.assertIn('Found 1 candidate instances', output)
|
||||||
|
|
||||||
|
# Now run with our specific cell and it should be the only one
|
||||||
|
# processed.
|
||||||
|
result = self.cli.heal_allocations(verbose=True,
|
||||||
|
cell_uuid=cell2_id)
|
||||||
|
output = self.output.getvalue()
|
||||||
|
self.assertEqual(0, result, self.output.getvalue())
|
||||||
|
self.assertIn('Found 1 candidate instances', output)
|
||||||
|
self.assertIn('Processed 1 instances.', output)
|
||||||
|
|
||||||
|
# Now run it again on the specific cell and it should be done.
|
||||||
|
result = self.cli.heal_allocations(
|
||||||
|
verbose=True, cell_uuid=cell2_id)
|
||||||
|
output = self.output.getvalue()
|
||||||
|
self.assertEqual(4, result, self.output.getvalue())
|
||||||
|
self.assertIn('Found 1 candidate instances', output)
|
||||||
|
self.assertIn('Processed 0 instances.', output)
|
||||||
|
|
||||||
|
|
||||||
class TestNovaManagePlacementHealPortAllocations(
|
class TestNovaManagePlacementHealPortAllocations(
|
||||||
test_servers.PortResourceRequestBasedSchedulingTestBase):
|
test_servers.PortResourceRequestBasedSchedulingTestBase):
|
||||||
|
@ -2347,6 +2347,24 @@ class TestNovaManagePlacement(test.NoDBTestCase):
|
|||||||
self.cli = manage.PlacementCommands()
|
self.cli = manage.PlacementCommands()
|
||||||
self.useFixture(fixtures.MockPatch('nova.network.neutron.get_client'))
|
self.useFixture(fixtures.MockPatch('nova.network.neutron.get_client'))
|
||||||
|
|
||||||
|
def test_heal_allocations_with_cell_instance_id(self):
|
||||||
|
"""Test heal allocation with both cell id and instance id"""
|
||||||
|
cell_uuid = uuidutils.generate_uuid()
|
||||||
|
instance_uuid = uuidutils.generate_uuid()
|
||||||
|
self.assertEqual(127, self.cli.heal_allocations(
|
||||||
|
instance_uuid=instance_uuid,
|
||||||
|
cell_uuid=cell_uuid))
|
||||||
|
self.assertIn('The --cell and --instance options',
|
||||||
|
self.output.getvalue())
|
||||||
|
|
||||||
|
@mock.patch('nova.objects.CellMapping.get_by_uuid',
|
||||||
|
side_effect=exception.CellMappingNotFound(uuid='fake'))
|
||||||
|
def test_heal_allocations_with_cell_id_not_found(self, mock_get):
|
||||||
|
"""Test the case where cell_id is not found"""
|
||||||
|
self.assertEqual(127, self.cli.heal_allocations(cell_uuid='fake'))
|
||||||
|
output = self.output.getvalue().strip()
|
||||||
|
self.assertEqual('Cell with uuid fake was not found.', output)
|
||||||
|
|
||||||
@ddt.data(-1, 0, "one")
|
@ddt.data(-1, 0, "one")
|
||||||
def test_heal_allocations_invalid_max_count(self, max_count):
|
def test_heal_allocations_invalid_max_count(self, max_count):
|
||||||
self.assertEqual(127, self.cli.heal_allocations(max_count=max_count))
|
self.assertEqual(127, self.cli.heal_allocations(max_count=max_count))
|
||||||
|
@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- Add ``--cell`` option to the ``nova-manage placement heal_allocations``
|
||||||
|
command. This option allows healing instance allocations within a specific cell.
|
Loading…
x
Reference in New Issue
Block a user