
The HostInfo object reports information about all plugins installed on the host and which vif types they support. When configuring a port for a particular instance though, the service host may only support a subset of vif types. For example, if the VM does not have shared memory, or is not using virtio-net, then it is not possible to use the vhostuser VIF type. Thus users of os-vif need to be able to filter the HostInfo data to restrict to to the subset of vif types that are actually usable in the particular usage scenario. Rather than having the compute node pass across an arbitary set of information to os-vif, to have it do filtering in the os_vif.host_info() method, add an API that lets Nova filter the host info explicitly. For example, when configuring a instance's port Nova would do supported_vif_types = ["VIFBridge", "VIFOpenVSwitch"] if ...instance has shared memory and QEMU > 2.1.0... supported_vif_types.append("VIFVHostUser") host_info = os_vif.host_info(supported_vif_types) Change-Id: I1f8c8ae49b767b7684f60cd9cac153fc9ab42088
151 lines
5.3 KiB
Python
151 lines
5.3 KiB
Python
# 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_log import log as logging
|
|
from stevedore import extension
|
|
|
|
import os_vif.exception
|
|
import os_vif.i18n
|
|
import os_vif.objects
|
|
|
|
_LE = os_vif.i18n._LE
|
|
_LI = os_vif.i18n._LI
|
|
|
|
_EXT_MANAGER = None
|
|
LOG = logging.getLogger(__name__)
|
|
|
|
|
|
def initialize(reset=False):
|
|
"""
|
|
Loads all os_vif plugins and initializes them with a dictionary of
|
|
configuration options. These configuration options are passed as-is
|
|
to the individual VIF plugins that are loaded via stevedore.
|
|
|
|
:param reset: Recreate and load the VIF plugin extensions.
|
|
|
|
"""
|
|
global _EXT_MANAGER
|
|
if _EXT_MANAGER is None:
|
|
os_vif.objects.register_all()
|
|
|
|
if reset or (_EXT_MANAGER is None):
|
|
_EXT_MANAGER = extension.ExtensionManager(namespace='os_vif',
|
|
invoke_on_load=False)
|
|
loaded_plugins = []
|
|
for plugin_name in _EXT_MANAGER.names():
|
|
cls = _EXT_MANAGER[plugin_name].plugin
|
|
obj = cls.load(plugin_name)
|
|
LOG.debug(("Loaded VIF plugin class '%(cls)s' "
|
|
"with name '%(plugin_name)s'"),
|
|
{'cls': cls, 'plugin_name': plugin_name})
|
|
loaded_plugins.append(plugin_name)
|
|
_EXT_MANAGER[plugin_name].obj = obj
|
|
LOG.info(_LI("Loaded VIF plugins: %s"), ", ".join(loaded_plugins))
|
|
|
|
|
|
def plug(vif, instance_info):
|
|
"""
|
|
Given a model of a VIF, perform operations to plug the VIF properly.
|
|
|
|
:param vif: `os_vif.objects.VIF` object.
|
|
:param instance_info: `os_vif.objects.InstanceInfo` object.
|
|
:raises `exception.LibraryNotInitialized` if the user of the library
|
|
did not call os_vif.initialize(**config) before trying to
|
|
plug a VIF.
|
|
:raises `exception.NoMatchingPlugin` if there is no plugin for the
|
|
type of VIF supplied.
|
|
:raises `exception.PlugException` if anything fails during unplug
|
|
operations.
|
|
"""
|
|
if _EXT_MANAGER is None:
|
|
raise os_vif.exception.LibraryNotInitialized()
|
|
|
|
plugin_name = vif.plugin
|
|
try:
|
|
plugin = _EXT_MANAGER[plugin_name].obj
|
|
except KeyError:
|
|
raise os_vif.exception.NoMatchingPlugin(plugin_name=plugin_name)
|
|
|
|
try:
|
|
LOG.debug("Plugging vif %s", vif)
|
|
plugin.plug(vif, instance_info)
|
|
LOG.info(_LI("Successfully plugged vif %s"), vif)
|
|
except Exception as err:
|
|
LOG.error(_LE("Failed to plug vif %(vif)s"),
|
|
{"vif": vif}, exc_info=True)
|
|
raise os_vif.exception.PlugException(vif=vif, err=err)
|
|
|
|
|
|
def unplug(vif, instance_info):
|
|
"""
|
|
Given a model of a VIF, perform operations to unplug the VIF properly.
|
|
|
|
:param vif: `os_vif.objects.VIF` object.
|
|
:param instance_info: `os_vif.objects.InstanceInfo` object.
|
|
:raises `exception.LibraryNotInitialized` if the user of the library
|
|
did not call os_vif.initialize(**config) before trying to
|
|
plug a VIF.
|
|
:raises `exception.NoMatchingPlugin` if there is no plugin for the
|
|
type of VIF supplied.
|
|
:raises `exception.UnplugException` if anything fails during unplug
|
|
operations.
|
|
"""
|
|
if _EXT_MANAGER is None:
|
|
raise os_vif.exception.LibraryNotInitialized()
|
|
|
|
plugin_name = vif.plugin
|
|
try:
|
|
plugin = _EXT_MANAGER[plugin_name].obj
|
|
except KeyError:
|
|
raise os_vif.exception.NoMatchingPlugin(plugin_name=plugin_name)
|
|
|
|
try:
|
|
LOG.debug("Unplugging vif %s", vif)
|
|
plugin.unplug(vif, instance_info)
|
|
LOG.info(_LI("Successfully unplugged vif %s"), vif)
|
|
except Exception as err:
|
|
LOG.error(_LE("Failed to unplug vif %(vif)s"),
|
|
{"vif": vif}, exc_info=True)
|
|
raise os_vif.exception.UnplugException(vif=vif, err=err)
|
|
|
|
|
|
def host_info(permitted_vif_type_names=None):
|
|
"""
|
|
:param permitted_vif_type_names: list of VIF object names
|
|
|
|
Get information about the host platform configuration to be
|
|
provided to the network manager. This will include information
|
|
about what plugins are installed in the host
|
|
|
|
If permitted_vif_type_names is not None, the returned HostInfo
|
|
will be filtered such that it only includes plugins which
|
|
support one of the listed VIF types. This allows the caller
|
|
to filter out impls which are not compatible with the current
|
|
usage configuration. For example, to remove VIFVHostUser if
|
|
the guest does not support shared memory.
|
|
|
|
:returns: a os_vif.host_info.HostInfo class instance
|
|
"""
|
|
|
|
if _EXT_MANAGER is None:
|
|
raise os_vif.exception.LibraryNotInitialized()
|
|
|
|
plugins = [
|
|
_EXT_MANAGER[name].obj.describe()
|
|
for name in sorted(_EXT_MANAGER.names())
|
|
]
|
|
|
|
info = os_vif.objects.host_info.HostInfo(plugin_info=plugins)
|
|
if permitted_vif_type_names is not None:
|
|
info.filter_vif_types(permitted_vif_type_names)
|
|
return info
|