nova/nova/compute/resources/__init__.py

134 lines
4.8 KiB
Python

# Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
# 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.
import stevedore
from nova.i18n import _LW
from nova.openstack.common import log as logging
LOG = logging.getLogger(__name__)
RESOURCE_NAMESPACE = 'nova.compute.resources'
class ResourceHandler(object):
def _log_missing_plugins(self, names):
for name in names:
if name not in self._mgr.names():
LOG.warning(_LW('Compute resource plugin %s was not loaded'),
name)
def __init__(self, names, propagate_map_exceptions=False):
"""Initialise the resource handler by loading the plugins.
The ResourceHandler uses stevedore to load the resource plugins.
The handler can handle and report exceptions raised in the plugins
depending on the value of the propagate_map_exceptions parameter.
It is useful in testing to propagate exceptions so they are exposed
as part of the test. If exceptions are not propagated they are
logged at error level.
Any named plugins that are not located are logged.
:param names: the list of plugins to load by name
:param propagate_map_exceptions: True indicates exceptions in the
plugins should be raised, False indicates they should be handled and
logged.
"""
self._mgr = stevedore.NamedExtensionManager(
namespace=RESOURCE_NAMESPACE,
names=names,
propagate_map_exceptions=propagate_map_exceptions,
invoke_on_load=True)
self._log_missing_plugins(names)
def reset_resources(self, resources, driver):
"""Reset the resources to their initial state.
Each plugin is called to reset its state. The resources data provided
is initial state gathered from the hypervisor. The driver is also
provided in case the plugin needs to obtain additional information
from the driver, for example, the memory calculation obtains
the memory overhead from the driver.
:param resources: the resources reported by the hypervisor
:param driver: the driver for the hypervisor
:returns: None
"""
if self._mgr.extensions:
self._mgr.map_method('reset', resources, driver)
def test_resources(self, usage, limits):
"""Test the ability to support the given instance.
Each resource plugin is called to determine if it's resource is able
to support the additional requirements of a new instance. The
plugins either return None to indicate they have sufficient resource
available or a human readable string to indicate why they can not.
:param usage: the additional resource usage
:param limits: limits used for the calculation
:returns: a list or return values from the plugins
"""
if not self._mgr.extensions:
return []
reasons = self._mgr.map_method('test', usage, limits)
return reasons
def update_from_instance(self, usage, sign=1):
"""Update the resource information to reflect the allocation for
an instance with the given resource usage.
:param usage: the resource usage of the instance
:param sign: has value 1 or -1. 1 indicates the instance is being
added to the current usage, -1 indicates the instance is being removed.
:returns: None
"""
if not self._mgr.extensions:
return
if sign == 1:
self._mgr.map_method('add_instance', usage)
else:
self._mgr.map_method('remove_instance', usage)
def write_resources(self, resources):
"""Write the resource data to populate the resources.
Each resource plugin is called to write its resource data to
resources.
:param resources: the compute node resources
:returns: None
"""
if self._mgr.extensions:
self._mgr.map_method('write', resources)
def report_free_resources(self):
"""Each resource plugin is called to log free resource information.
:returns: None
"""
if not self._mgr.extensions:
return
self._mgr.map_method('report_free')