Make nova-manage online migrations more verbose

This makes the online_data_migrations command for nova-manage a little
more verbose in what it is doing. Each time it is run, it will show you
all the migrations that need running and how many records remain for
each. Basically, you run this until you see all zeroes.

Change-Id: I78c6312ec8e226a6ef9185382b6180f246f8fe84
This commit is contained in:
Dan Smith 2016-09-20 07:21:14 -07:00
parent 80fd1ccac9
commit 7e71a4e0a2
3 changed files with 42 additions and 6 deletions

View File

@ -66,6 +66,7 @@ from oslo_log import log as logging
import oslo_messaging as messaging
from oslo_utils import importutils
from oslo_utils import uuidutils
import prettytable
import six
import six.moves.urllib.parse as urlparse
@ -881,6 +882,7 @@ class DbCommands(object):
def _run_migration(self, ctxt, max_count):
ran = 0
migrations = {}
for migration_meth in self.online_migrations:
count = max_count - ran
try:
@ -890,16 +892,20 @@ class DbCommands(object):
method=migration_meth))
found = done = 0
name = migration_meth.__name__
if found:
print(_('%(total)i rows matched query %(meth)s, %(done)i '
'migrated') % {'total': found,
'meth': migration_meth.__name__,
'meth': name,
'done': done})
migrations.setdefault(name, (0, 0))
migrations[name] = (migrations[name][0] + found,
migrations[name][1] + done)
if max_count is not None:
ran += done
if ran >= max_count:
break
return ran
return migrations
@args('--max-count', metavar='<number>', dest='max_count',
help='Maximum number of objects to consider')
@ -920,11 +926,22 @@ class DbCommands(object):
print(_('Running batches of %i until complete') % max_count)
ran = None
migration_info = {}
while ran is None or ran != 0:
ran = self._run_migration(ctxt, max_count)
migrations = self._run_migration(ctxt, max_count)
migration_info.update(migrations)
ran = sum([done for found, done in migrations.values()])
if not unlimited:
break
t = prettytable.PrettyTable([_('Migration'),
_('Total Needed'),
_('Completed')])
for name in sorted(migration_info.keys()):
info = migration_info[name]
t.add_row([name, info[0], info[1]])
print(t)
return ran and 1 or 0

View File

@ -592,12 +592,24 @@ class DBCommandsTestCase(test.NoDBTestCase):
@mock.patch('nova.context.get_admin_context')
def test_online_migrations(self, mock_get_context):
self.useFixture(fixtures.MonkeyPatch('sys.stdout', StringIO()))
ctxt = mock_get_context.return_value
command_cls = self._fake_db_command()
command = command_cls()
command.online_data_migrations(10)
command_cls.online_migrations[0].assert_called_once_with(ctxt, 10)
command_cls.online_migrations[1].assert_called_once_with(ctxt, 6)
expected = """\
5 rows matched query mock_mig_1, 4 migrated
6 rows matched query mock_mig_2, 6 migrated
+------------+--------------+-----------+
| Migration | Total Needed | Completed |
+------------+--------------+-----------+
| mock_mig_1 | 5 | 4 |
| mock_mig_2 | 6 | 6 |
+------------+--------------+-----------+
"""
self.assertEqual(expected, sys.stdout.getvalue())
@mock.patch('nova.context.get_admin_context')
def test_online_migrations_no_max_count(self, mock_get_context):
@ -622,6 +634,7 @@ class DBCommandsTestCase(test.NoDBTestCase):
def test_online_migrations_error(self):
fake_migration = mock.MagicMock()
fake_migration.side_effect = Exception
fake_migration.__name__ = 'fake'
command_cls = self._fake_db_command((fake_migration,))
command = command_cls()
command.online_data_migrations(None)
@ -636,19 +649,19 @@ class DBCommandsTestCase(test.NoDBTestCase):
def test_online_migrations_no_max(self):
with mock.patch.object(self.commands, '_run_migration') as rm:
rm.return_value = 0
rm.return_value = {}
self.assertEqual(0,
self.commands.online_data_migrations())
def test_online_migrations_finished(self):
with mock.patch.object(self.commands, '_run_migration') as rm:
rm.return_value = 0
rm.return_value = {}
self.assertEqual(0,
self.commands.online_data_migrations(max_count=5))
def test_online_migrations_not_finished(self):
with mock.patch.object(self.commands, '_run_migration') as rm:
rm.return_value = 5
rm.return_value = {'mig': (10, 5)}
self.assertEqual(1,
self.commands.online_data_migrations(max_count=5))

View File

@ -0,0 +1,6 @@
---
features:
- The nova-manage online_data_migrations command now prints a
tabular summary of completed and remaining records. The goal
here is to get all your numbers to zero. The previous execution
return code behavior is retained for scripting.