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

View File

@ -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='<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):
"""List hosts."""
@ -1444,7 +1246,6 @@ CATEGORIES = {
'logs': GetLogCommands,
'network': NetworkCommands,
'project': ProjectCommands,
'service': ServiceCommands,
'shell': ShellCommands,
'vm': VmCommands,
'vpn': VpnCommands,

View File

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

View File

@ -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()

View File

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