Marker reset option for nova-manage map_instances

Currently nova-manage map_instances uses a marker set-up by which repeated
runs of the command will start from where the last run finished. Even
deleting the cell with the instance_mappings will not remove the marker
since the marker mapping has a NULL cell_mapping field. There needs to be
a way to reset this marker so that the user can run map_instances from the
beginning instead of the map_instances command saying "all instances are
already mapped" as is the current behavior.

Change-Id: Ic9a0bda9314cc1caed993db101bf6f874c0a0ae8
Closes-Bug: #1745358
This commit is contained in:
Surya Seetharaman 2018-01-31 12:39:34 +01:00
parent 9e328b7bb4
commit 98163f98b7
4 changed files with 93 additions and 7 deletions

View File

@ -153,14 +153,16 @@ Nova Cells v2
error before they have been scheduled. Returns 0 if cell0 is created
successfully or already setup.
``nova-manage cell_v2 map_instances --cell_uuid <cell_uuid> [--max-count <max_count>]``
``nova-manage cell_v2 map_instances --cell_uuid <cell_uuid> [--max-count <max_count>] [--reset]``
Map instances to the provided cell. Instances in the nova database will
be queried from oldest to newest and mapped to the provided cell. A
max_count can be set on the number of instance to map in a single run.
Repeated runs of the command will start from where the last run finished
so it is not necessary to increase max-count to finish. Returns 0 if all
instances have been mapped, and 1 if there are still instances to be
mapped.
so it is not necessary to increase max-count to finish. A reset option
can be passed which will reset the marker, thus making the command start
from the beginning as opposed to the default behavior of starting from
where the last run finished. Returns 0 if all instances have been mapped,
and 1 if there are still instances to be mapped.
If ``--max-count`` is not specified, all instances in the cell will be
mapped in batches of 50. If you have a large number of instances, consider

View File

@ -1130,7 +1130,11 @@ class CellV2Commands(object):
'in the cell will be mapped in batches of 50. If you have a '
'large number of instances, consider specifying a custom value '
'and run the command until it exits with 0.')
def map_instances(self, cell_uuid, max_count=None):
@args('--reset', action='store_true', dest='reset_marker',
help='The command will start from the beginning as opposed to the '
'default behavior of starting from where the last run '
'finished')
def map_instances(self, cell_uuid, max_count=None, reset_marker=None):
"""Map instances into the provided cell.
Instances in the nova database of the provided cell (nova database
@ -1138,8 +1142,11 @@ class CellV2Commands(object):
oldest to newest and if unmapped, will be mapped to the provided cell.
A max-count can be set on the number of instance to map in a single
run. Repeated runs of the command will start from where the last run
finished so it is not necessary to increase max-count to finish. An
exit code of 0 indicates that all instances have been mapped.
finished so it is not necessary to increase max-count to finish. A
reset option can be passed which will reset the marker, thus making the
command start from the beginning as opposed to the default behavior of
starting from where the last run finished. An exit code of 0 indicates
that all instances have been mapped.
"""
if max_count is not None:
@ -1169,6 +1176,8 @@ class CellV2Commands(object):
else:
# There should be only one here
marker = marker_mapping[0].instance_uuid.replace(' ', '-')
if reset_marker:
marker = None
marker_mapping[0].destroy()
next_marker = True

View File

@ -1272,6 +1272,73 @@ class CellV2CommandsTestCase(test.NoDBTestCase):
test.MatchType(context.RequestContext),
test.MatchObjPrims(cell_mapping))
@mock.patch.object(context, 'target_cell')
def test_map_instances_marker_reset(self, mock_target_cell):
ctxt = context.RequestContext('fake-user', 'fake_project')
cell_uuid = uuidutils.generate_uuid()
cell_mapping = objects.CellMapping(
ctxt, uuid=cell_uuid, name='fake',
transport_url='fake://', database_connection='fake://')
cell_mapping.create()
mock_target_cell.return_value.__enter__.return_value = ctxt
instance_uuids = []
for i in range(5):
uuid = uuidutils.generate_uuid()
instance_uuids.append(uuid)
objects.Instance(ctxt, project_id=ctxt.project_id,
uuid=uuid).create()
# Maps first three instances.
ret = self.commands.map_instances(cell_uuid, max_count=3)
self.assertEqual(1, ret)
# Verifying that the marker is now based on third instance
# i.e the position of the marker.
inst_mappings = objects.InstanceMappingList.get_by_project_id(ctxt,
'INSTANCE_MIGRATION_MARKER')
marker = inst_mappings[0].instance_uuid.replace(' ', '-')
self.assertEqual(instance_uuids[2], marker)
# Now calling reset with map_instances max_count=2 would reset
# the marker as expected and start map_instances from the beginning.
# This implies we end up finding the marker based on second instance.
ret = self.commands.map_instances(cell_uuid, max_count=2,
reset_marker=True)
self.assertEqual(1, ret)
inst_mappings = objects.InstanceMappingList.get_by_project_id(ctxt,
'INSTANCE_MIGRATION_MARKER')
marker = inst_mappings[0].instance_uuid.replace(' ', '-')
self.assertEqual(instance_uuids[1], marker)
# Maps 4th instance using the marker (3rd is already mapped).
ret = self.commands.map_instances(cell_uuid, max_count=2)
self.assertEqual(1, ret)
# Verifying that the marker is now based on fourth instance
# i.e the position of the marker.
inst_mappings = objects.InstanceMappingList.get_by_project_id(ctxt,
'INSTANCE_MIGRATION_MARKER')
marker = inst_mappings[0].instance_uuid.replace(' ', '-')
self.assertEqual(instance_uuids[3], marker)
# Maps first four instances (all four duplicate entries which
# are already present from previous calls)
ret = self.commands.map_instances(cell_uuid, max_count=4,
reset_marker=True)
self.assertEqual(1, ret)
# Verifying that the marker is still based on fourth instance
# i.e the position of the marker.
inst_mappings = objects.InstanceMappingList.get_by_project_id(ctxt,
'INSTANCE_MIGRATION_MARKER')
marker = inst_mappings[0].instance_uuid.replace(' ', '-')
self.assertEqual(instance_uuids[3], marker)
# Maps the 5th instance.
ret = self.commands.map_instances(cell_uuid)
self.assertEqual(0, ret)
def test_map_instances_validate_cell_uuid(self):
# create a random cell_uuid which is invalid
cell_uuid = uuidutils.generate_uuid()

View File

@ -0,0 +1,8 @@
---
features:
- |
Currently the ``nova-manage cell_v2 map_instances`` command uses a marker
setup by which repeated runs of the command will start from where the last
run finished, by default. A ``--reset`` option has been added to this command
by which the marker can be reset and users can start the process from the
beginning if needed, instead of the default behavior.