nova/nova/compute/monitors/__init__.py

94 lines
3.9 KiB
Python

# Copyright 2013 Intel Corporation.
# All Rights Reserved.
#
# 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.
"""
Resource monitor API specification.
"""
from oslo_log import log as logging
from stevedore import enabled
import nova.conf
CONF = nova.conf.CONF
LOG = logging.getLogger(__name__)
class MonitorHandler(object):
NAMESPACES = [
'nova.compute.monitors.cpu',
]
def __init__(self, resource_tracker):
# Dictionary keyed by the monitor type namespace. Value is the
# first loaded monitor of that namespace or False.
self.type_monitor_loaded = {ns: False for ns in self.NAMESPACES}
self.monitors = []
for ns in self.NAMESPACES:
plugin_mgr = enabled.EnabledExtensionManager(
namespace=ns,
invoke_on_load=True,
check_func=self.check_enabled_monitor,
invoke_args=(resource_tracker,)
)
self.monitors += [ext.obj for ext in plugin_mgr]
def check_enabled_monitor(self, ext):
"""Ensures that only one monitor is specified of any type."""
# The extension does not have a namespace attribute, unfortunately,
# but we can get the namespace by examining the first part of the
# entry_point_target attribute, which looks like this:
# 'nova.compute.monitors.cpu.virt_driver:Monitor'
ept = ext.entry_point_target
ept_parts = ept.split(':')
namespace_parts = ept_parts[0].split('.')
namespace = '.'.join(namespace_parts[0:-1])
if self.type_monitor_loaded[namespace] is not False:
LOG.warning("Excluding %(namespace)s monitor "
"%(monitor_name)s. Already loaded "
"%(loaded_monitor)s.",
{'namespace': namespace,
'monitor_name': ext.name,
'loaded_monitor': self.type_monitor_loaded[namespace]
})
return False
# NOTE(jaypipes): We used to only have CPU monitors, so
# CONF.compute_monitors could contain "virt_driver" without any monitor
# type namespace. So, to maintain backwards-compatibility with that
# older way of specifying monitors, we first loop through any values in
# CONF.compute_monitors and put any non-namespace'd values into the
# 'cpu' namespace.
cfg_monitors = ['cpu.' + cfg if '.' not in cfg else cfg
for cfg in CONF.compute_monitors]
# NOTE(jaypipes): Append 'nova.compute.monitors.' to any monitor value
# that doesn't have it to allow CONF.compute_monitors to use shortened
# namespaces (like 'cpu.' instead of 'nova.compute.monitors.cpu.')
cfg_monitors = ['nova.compute.monitors.' + cfg
if 'nova.compute.monitors.' not in cfg else cfg
for cfg in cfg_monitors]
if namespace + '.' + ext.name in cfg_monitors:
self.type_monitor_loaded[namespace] = ext.name
return True
# Only log something if compute_monitors is not empty.
if CONF.compute_monitors:
LOG.warning("Excluding %(namespace)s monitor %(monitor_name)s. "
"Not in the list of enabled monitors "
"(CONF.compute_monitors).",
{'namespace': namespace, 'monitor_name': ext.name})
return False