Remove unused nova related code

We don't interface with nova anymore. Remove all novaclient related
code. Also, remove python-novaclient from requirements.

Partial-Bug: #1765962
Change-Id: Iac144061792c2e9988690565c4c8578dd47b3809
This commit is contained in:
Hongbin Lu 2018-04-20 02:43:26 +00:00
parent c4507a2586
commit fb3af49462
7 changed files with 1 additions and 324 deletions

View File

@ -120,7 +120,6 @@ python-glanceclient==2.8.0
python-keystoneclient==3.15.0
python-mimeparse==1.6.0
python-neutronclient==6.7.0
python-novaclient==9.1.0
python-subunit==1.2.0
pytz==2018.3
PyYAML==3.12

View File

@ -11,7 +11,6 @@ pecan!=1.0.2,!=1.0.3,!=1.0.4,!=1.2,>=1.0.0 # BSD
python-etcd>=0.4.3 # MIT License
python-glanceclient>=2.8.0 # Apache-2.0
python-neutronclient>=6.7.0 # Apache-2.0
python-novaclient>=9.1.0 # Apache-2.0
python-cinderclient>=3.3.0 # Apache-2.0
oslo.i18n>=3.15.3 # Apache-2.0
oslo.log>=3.36.0 # Apache-2.0

View File

@ -15,7 +15,6 @@
from cinderclient import client as cinderclient
from glanceclient import client as glanceclient
from neutronclient.v2_0 import client as neutronclient
from novaclient import client as novaclient
from zun.common import exception
from zun.common import keystone
@ -29,7 +28,6 @@ class OpenStackClients(object):
self.context = context
self._keystone = None
self._glance = None
self._nova = None
self._neutron = None
self._cinder = None
@ -87,17 +85,6 @@ class OpenStackClients(object):
return self._glance
@exception.wrap_keystone_exception
def nova(self):
if self._nova:
return self._nova
nova_api_version = self._get_client_option('nova', 'api_version')
session = self.keystone().session
self._nova = novaclient.Client(nova_api_version, session=session)
return self._nova
@exception.wrap_keystone_exception
def neutron(self):
if self._neutron:

View File

