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
This commit is contained in:
Balazs Gibizer 2016-03-30 12:43:47 +02:00
parent 68a4b4729a
commit de4043d454
4 changed files with 5 additions and 258 deletions

@ -82,7 +82,6 @@ from nova import objects
from nova.objects import flavor as flavor_obj from nova.objects import flavor as flavor_obj
from nova import quota from nova import quota
from nova import rpc from nova import rpc
from nova import servicegroup
from nova import utils from nova import utils
from nova import version from nova import version
@ -104,17 +103,6 @@ def args(*args, **kwargs):
return _decorator 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): def param2id(object_id):
"""Helper function to convert various volume id types to internal id. """Helper function to convert various volume id types to internal id.
args: [object_id], e.g. 'vol-0000000a' or 'volume-0000000a' or '10' args: [object_id], e.g. 'vol-0000000a' or 'volume-0000000a' or '10'
@ -706,192 +694,6 @@ class VmCommands(object):
instance.launch_index or 0))) 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='<host>', help='Host')
@args('--service', metavar='<service>', 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='<host>', help='Host')
@args('--service', metavar='<service>', 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='<host>', help='Host')
@args('--service', metavar='<service>', 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='<host>', 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): class HostCommands(object):
"""List hosts.""" """List hosts."""
@ -1444,7 +1246,6 @@ CATEGORIES = {
'logs': GetLogCommands, 'logs': GetLogCommands,
'network': NetworkCommands, 'network': NetworkCommands,
'project': ProjectCommands, 'project': ProjectCommands,
'service': ServiceCommands,
'shell': ShellCommands, 'shell': ShellCommands,
'vm': VmCommands, 'vm': VmCommands,
'vpn': VpnCommands, 'vpn': VpnCommands,

@ -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'])

@ -556,18 +556,6 @@ class ApiDbCommandsTestCase(test.NoDBTestCase):
sqla_sync.assert_called_once_with(version=4, database='api') 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): class CellCommandsTestCase(test.NoDBTestCase):
def setUp(self): def setUp(self):
super(CellCommandsTestCase, self).setUp() super(CellCommandsTestCase, self).setUp()

@ -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.