Create driver directories and prototype generic driver
Change-Id: I595d6b969acd53ecae3d28cec22fe152ca5d5ff7
This commit is contained in:
parent
8584b50f60
commit
df8671c65a
|
@ -0,0 +1,118 @@
|
|||
# Copyright 2017 Lenovo, Inc.
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""Accelerator base exception handling. """
|
||||
|
||||
import collections
|
||||
|
||||
from oslo_log import log as logging
|
||||
from oslo_serialization import jsonutils
|
||||
import six
|
||||
from six.moves import http_client
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _ensure_exception_kwargs_serializable(exc_class_name, kwargs):
|
||||
"""Ensure that kwargs are serializable
|
||||
|
||||
Ensure that all kwargs passed to exception constructor can be passed over
|
||||
RPC, by trying to convert them to JSON, or, as a last resort, to string.
|
||||
If it is not possible, unserializable kwargs will be removed, letting the
|
||||
receiver to handle the exception string as it is configured to.
|
||||
|
||||
:param exc_class_name: an AcceleratorException class name.
|
||||
:param kwargs: a dictionary of keyword arguments passed to the exception
|
||||
constructor.
|
||||
:returns: a dictionary of serializable keyword arguments.
|
||||
"""
|
||||
serializers = [(jsonutils.dumps, _('when converting to JSON')),
|
||||
(six.text_type, _('when converting to string'))]
|
||||
exceptions = collections.defaultdict(list)
|
||||
serializable_kwargs = {}
|
||||
for k, v in kwargs.items():
|
||||
for serializer, msg in serializers:
|
||||
try:
|
||||
serializable_kwargs[k] = serializer(v)
|
||||
exceptions.pop(k, None)
|
||||
break
|
||||
except Exception as e:
|
||||
exceptions[k].append(
|
||||
'(%(serializer_type)s) %(e_type)s: %(e_contents)s' %
|
||||
{'serializer_type': msg, 'e_contents': e,
|
||||
'e_type': e.__class__.__name__})
|
||||
if exceptions:
|
||||
LOG.error("One or more arguments passed to the %(exc_class)s "
|
||||
"constructor as kwargs can not be serialized. The "
|
||||
"serialized arguments: %(serialized)s. These "
|
||||
"unserialized kwargs were dropped because of the "
|
||||
"exceptions encountered during their "
|
||||
"serialization:\n%(errors)s",
|
||||
dict(errors=';\n'.join("%s: %s" % (k, '; '.join(v))
|
||||
for k, v in exceptions.items()),
|
||||
exc_class=exc_class_name,
|
||||
serialized=serializable_kwargs))
|
||||
# We might be able to actually put the following keys' values into
|
||||
# format string, but there is no guarantee, drop it just in case.
|
||||
for k in exceptions:
|
||||
del kwargs[k]
|
||||
return serializable_kwargs
|
||||
|
||||
|
||||
class AcceleratorException(Exception):
|
||||
"""Base Accelerator Exception
|
||||
|
||||
To correctly use this class, inherit from it and define
|
||||
a '_msg_fmt' property. That message will get printf'd
|
||||
with the keyword arguments provided to the constructor.
|
||||
|
||||
If you need to access the message from an exception you should use
|
||||
six.text_type(exc)
|
||||
|
||||
"""
|
||||
_msg_fmt = _("An unknown exception occurred.")
|
||||
code = http_client.INTERNAL_SERVER_ERROR
|
||||
headers = {}
|
||||
safe = False
|
||||
|
||||
def __init__(self, message=None, **kwargs):
|
||||
|
||||
self.kwargs = _ensure_exception_kwargs_serializable(
|
||||
self.__class__.__name__, kwargs)
|
||||
|
||||
if 'code' not in self.kwargs:
|
||||
try:
|
||||
self.kwargs['code'] = self.code
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
if not message:
|
||||
if kwargs:
|
||||
message = self._msg_fmt % kwargs
|
||||
else:
|
||||
message = self._msg_fmt
|
||||
|
||||
super(AcceleratorException, self).__init__(message)
|
||||
|
||||
|
||||
class Invalid(AcceleratorException):
|
||||
_msg_fmt = _("Unacceptable parameters.")
|
||||
|
||||
|
||||
class InvalidParameterValue(Invalid):
|
||||
_msg_fmt = "%(err)s"
|
||||
|
||||
|
||||
class MissingParameterValue(InvalidParameterValue):
|
||||
_msg_fmt = "%(err)s"
|
|
@ -0,0 +1,79 @@
|
|||
# Copyright 2017 Lenovo, Inc.
|
||||
#
|
||||
# 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.
|
||||
"""
|
||||
Abstract base classes for drivers.
|
||||
"""
|
||||
|
||||
import abc
|
||||
import six
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class BaseDriver(object):
|
||||
"""Base class for all drivers.
|
||||
|
||||
Defines the abstract base class for generic and vendor drivers.
|
||||
"""
|
||||
|
||||
standard_interfaces = ('discover', 'list', 'update', 'attach', 'detach')
|
||||
|
||||
discover = None
|
||||
"""`Standard` attribute for discovering drivers.
|
||||
|
||||
A reference to an instance of :class:DiscoverInterface.
|
||||
"""
|
||||
|
||||
list = None
|
||||
"""`Core` attribute for listing drivers.
|
||||
|
||||
A reference to an instance of :class:ListInterface.
|
||||
"""
|
||||
|
||||
update = None
|
||||
"""`Standard` attribute to update drivers.
|
||||
|
||||
A reference to an instance of :class:UpdateInterface.
|
||||
"""
|
||||
|
||||
attach = None
|
||||
"""`Standard` attribute to attach accelerator to an instance.
|
||||
|
||||
A reference to an instance of :class:AttachInterface.
|
||||
"""
|
||||
|
||||
detach = None
|
||||
"""`Standard` attribute to detach accelerator to an instance.
|
||||
|
||||
A reference to an instance of :class:AttachInterface.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
@property
|
||||
def all_interfaces(self):
|
||||
return (list(self.standard_interfaces))
|
||||
|
||||
def get_properties(self):
|
||||
"""Gets the properties of the driver.
|
||||
|
||||
:returns: dictionary of <property name>:<property description> entries.
|
||||
"""
|
||||
|
||||
properties = {}
|
||||
for iface_name in self.all_interfaces:
|
||||
iface = getattr(self, iface_name, None)
|
||||
if iface:
|
||||
properties.update(iface.get_properties())
|
||||
return properties
|
|
@ -0,0 +1,33 @@
|
|||
# Copyright 2017 Lenovo, Inc.
|
||||
#
|
||||
# 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.
|
||||
|
||||
|
||||
"""
|
||||
Cyborg Generic driver implementation.
|
||||
"""
|
||||
from modules import generic
|
||||
|
||||
|
||||
class GenericDriver(object):
|
||||
"""Abstract base class representing the generic driver for Cyborg.
|
||||
|
||||
This class provides a reference implementation for a Cyborg driver.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.discover = generic.discover()
|
||||
self.list = generic.list()
|
||||
self.update = generic.update
|
||||
self.attach = generic.attach()
|
||||
self.detach = generic.detach()
|
|
@ -0,0 +1,81 @@
|
|||
# Copyright 2017 Lenovo, Inc.
|
||||
#
|
||||
# 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.
|
||||
|
||||
|
||||
"""
|
||||
Cyborg Generic driver modules implementation.
|
||||
"""
|
||||
|
||||
from cyborg.accelerator.common import exception
|
||||
from cyborg.accelerator.drivers import base
|
||||
from oslo_log import log as logging
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
# TODO(crushil): REQUIRED_PROPERTIES needs to be filled out.
|
||||
REQUIRED_PROPERTIES = {}
|
||||
COMMON_PROPERTIES = REQUIRED_PROPERTIES
|
||||
|
||||
|
||||
def _check_for_missing_params(info_dict, error_msg, param_prefix=''):
|
||||
missing_info = []
|
||||
for label, value in info_dict.items():
|
||||
if not value:
|
||||
missing_info.append(param_prefix + label)
|
||||
|
||||
if missing_info:
|
||||
exc_msg = _("%(error_msg)s. Missing are: %(missing_info)s")
|
||||
raise exception.MissingParameterValue(
|
||||
exc_msg % {'error_msg': error_msg, 'missing_info': missing_info})
|
||||
|
||||
|
||||
def _parse_driver_info(driver):
|
||||
info = driver.driver_info
|
||||
d_info = {k: info.get(k) for k in COMMON_PROPERTIES}
|
||||
error_msg = _("Cannot validate Generic Driver. Some parameters were"
|
||||
" missing in the configuration file.")
|
||||
_check_for_missing_params(d_info, error_msg)
|
||||
return d_info
|
||||
|
||||
|
||||
class GENERICDRIVER(base.BaseDriver):
|
||||
|
||||
def get_properties(self):
|
||||
"""Return the properties of the generic driver.
|
||||
|
||||
:returns: dictionary of <property name>:<property description> entries.
|
||||
"""
|
||||
return COMMON_PROPERTIES
|
||||
|
||||
def attach(self):
|
||||
|
||||
def install(self):
|
||||
pass
|
||||
|
||||
def detach(self):
|
||||
|
||||
def uninstall(self):
|
||||
pass
|
||||
|
||||
def delete(self):
|
||||
pass
|
||||
|
||||
def discover(self):
|
||||
pass
|
||||
|
||||
def list(self):
|
||||
pass
|
||||
|
||||
def update(self):
|
||||
pass
|
Loading…
Reference in New Issue