diff --git a/nova/cmd/manage.py b/nova/cmd/manage.py index 4d92248768d7..788ec2ccaa7b 100644 --- a/nova/cmd/manage.py +++ b/nova/cmd/manage.py @@ -1229,11 +1229,17 @@ class CellV2Commands(object): try: cell0_mapping = self.map_cell0() except db_exc.DBDuplicateEntry: - print('Already setup, nothing to do.') - return 0 + print(_('Cell0 is already setup')) + cell0_mapping = objects.CellMapping.get_by_uuid( + ctxt, objects.CellMapping.CELL0_UUID) + # Run migrations so cell0 is usable with context.target_cell(ctxt, cell0_mapping): - migration.db_sync(None, context=ctxt) + try: + migration.db_sync(None, context=ctxt) + except db_exc.DBError as ex: + print(_('Unable to sync cell0 schema: %s') % ex) + cell_uuid = self._map_cell_and_hosts(transport_url) if cell_uuid is None: # There are no compute hosts which means no cell_mapping was diff --git a/nova/tests/unit/test_nova_manage.py b/nova/tests/unit/test_nova_manage.py index 9be19e1e34cb..e6bb956cfd25 100644 --- a/nova/tests/unit/test_nova_manage.py +++ b/nova/tests/unit/test_nova_manage.py @@ -17,6 +17,7 @@ import sys import fixtures import mock +from oslo_db import exception as db_exc from oslo_utils import uuidutils from six.moves import StringIO @@ -1166,7 +1167,7 @@ class CellV2CommandsTestCase(test.NoDBTestCase): self.assertEqual('fake://netloc/nova_api_cell0', cell_mapping.database_connection) - def _test_migrate_simple_command(self, first_call=True): + def _test_migrate_simple_command(self, cell0_sync_fail=False): ctxt = context.RequestContext() CONF.set_default('connection', 'fake://netloc/nova_api', @@ -1194,12 +1195,11 @@ class CellV2CommandsTestCase(test.NoDBTestCase): @mock.patch.object(uuidutils, 'generate_uuid', return_value=cell_uuid) def _test(mock_gen_uuid, mock_db_sync): + if cell0_sync_fail: + mock_db_sync.side_effect = db_exc.DBError result = self.commands.simple_cell_setup(transport_url) - if first_call: - mock_db_sync.assert_called_once_with( - None, context=test.MatchType(context.RequestContext)) - else: - mock_db_sync.assert_not_called() + mock_db_sync.assert_called_once_with( + None, context=test.MatchType(context.RequestContext)) return result r = _test() @@ -1225,11 +1225,15 @@ class CellV2CommandsTestCase(test.NoDBTestCase): def test_simple_command_single(self): self._test_migrate_simple_command() + def test_simple_command_cell0_fail(self): + # Make sure that if db_sync fails, we still do all the other + # bits + self._test_migrate_simple_command(cell0_sync_fail=True) + def test_simple_command_multiple(self): + # Make sure that the command is idempotent + self._test_migrate_simple_command() self._test_migrate_simple_command() - with mock.patch.object(self.commands, '_map_cell_and_hosts') as m: - self._test_migrate_simple_command(first_call=False) - self.assertFalse(m.called) def test_simple_command_cellsv1(self): self.flags(enable=True, group='cells')