From de4043d454aee7a61a46b9a6bf8eaa6922591cb3 Mon Sep 17 00:00:00 2001 From: Balazs Gibizer Date: Wed, 30 Mar 2016 12:43:47 +0200 Subject: [PATCH] Remove nova-manage service subcommand The novaclient already has the following service commands: service-disable Disable the service. service-enable Enable the service. service-list Show a list of all running services. host-describe Describe a specific host This covers what the serivce subcommand of nova-manage provides. Therefore the service subcommand was deprecated in 13.0 and now it is removed. Implements: bp remove-service-management-from-nova-manage Change-Id: If61875ec78e0e8cd78ea915d8da7362f502d4ca7 --- nova/cmd/manage.py | 199 ------------------ nova/tests/unit/cmd/test_manage.py | 47 ----- nova/tests/unit/test_nova_manage.py | 12 -- ...e-service-subcommand-2a11ed662864341c.yaml | 5 + 4 files changed, 5 insertions(+), 258 deletions(-) delete mode 100644 nova/tests/unit/cmd/test_manage.py create mode 100644 releasenotes/notes/remove-nova-manage-service-subcommand-2a11ed662864341c.yaml diff --git a/nova/cmd/manage.py b/nova/cmd/manage.py index 292da2f8ec88..c5ad84ec55f9 100644 --- a/nova/cmd/manage.py +++ b/nova/cmd/manage.py @@ -82,7 +82,6 @@ from nova import objects from nova.objects import flavor as flavor_obj from nova import quota from nova import rpc -from nova import servicegroup from nova import utils from nova import version @@ -104,17 +103,6 @@ def args(*args, **kwargs): return _decorator -def deprecate(msg): - """Decorator which print the deprecation message before the decorated - function is called - """ - @decorator.decorator - def _deprecate(f, *args, **kwargs): - print(msg, file=sys.stderr) - return f(*args, **kwargs) - return _deprecate - - def param2id(object_id): """Helper function to convert various volume id types to internal id. args: [object_id], e.g. 'vol-0000000a' or 'volume-0000000a' or '10' @@ -706,192 +694,6 @@ class VmCommands(object): instance.launch_index or 0))) -class ServiceCommands(object): - """Enable and disable running services.""" - - description = ('DEPRECATED: Use the nova service-* commands from ' - 'python-novaclient instead or the os-services REST ' - 'resource. The service subcommand will be ' - 'removed in the 14.0 release.') - - @deprecate(description) - @args('--host', metavar='', help='Host') - @args('--service', metavar='', help='Nova service') - def list(self, host=None, service=None): - """Show a list of all running services. Filter by host & service - name - """ - servicegroup_api = servicegroup.API() - ctxt = context.get_admin_context() - services = db.service_get_all(ctxt) - services = availability_zones.set_availability_zones(ctxt, services) - if host: - services = [s for s in services if s['host'] == host] - if service: - services = [s for s in services if s['binary'] == service] - print_format = "%-16s %-36s %-16s %-10s %-5s %-10s" - print(print_format % ( - _('Binary'), - _('Host'), - _('Zone'), - _('Status'), - _('State'), - _('Updated_At'))) - for svc in services: - alive = servicegroup_api.service_is_up(svc) - art = (alive and ":-)") or "XXX" - active = 'enabled' - if svc['disabled']: - active = 'disabled' - print(print_format % (svc['binary'], svc['host'], - svc['availability_zone'], active, art, - svc['updated_at'])) - - @deprecate(description) - @args('--host', metavar='', help='Host') - @args('--service', metavar='', help='Nova service') - def enable(self, host, service): - """Enable scheduling for a service.""" - ctxt = context.get_admin_context() - try: - svc = db.service_get_by_host_and_binary(ctxt, host, service) - db.service_update(ctxt, svc['id'], {'disabled': False}) - except exception.NotFound as ex: - print(_("error: %s") % ex) - return(2) - print((_("Service %(service)s on host %(host)s enabled.") % - {'service': service, 'host': host})) - - @deprecate(description) - @args('--host', metavar='', help='Host') - @args('--service', metavar='', help='Nova service') - def disable(self, host, service): - """Disable scheduling for a service.""" - ctxt = context.get_admin_context() - try: - svc = db.service_get_by_host_and_binary(ctxt, host, service) - db.service_update(ctxt, svc['id'], {'disabled': True}) - except exception.NotFound as ex: - print(_("error: %s") % ex) - return(2) - print((_("Service %(service)s on host %(host)s disabled.") % - {'service': service, 'host': host})) - - def _show_host_resources(self, context, host): - """Shows the physical/usage resource given by hosts. - - :param context: security context - :param host: hostname - :returns: - example format is below:: - - {'resource':D, 'usage':{proj_id1:D, proj_id2:D}} - D: {'vcpus': 3, 'memory_mb': 2048, 'local_gb': 2048, - 'vcpus_used': 12, 'memory_mb_used': 10240, - 'local_gb_used': 64} - - """ - # Getting compute node info and related instances info - compute_ref = ( - objects.ComputeNode.get_first_node_by_host_for_old_compat(context, - host)) - instance_refs = db.instance_get_all_by_host(context, host) - - # Getting total available/used resource - resource = {'vcpus': compute_ref.vcpus, - 'memory_mb': compute_ref.memory_mb, - 'local_gb': compute_ref.local_gb, - 'vcpus_used': compute_ref.vcpus_used, - 'memory_mb_used': compute_ref.memory_mb_used, - 'local_gb_used': compute_ref.local_gb_used} - usage = dict() - if not instance_refs: - return {'resource': resource, 'usage': usage} - - # Getting usage resource per project - project_ids = [i['project_id'] for i in instance_refs] - project_ids = list(set(project_ids)) - for project_id in project_ids: - vcpus = [i['vcpus'] for i in instance_refs - if i['project_id'] == project_id] - - mem = [i['memory_mb'] for i in instance_refs - if i['project_id'] == project_id] - - root = [i['root_gb'] for i in instance_refs - if i['project_id'] == project_id] - - ephemeral = [i['ephemeral_gb'] for i in instance_refs - if i['project_id'] == project_id] - - usage[project_id] = {'vcpus': sum(vcpus), - 'memory_mb': sum(mem), - 'root_gb': sum(root), - 'ephemeral_gb': sum(ephemeral)} - - return {'resource': resource, 'usage': usage} - - @deprecate(description) - @args('--host', metavar='', help='Host') - def describe_resource(self, host): - """Describes cpu/memory/hdd info for host. - - :param host: hostname. - - """ - try: - result = self._show_host_resources(context.get_admin_context(), - host=host) - except exception.NovaException as ex: - print(_("error: %s") % ex) - return 2 - - if not isinstance(result, dict): - print(_('An unexpected error has occurred.')) - print(_('[Result]'), result) - else: - # Printing a total and used_now - # (NOTE)The host name width 16 characters - print('%(a)-25s%(b)16s%(c)8s%(d)8s%(e)8s' % {"a": _('HOST'), - "b": _('PROJECT'), - "c": _('cpu'), - "d": _('mem(mb)'), - "e": _('hdd')}) - print(('%(a)-16s(total)%(b)26s%(c)8s%(d)8s' % - {"a": host, - "b": result['resource']['vcpus'], - "c": result['resource']['memory_mb'], - "d": result['resource']['local_gb']})) - - print(('%(a)-16s(used_now)%(b)23s%(c)8s%(d)8s' % - {"a": host, - "b": result['resource']['vcpus_used'], - "c": result['resource']['memory_mb_used'], - "d": result['resource']['local_gb_used']})) - - # Printing a used_max - cpu_sum = 0 - mem_sum = 0 - hdd_sum = 0 - for p_id, val in result['usage'].items(): - cpu_sum += val['vcpus'] - mem_sum += val['memory_mb'] - hdd_sum += val['root_gb'] - hdd_sum += val['ephemeral_gb'] - print('%(a)-16s(used_max)%(b)23s%(c)8s%(d)8s' % {"a": host, - "b": cpu_sum, - "c": mem_sum, - "d": hdd_sum}) - - for p_id, val in result['usage'].items(): - print('%(a)-25s%(b)16s%(c)8s%(d)8s%(e)8s' % { - "a": host, - "b": p_id, - "c": val['vcpus'], - "d": val['memory_mb'], - "e": val['root_gb'] + val['ephemeral_gb']}) - - class HostCommands(object): """List hosts.""" @@ -1444,7 +1246,6 @@ CATEGORIES = { 'logs': GetLogCommands, 'network': NetworkCommands, 'project': ProjectCommands, - 'service': ServiceCommands, 'shell': ShellCommands, 'vm': VmCommands, 'vpn': VpnCommands, diff --git a/nova/tests/unit/cmd/test_manage.py b/nova/tests/unit/cmd/test_manage.py deleted file mode 100644 index 3923b58a07d7..000000000000 --- a/nova/tests/unit/cmd/test_manage.py +++ /dev/null @@ -1,47 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import mock - -from nova.cmd import manage -from nova import objects -from nova import test - - -class ServiceCommandsTestCase(test.NoDBTestCase): - - def setUp(self): - super(ServiceCommandsTestCase, self).setUp() - self.svc_cmds = manage.ServiceCommands() - - @mock.patch('nova.db.instance_get_all_by_host') - @mock.patch.object(objects.ComputeNode, - 'get_first_node_by_host_for_old_compat') - def test__show_host_resources(self, mock_cn_get, mock_inst_get): - resources = {'vcpus': 4, - 'memory_mb': 65536, - 'local_gb': 100, - 'vcpus_used': 1, - 'memory_mb_used': 16384, - 'local_gb_used': 20} - mock_cn_get.return_value = objects.ComputeNode(**resources) - mock_inst_get.return_value = [] - - result = self.svc_cmds._show_host_resources(mock.sentinel.ctxt, - mock.sentinel.host) - - mock_cn_get.assert_called_once_with(mock.sentinel.ctxt, - mock.sentinel.host) - mock_inst_get.assert_called_once_with(mock.sentinel.ctxt, - mock.sentinel.host) - self.assertEqual(resources, result['resource']) - self.assertEqual({}, result['usage']) diff --git a/nova/tests/unit/test_nova_manage.py b/nova/tests/unit/test_nova_manage.py index e473a5b2cedc..5984e5443d5c 100644 --- a/nova/tests/unit/test_nova_manage.py +++ b/nova/tests/unit/test_nova_manage.py @@ -556,18 +556,6 @@ class ApiDbCommandsTestCase(test.NoDBTestCase): sqla_sync.assert_called_once_with(version=4, database='api') -class ServiceCommandsTestCase(test.TestCase): - def setUp(self): - super(ServiceCommandsTestCase, self).setUp() - self.commands = manage.ServiceCommands() - - def test_service_enable_invalid_params(self): - self.assertEqual(2, self.commands.enable('nohost', 'noservice')) - - def test_service_disable_invalid_params(self): - self.assertEqual(2, self.commands.disable('nohost', 'noservice')) - - class CellCommandsTestCase(test.NoDBTestCase): def setUp(self): super(CellCommandsTestCase, self).setUp() diff --git a/releasenotes/notes/remove-nova-manage-service-subcommand-2a11ed662864341c.yaml b/releasenotes/notes/remove-nova-manage-service-subcommand-2a11ed662864341c.yaml new file mode 100644 index 000000000000..8010e9354332 --- /dev/null +++ b/releasenotes/notes/remove-nova-manage-service-subcommand-2a11ed662864341c.yaml @@ -0,0 +1,5 @@ +--- +features: + - The service subcommand of nova-manage was deprecated in 13.0. Now in 14.0 + the service subcommand is removed. Use service-* commands from + python-novaclient or the os-services REST resource instead.