@ -1,255 +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 requests
import six
from novaclient import exceptions
from oslo_log import log as logging
from oslo_utils import excutils
from oslo_utils import uuidutils
from zun.common import clients
from zun.common import exception
from zun.common.i18n import _
LOG = logging.getLogger(__name__)
def retry_if_connection_err(exception):
return isinstance(exception, requests.ConnectionError)
class NovaClient(object):
deferred_server_statuses = ['BUILD',
'HARD_REBOOT',
'PASSWORD',
'REBOOT',
'RESCUE',
'RESIZE',
'REVERT_RESIZE',
'SHUTOFF',
'SUSPENDED',
'VERIFY_RESIZE']
def __init__(self, context):
self.context = context
self._client = None
def client(self):
if not self._client:
self._client = clients.OpenStackClients(self.context).nova()
return self._client
def is_not_found(self, ex):
return isinstance(ex, exceptions.NotFound)
def create_server(self, name, image, flavor, **kwargs):
image = self.get_image_by_name_or_id(image)
flavor = self.get_flavor_by_name_or_id(flavor)
return self.client().servers.create(name, image, flavor, **kwargs)
def get_image_by_name_or_id(self, image_ident):
"""Get an image by name or ID."""
try:
return self.client().glance.find_image(image_ident)
except exceptions.NotFound as e:
raise exception.ImageNotFound(six.text_type(e))
except exceptions.NoUniqueMatch as e:
raise exception.Conflict(six.text_type(e))
def get_flavor_by_name_or_id(self, flavor_ident):
"""Get the flavor object for the specified flavor name or id.
:param flavor_identifier: the name or id of the flavor to find
:returns: a flavor object with name or id :flavor:
"""
try:
flavor = self.client().flavors.get(flavor_ident)
except exceptions.NotFound:
flavor = self.client().flavors.find(name=flavor_ident)
return flavor
def fetch_server(self, server_id):
"""Fetch fresh server object from Nova.
Log warnings and return None for non-critical API errors.
Use this method in various ``check_*_complete`` resource methods,
where intermittent errors can be tolerated.
"""
server = None
try:
server = self.client().servers.get(server_id)
except exceptions.OverLimit as exc:
LOG.warning("Received an OverLimit response when "
"fetching server (%(id)s) : %(exception)s",
{'id': server_id,
'exception': exc})
except exceptions.ClientException as exc:
if ((getattr(exc, 'http_status', getattr(exc, 'code', None)) in
(500, 503))):
LOG.warning("Received the following exception when "
"fetching server (%(id)s) : %(exception)s",
{'id': server_id,
'exception': exc})
else:
raise
return server
def refresh_server(self, server):
"""Refresh server's attributes.
Also log warnings for non-critical API errors.
"""
try:
server.get()
except exceptions.OverLimit as exc:
LOG.warning("Server %(name)s (%(id)s) received an OverLimit "
"response during server.get(): %(exception)s",
{'name': server.name,
'id': server.id,
'exception': exc})
except exceptions.ClientException as exc:
if ((getattr(exc, 'http_status', getattr(exc, 'code', None)) in
(500, 503))):
LOG.warning('Server "%(name)s" (%(id)s) received the '
'following exception during server.get(): '
'%(exception)s',
{'name': server.name,
'id': server.id,
'exception': exc})
else:
raise
def get_status(self, server):
"""Return the server's status.
:param server: server object
:returns: status as a string
"""
# Some clouds append extra (STATUS) strings to the status, strip it
return server.status.split('(')[0]
def check_active(self, server):
"""Check server status.
Accepts both server IDs and server objects.
Returns True if server is ACTIVE,
raises errors when server has an ERROR or unknown to Zun status,
returns False otherwise.
"""
# not checking with is_uuid_like as most tests use strings e.g. '1234'
if isinstance(server, six.string_types):
server = self.fetch_server(server)
if server is None:
return False
else:
status = self.get_status(server)
else:
status = self.get_status(server)
if status != 'ACTIVE':
self.refresh_server(server)
status = self.get_status(server)
if status in self.deferred_server_statuses:
return False
elif status == 'ACTIVE':
return True
elif status == 'ERROR':
fault = getattr(server, 'fault', {})
raise exception.ServerInError(
resource_status=status,
status_reason=_("Message: %(message)s, Code: %(code)s") % {
'message': fault.get('message', _('Unknown')),
'code': fault.get('code', _('Unknown'))
})
else:
raise exception.ServerUnknownStatus(
resource_status=server.status,
status_reason=_('Unknown'),
result=_('Server is not active'))
def delete_server(self, server):
server_id = self.get_server_id(server, raise_on_error=False)
if server_id:
self.client().servers.delete(server_id)
return server_id
def stop_server(self, server):
server_id = self.get_server_id(server, raise_on_error=False)
if server_id:
self.client().servers.stop(server_id)
return server_id
def check_delete_server_complete(self, server_id):
"""Wait for server to disappear from Nova."""
try:
server = self.fetch_server(server_id)
except Exception as exc:
self.ignore_not_found(exc)
return True
if not server:
return False
task_state_in_nova = getattr(server, 'OS-EXT-STS:task_state', None)
# the status of server won't change until the delete task has done
if task_state_in_nova == 'deleting':
return False
status = self.get_status(server)
if status in ("DELETED", "SOFT_DELETED"):
return True
if status == 'ERROR':
fault = getattr(server, 'fault', {})
message = fault.get('message', 'Unknown')
code = fault.get('code')
errmsg = _("Server %(name)s delete failed: (%(code)s) "
"%(message)s") % dict(name=server.name,
code=code,
message=message)
raise exception.ServerInError(resource_status=status,
status_reason=errmsg)
return False
@excutils.exception_filter
def ignore_not_found(self, ex):
"""Raises the exception unless it is a not-found."""
return self.is_not_found(ex)
def get_addresses(self, server):
"""Return the server's IP address, fetching it from Nova."""
try:
server_id = self.get_server_id(server)
server = self.client().servers.get(server_id)
except exceptions.NotFound as ex:
LOG.warning('Instance (%(server)s) not found: %(ex)s',
{'server': server, 'ex': ex})
else:
return server.addresses
def get_server_id(self, server, raise_on_error=True):
if uuidutils.is_uuid_like(server):
return server
elif isinstance(server, six.string_types):
servers = self.client().servers.list(search_opts={'name': server})
if len(servers) == 1:
return servers[0].id
if raise_on_error:
raise exception.ZunException(_(
"Unable to get server id with name %s") % server)
else:
raise exception.ZunException(_("Unexpected server type"))

View File

@ -27,7 +27,6 @@ from zun.conf import keystone
from zun.conf import netconf
from zun.conf import network
from zun.conf import neutron_client
from zun.conf import nova_client
from zun.conf import path
from zun.conf import pci
from zun.conf import profiler
@ -49,7 +48,6 @@ docker.register_opts(CONF)
glance_client.register_opts(CONF)
image_driver.register_opts(CONF)
keystone.register_opts(CONF)
nova_client.register_opts(CONF)
path.register_opts(CONF)
scheduler.register_opts(CONF)
services.register_opts(CONF)

View File

@ -1,51 +0,0 @@
# -*- encoding: utf-8 -*-
#
# Copyright © 2012 eNovance <licensing@enovance.com>
#
# 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.
from oslo_config import cfg
nova_group = cfg.OptGroup(name='nova_client',
title='Options for the Nova client')
common_security_opts = [
cfg.StrOpt('ca_file',
help='Optional CA cert file to use in SSL connections.'),
cfg.StrOpt('cert_file',
help='Optional PEM-formatted certificate chain file.'),
cfg.StrOpt('key_file',
help='Optional PEM-formatted file that contains the '
'private key.'),
cfg.BoolOpt('insecure',
default=False,
help="If set, then the server's certificate will not "
"be verified.")]
nova_client_opts = [
cfg.StrOpt('api_version',
default='2.37',
help='Version of Nova API to use in novaclient.')]
ALL_OPTS = (nova_client_opts + common_security_opts)
def register_opts(conf):
conf.register_group(nova_group)
conf.register_opts(ALL_OPTS, group=nova_group)
def list_opts():
return {nova_group: ALL_OPTS}

View File

@ -22,7 +22,7 @@ Guidelines for writing new hacking checks
should be submitted to the common 'hacking' module.
- Pick numbers in the range Z3xx. Find the current test with
the highest allocated number and then pick the next value.
If nova has an N3xx code for that test, use the same number.
If zun has an N3xx code for that test, use the same number.
- Keep the test method code in the source file ordered based
on the Z3xx value.
- List the new rule in the top level HACKING.rst file