diff --git a/doc/source/cli/nova-manage.rst b/doc/source/cli/nova-manage.rst index 30b54500c841..d91e7ca5702c 100644 --- a/doc/source/cli/nova-manage.rst +++ b/doc/source/cli/nova-manage.rst @@ -237,7 +237,7 @@ Nova Cells v2 If the cell is not found by uuid, this command will return an exit code of 1. Otherwise, the exit code will be 0. -``nova-manage cell_v2 update_cell --cell_uuid [--name ] [--transport-url ] [--database_connection ]`` +``nova-manage cell_v2 update_cell --cell_uuid [--name ] [--transport-url ] [--database_connection ] [--disable] [--enable]`` Updates the properties of a cell by the given uuid. If a database_connection is not specified, it will attempt to use the one defined by ``[database]/connection`` in the configuration file. If a @@ -246,7 +246,10 @@ Nova Cells v2 found by uuid, this command will return an exit code of 1. If the provided transport_url or/and database_connection is/are same as another cell, this command will return an exit code of 3. If the properties cannot be set, - this will return 2. Otherwise, the exit code will be 0. + this will return 2. If an attempt is made to disable and enable a cell at the + same time, this command will return an exit code of 4. If an attempt is made + to disable or enable cell0 this command will return an exit code of 5. + Otherwise, the exit code will be 0. .. note:: @@ -254,6 +257,9 @@ Nova Cells v2 running system will NOT result in all nodes immediately using the new values. Use caution when changing these values. + The scheduler will not notice that a cell has been enabled/disabled until + it is restarted or sent the SIGHUP signal. + ``nova-manage cell_v2 delete_host --cell_uuid --host `` Delete a host by the given host name and the given cell uuid. Returns 0 if the empty host is found and deleted successfully, 1 if a cell with diff --git a/nova/cmd/manage.py b/nova/cmd/manage.py index 406c1f01d78e..5ff6a1f9fdf9 100644 --- a/nova/cmd/manage.py +++ b/nova/cmd/manage.py @@ -1541,19 +1541,32 @@ class CellV2Commands(object): dest='db_connection', help=_('Set the cell database_connection. NOTE that running nodes ' 'will not see the change until restart!')) + @args('--disable', action='store_true', dest='disable', + help=_('Disables the cell. Note that the scheduling will be blocked ' + 'to this cell until its enabled and followed by a SIGHUP of ' + 'nova-scheduler service.')) + @args('--enable', action='store_true', dest='enable', + help=_('Enables the cell. Note that this makes a disabled cell ' + 'available for scheduling after a SIGHUP of the ' + 'nova-scheduler service')) def update_cell(self, cell_uuid, name=None, transport_url=None, - db_connection=None): + db_connection=None, disable=False, enable=False): """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 provided transport_url or/and database_connection is/are same as another cell, this command will return an exit code - of 3. If the properties cannot be set, this will return 2. + of 3. If the properties cannot be set, this will return 2. If an + attempt is made to disable and enable a cell at the same time, this + command will exit with a return code of 4. If an attempt is made to + disable or enable cell0 this command will exit with a return code of 5. 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. + NOTE (tssurya): The scheduler will not notice that a cell has been + enabled/disabled until it is restarted or sent the SIGHUP signal. """ ctxt = context.get_admin_context() try: @@ -1580,6 +1593,22 @@ class CellV2Commands(object): if db_connection: cell_mapping.database_connection = db_connection + if disable and enable: + print(_('Cell cannot be disabled and enabled at the same time.')) + return 4 + if disable or enable: + if cell_mapping.is_cell0(): + print(_('Cell0 cannot be disabled.')) + return 5 + elif disable and not cell_mapping.disabled: + cell_mapping.disabled = True + elif enable and cell_mapping.disabled: + cell_mapping.disabled = False + elif disable and cell_mapping.disabled: + print(_('Cell %s is already disabled') % cell_uuid) + elif enable and not cell_mapping.disabled: + print(_('Cell %s is already enabled') % cell_uuid) + try: cell_mapping.save() except Exception as e: diff --git a/nova/tests/unit/test_nova_manage.py b/nova/tests/unit/test_nova_manage.py index ab8eb3045736..b3f6c1f748bd 100644 --- a/nova/tests/unit/test_nova_manage.py +++ b/nova/tests/unit/test_nova_manage.py @@ -2062,6 +2062,89 @@ class CellV2CommandsTestCase(test.NoDBTestCase): output = self.output.getvalue().strip() self.assertEqual('', output) + def test_update_cell_disable_and_enable(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(4, self.commands.update_cell(uuidsentinel.cell1, + disable=True, + enable=True)) + output = self.output.getvalue().strip() + self.assertEqual('Cell cannot be disabled and enabled at the same ' + 'time.', output) + + def test_update_cell_disable_cell0(self): + ctxt = context.get_admin_context() + uuid0 = objects.CellMapping.CELL0_UUID + objects.CellMapping(context=ctxt, uuid=uuid0, name='cell0', + transport_url='fake://mq', + database_connection='fake:///db').create() + self.assertEqual(5, self.commands.update_cell(uuid0, disable=True)) + output = self.output.getvalue().strip() + self.assertEqual('Cell0 cannot be disabled.', output) + + def test_update_cell_disable_success(self): + ctxt = context.get_admin_context() + uuid = uuidsentinel.cell1 + objects.CellMapping(context=ctxt, uuid=uuid, + name='cell1', + transport_url='fake://mq', + database_connection='fake:///db').create() + cm = objects.CellMapping.get_by_uuid(ctxt, uuid) + self.assertFalse(cm.disabled) + self.assertEqual(0, self.commands.update_cell(uuid, disable=True)) + cm = objects.CellMapping.get_by_uuid(ctxt, uuid) + self.assertTrue(cm.disabled) + output = self.output.getvalue().strip() + self.assertEqual('', output) + + def test_update_cell_enable_success(self): + ctxt = context.get_admin_context() + uuid = uuidsentinel.cell1 + objects.CellMapping(context=ctxt, uuid=uuid, + name='cell1', + transport_url='fake://mq', + database_connection='fake:///db', + disabled=True).create() + cm = objects.CellMapping.get_by_uuid(ctxt, uuid) + self.assertTrue(cm.disabled) + self.assertEqual(0, self.commands.update_cell(uuid, enable=True)) + cm = objects.CellMapping.get_by_uuid(ctxt, uuid) + self.assertFalse(cm.disabled) + output = self.output.getvalue().strip() + self.assertEqual('', output) + + def test_update_cell_disable_already_disabled(self): + ctxt = context.get_admin_context() + objects.CellMapping(context=ctxt, uuid=uuidsentinel.cell1, + name='cell1', + transport_url='fake://mq', + database_connection='fake:///db', + disabled=True).create() + cm = objects.CellMapping.get_by_uuid(ctxt, uuidsentinel.cell1) + self.assertTrue(cm.disabled) + self.assertEqual(0, self.commands.update_cell(uuidsentinel.cell1, + disable=True)) + self.assertTrue(cm.disabled) + output = self.output.getvalue().strip() + self.assertIn('is already disabled', output) + + def test_update_cell_enable_already_enabled(self): + ctxt = context.get_admin_context() + objects.CellMapping(context=ctxt, uuid=uuidsentinel.cell1, + name='cell1', + transport_url='fake://mq', + database_connection='fake:///db').create() + cm = objects.CellMapping.get_by_uuid(ctxt, uuidsentinel.cell1) + self.assertFalse(cm.disabled) + self.assertEqual(0, self.commands.update_cell(uuidsentinel.cell1, + enable=True)) + self.assertFalse(cm.disabled) + output = self.output.getvalue().strip() + self.assertIn('is already enabled', output) + def test_list_hosts(self): ctxt = context.get_admin_context() # create the cell mapping diff --git a/releasenotes/notes/add-disabled-to-create_cell-feb1643ec4716eb2.yaml b/releasenotes/notes/add-disabled-to-create_cell-feb1643ec4716eb2.yaml index 2a59ba054fe0..0c3597f416de 100644 --- a/releasenotes/notes/add-disabled-to-create_cell-feb1643ec4716eb2.yaml +++ b/releasenotes/notes/add-disabled-to-create_cell-feb1643ec4716eb2.yaml @@ -4,3 +4,7 @@ features: A new option ``disabled`` has been added to nova-manage cell_v2 create_cell command by which users can create pre-disabled cells. Hence unless such cells are enabled, no VMs will be spawned on the hosts in these cells. + - | + Two new options ``--enable`` and ``--disable`` have been added to the + ``nova-manage cell_v2 update_cell`` command. Using these flags users can enable + or disable scheduling to a cell.