Add an update_cell command to nova-manage

In case a cell record was incorrectly created, or needs to be updated
to point to a new database or mq endpoint, we need a way for users to
be able to update a CellMapping record. Since deleting and re-creating
is definitely not an option, this patch adds an update_cell which
allows updating the mutable fields if necessary.

Change-Id: I75ddfa458a6fb650f1098505193398984f2be596
This commit is contained in:
Dan Smith 2017-02-07 08:43:42 -08:00
parent 46c778efaf
commit 1102441a42
3 changed files with 86 additions and 0 deletions

View File

@ -163,6 +163,17 @@ Nova Cells v2
found, 2 if host mappings were found for the cell (cell not empty), and
3 if there are instances mapped to the cell (cell not empty).
``nova-manage cell_v2 update_cell --cell_uuid <cell_uuid> [--name <cell_name>] [--transport-url <transport_url>] [--database_connection <database_connection>]``
Updates the properties of a cell by the given uuid. If the cell is not
found by uuid, this command will return an exit code of 1. If the
properties cannot be set, this will return 2. Otherwise, the exit code
will be 0.
NOTE: Updating the transport_url or database_connection fields on
a running system will NOT result in all nodes immediately using the
new values. Use caution when changing these values.
Nova Logs
~~~~~~~~~

View File

@ -1496,6 +1496,49 @@ class CellV2Commands(object):
cell_mapping.destroy()
return 0
@args('--cell_uuid', metavar='<cell_uuid>', dest='cell_uuid',
required=True, help=_('The uuid of the cell to update.'))
@args('--name', metavar='<name>', dest='name',
help=_('Set the cell name.'))
@args('--transport-url', metavar='<transport>', dest='transport_url',
help=_('Set the cell transport_url. NOTE that running nodes '
'will not see the change until restart!'))
@args('--database_connection', metavar='<database>', dest='db_connection',
help=_('Set the cell database_connection. NOTE that running nodes '
'will not see the change until restart!'))
def update_cell(self, cell_uuid, name, transport_url, db_connection):
"""Updates the properties of a cell by the given uuid.
If the cell is not found by uuid, this command will return an exit
code of 1. If the properties cannot be set, this will return 2.
Otherwise, the exit code will be 0.
NOTE: Updating the transport_url or database_connection fields on
a running system will NOT result in all nodes immediately using the
new values. Use caution when changing these values.
"""
ctxt = context.get_admin_context()
try:
cell_mapping = objects.CellMapping.get_by_uuid(ctxt, cell_uuid)
except exception.CellMappingNotFound:
print(_('Cell with uuid %s was not found.') % cell_uuid)
return 1
if name:
cell_mapping.name = name
if transport_url:
cell_mapping.transport_url = transport_url
if db_connection:
cell_mapping.database_connection = db_connection
try:
cell_mapping.save()
except Exception as e:
print(_('Unable to update CellMapping: %s') % e)
return 2
return 0
CATEGORIES = {
'account': AccountCommands,

View File

@ -1532,6 +1532,38 @@ class CellV2CommandsTestCase(test.NoDBTestCase):
output = self.output.getvalue().strip()
self.assertEqual('', output)
def test_update_cell_not_found(self):
self.assertEqual(1, self.commands.update_cell(
uuidsentinel.cell1, 'foo', 'fake://new', 'fake:///new'))
self.assertIn('not found', self.output.getvalue())
def test_update_cell_failed(self):
ctxt = context.get_admin_context()
objects.CellMapping(context=ctxt, uuid=uuidsentinel.cell1,
name='cell1',
transport_url='fake://mq',
database_connection='fake:///db').create()
with mock.patch('nova.objects.CellMapping.save') as mock_save:
mock_save.side_effect = Exception
self.assertEqual(2, self.commands.update_cell(
uuidsentinel.cell1, 'foo', 'fake://new', 'fake:///new'))
self.assertIn('Unable to update', self.output.getvalue())
def test_update_cell_success(self):
ctxt = context.get_admin_context()
objects.CellMapping(context=ctxt, uuid=uuidsentinel.cell1,
name='cell1',
transport_url='fake://mq',
database_connection='fake:///db').create()
self.assertEqual(0, self.commands.update_cell(
uuidsentinel.cell1, 'foo', 'fake://new', 'fake:///new'))
cm = objects.CellMapping.get_by_uuid(ctxt, uuidsentinel.cell1)
self.assertEqual('foo', cm.name)
self.assertEqual('fake://new', cm.transport_url)
self.assertEqual('fake:///new', cm.database_connection)
output = self.output.getvalue().strip()
self.assertEqual('', output)
class TestNovaManageMain(test.NoDBTestCase):
"""Tests the nova-manage:main() setup code."""