From 9fdcae9ea943a690b1eaf2d08ef63f710436f749 Mon Sep 17 00:00:00 2001 From: Dina Belova Date: Wed, 8 Oct 2014 16:52:14 +0400 Subject: [PATCH] Merge Central and Compute agents to *polling agent* Implements-Blueprint: merge-compute-central-agents Change-Id: I0e8c38ba624d0f9c88582a8b2d7180e808d262a7 --- ceilometer/agent/base.py | 63 ++++++++++++---- ceilometer/agent/manager.py | 7 +- ceilometer/cmd/agent_central.py | 24 ------ ceilometer/cmd/agent_compute.py | 24 ------ ceilometer/cmd/polling.py | 75 +++++++++++++++++++ ceilometer/compute/manager.py | 33 -------- ceilometer/compute/plugin.py | 59 --------------- ceilometer/compute/pollsters/__init__.py | 51 +++++++++++++ ceilometer/compute/pollsters/cpu.py | 14 ++-- ceilometer/compute/pollsters/disk.py | 14 ++-- ceilometer/compute/pollsters/instance.py | 6 +- ceilometer/compute/pollsters/memory.py | 8 +- ceilometer/compute/pollsters/net.py | 8 +- ceilometer/opts.py | 2 + ceilometer/tests/agent/agentbase.py | 11 +-- ceilometer/tests/agent/test_manager.py | 20 ++++- ceilometer/tests/compute/pollsters/base.py | 9 +++ .../tests/compute/pollsters/test_cpu.py | 2 +- .../tests/compute/pollsters/test_diskio.py | 11 ++- .../tests/compute/pollsters/test_instance.py | 2 +- .../pollsters/test_location_metadata.py | 2 +- .../tests/compute/pollsters/test_memory.py | 2 +- .../tests/compute/pollsters/test_net.py | 2 +- ceilometer/tests/compute/test_manager.py | 35 --------- ceilometer/tests/ipmi/test_manager.py | 2 +- setup.cfg | 5 +- 26 files changed, 258 insertions(+), 233 deletions(-) delete mode 100644 ceilometer/cmd/agent_central.py delete mode 100644 ceilometer/cmd/agent_compute.py create mode 100644 ceilometer/cmd/polling.py delete mode 100644 ceilometer/compute/manager.py delete mode 100644 ceilometer/compute/plugin.py delete mode 100644 ceilometer/tests/compute/test_manager.py diff --git a/ceilometer/agent/base.py b/ceilometer/agent/base.py index e94e8859d..82ccaa8c1 100644 --- a/ceilometer/agent/base.py +++ b/ceilometer/agent/base.py @@ -19,6 +19,7 @@ # under the License. import collections +import fnmatch import itertools from oslo.config import cfg @@ -40,6 +41,15 @@ cfg.CONF.import_opt('heartbeat', 'ceilometer.coordination', group='coordination') +class PollsterListForbidden(Exception): + def __init__(self): + msg = ('It is forbidden to use pollster-list option of polling agent ' + 'in case of using coordination between multiple agents. Please ' + 'use either multiple agents being coordinated or polling list ' + 'option for one polling agent.') + super(PollsterListForbidden, self).__init__(msg) + + class Resources(object): def __init__(self, agent_manager): self.agent_manager = agent_manager @@ -140,14 +150,42 @@ class PollingTask(object): class AgentManager(os_service.Service): - def __init__(self, namespace, group_prefix=None): + def __init__(self, namespaces, pollster_list, group_prefix=None): super(AgentManager, self).__init__() - self.pollster_manager = self._extensions('poll', namespace) + + def _match(pollster): + """Find out if pollster name matches to one of the list.""" + return any(fnmatch.fnmatch(pollster.name, pattern) for + pattern in pollster_list) + + # features of using coordination and pollster-list are exclusive, and + # cannot be used at one moment to avoid both samples duplication and + # samples being lost + if pollster_list and cfg.CONF.coordination.backend_url: + raise PollsterListForbidden() + + if type(namespaces) is not list: + namespaces = [namespaces] + + # we'll have default ['compute', 'central'] here if no namespaces will + # be passed + extensions = (self._extensions('poll', namespace).extensions + for namespace in namespaces) + if pollster_list: + extensions = (itertools.ifilter(_match, exts) + for exts in extensions) + + self.extensions = list(itertools.chain(*list(extensions))) + self.discovery_manager = self._extensions('discover') self.context = context.RequestContext('admin', 'admin', is_admin=True) self.partition_coordinator = coordination.PartitionCoordinator() - self.group_prefix = ('%s-%s' % (namespace, group_prefix) - if group_prefix else namespace) + + # Compose coordination group prefix. + # We'll use namespaces as the basement for this partitioning. + namespace_prefix = '-'.join(sorted(namespaces)) + self.group_prefix = ('%s-%s' % (namespace_prefix, group_prefix) + if group_prefix else namespace_prefix) @staticmethod def _extensions(category, agent_ns=None): @@ -177,15 +215,14 @@ class AgentManager(os_service.Service): def setup_polling_tasks(self): polling_tasks = {} - for pipeline, pollster in itertools.product( - self.pipeline_manager.pipelines, - self.pollster_manager.extensions): - if pipeline.support_meter(pollster.name): - polling_task = polling_tasks.get(pipeline.get_interval()) - if not polling_task: - polling_task = self.create_polling_task() - polling_tasks[pipeline.get_interval()] = polling_task - polling_task.add(pollster, pipeline) + for pipeline in self.pipeline_manager.pipelines: + for pollster in self.extensions: + if pipeline.support_meter(pollster.name): + polling_task = polling_tasks.get(pipeline.get_interval()) + if not polling_task: + polling_task = self.create_polling_task() + polling_tasks[pipeline.get_interval()] = polling_task + polling_task.add(pollster, pipeline) return polling_tasks diff --git a/ceilometer/agent/manager.py b/ceilometer/agent/manager.py index e607f2e46..91dfcf7b2 100644 --- a/ceilometer/agent/manager.py +++ b/ceilometer/agent/manager.py @@ -41,9 +41,12 @@ LOG = log.getLogger(__name__) class AgentManager(base.AgentManager): - def __init__(self, namespace='agent'): + def __init__(self, namespaces=None, pollster_list=None): + namespaces = namespaces or ['compute', 'central'] + pollster_list = pollster_list or [] super(AgentManager, self).__init__( - namespace, group_prefix=cfg.CONF.polling.partitioning_group_prefix) + namespaces, pollster_list, + group_prefix=cfg.CONF.polling.partitioning_group_prefix) def interval_task(self, task): try: diff --git a/ceilometer/cmd/agent_central.py b/ceilometer/cmd/agent_central.py deleted file mode 100644 index 45bb79ffa..000000000 --- a/ceilometer/cmd/agent_central.py +++ /dev/null @@ -1,24 +0,0 @@ -# -*- encoding: utf-8 -*- -# -# Copyright 2014 OpenStack Foundation -# -# 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 ceilometer.agent import manager -from ceilometer.openstack.common import service as os_service -from ceilometer import service - - -def main(): - service.prepare_service() - os_service.launch(manager.AgentManager()).wait() diff --git a/ceilometer/cmd/agent_compute.py b/ceilometer/cmd/agent_compute.py deleted file mode 100644 index d23f2b0d3..000000000 --- a/ceilometer/cmd/agent_compute.py +++ /dev/null @@ -1,24 +0,0 @@ -# -*- encoding: utf-8 -*- -# -# Copyright 2014 OpenStack Foundation -# -# 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 ceilometer.compute import manager -from ceilometer.openstack.common import service as os_service -from ceilometer import service - - -def main(): - service.prepare_service() - os_service.launch(manager.AgentManager()).wait() diff --git a/ceilometer/cmd/polling.py b/ceilometer/cmd/polling.py new file mode 100644 index 000000000..05dde9933 --- /dev/null +++ b/ceilometer/cmd/polling.py @@ -0,0 +1,75 @@ +# -*- encoding: utf-8 -*- +# +# Copyright 2014 OpenStack Foundation +# +# 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 + +from ceilometer.agent import manager +from ceilometer.openstack.common import service as os_service +from ceilometer import service + +CONF = cfg.CONF + + +class MultiChoicesOpt(cfg.Opt): + def __init__(self, name, choices=None, **kwargs): + super(MultiChoicesOpt, self).__init__(name, + type=cfg.types.List(), + **kwargs) + self.choices = choices + + def _get_argparse_kwargs(self, group, **kwargs): + """Extends the base argparse keyword dict for multi choices options.""" + kwargs = super(MultiChoicesOpt, self)._get_argparse_kwargs(group) + kwargs['nargs'] = '+' + choices = kwargs.get('choices', self.choices) + if choices: + kwargs['choices'] = choices + return kwargs + +# todo(dbelova): add ipmi agent here as well +CLI_OPTS = [ + MultiChoicesOpt('polling-namespaces', + default=['compute', 'central'], + choices=['compute', 'central'], + dest='polling_namespaces', + help='Polling namespace(s) to be used while ' + 'resource polling'), + MultiChoicesOpt('pollster-list', + default=[], + dest='pollster_list', + help='List of pollsters (or wildcard templates) to be ' + 'used while polling'), +] + +CONF.register_cli_opts(CLI_OPTS) + + +def main(): + service.prepare_service() + os_service.launch(manager.AgentManager(CONF.polling_namespaces, + CONF.pollster_list)).wait() + + +# todo(dbelova): remove it someday. Needed for backward compatibility +def main_compute(): + service.prepare_service() + os_service.launch(manager.AgentManager(['compute'])).wait() + + +# todo(dbelova): remove it someday. Needed for backward compatibility +def main_central(): + service.prepare_service() + os_service.launch(manager.AgentManager(['central'])).wait() diff --git a/ceilometer/compute/manager.py b/ceilometer/compute/manager.py deleted file mode 100644 index cb0e73668..000000000 --- a/ceilometer/compute/manager.py +++ /dev/null @@ -1,33 +0,0 @@ -# -# Copyright 2012-2013 eNovance -# -# Author: Julien Danjou -# -# 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 ceilometer.agent import manager -from ceilometer.compute.virt import inspector as virt_inspector -from ceilometer.openstack.common import log - -LOG = log.getLogger(__name__) - - -class AgentManager(manager.AgentManager): - - def __init__(self): - super(AgentManager, self).__init__('compute') - self._inspector = virt_inspector.get_hypervisor_inspector() - - @property - def inspector(self): - return self._inspector diff --git a/ceilometer/compute/plugin.py b/ceilometer/compute/plugin.py deleted file mode 100644 index 53596e8ef..000000000 --- a/ceilometer/compute/plugin.py +++ /dev/null @@ -1,59 +0,0 @@ -# -# Copyright 2012 New Dream Network, LLC (DreamHost) -# -# Author: Doug Hellmann -# -# 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. -"""Base class for plugins used by the compute agent. -""" - -import abc - -from oslo.utils import timeutils -import six - -from ceilometer.agent import plugin_base as plugin - - -@six.add_metaclass(abc.ABCMeta) -class ComputePollster(plugin.PollsterBase): - """Base class for plugins. - - It supports the polling API on the compute node. - """ - - @property - def default_discovery(self): - return 'local_instances' - - @abc.abstractmethod - def get_samples(self, manager, cache, resources): - """Return a sequence of Counter instances from polling the resources. - - :param manager: The service manager invoking the plugin - :param cache: A dictionary for passing data between plugins - :param resources: The resources to examine (expected to be instances) - """ - - def _record_poll_time(self): - """Method records current time as the poll time. - - :return: time in seconds since the last poll time was recorded - """ - current_time = timeutils.utcnow() - duration = None - if hasattr(self, '_last_poll_time'): - duration = timeutils.delta_seconds(self._last_poll_time, - current_time) - self._last_poll_time = current_time - return duration diff --git a/ceilometer/compute/pollsters/__init__.py b/ceilometer/compute/pollsters/__init__.py index e69de29bb..a648ce8b6 100644 --- a/ceilometer/compute/pollsters/__init__.py +++ b/ceilometer/compute/pollsters/__init__.py @@ -0,0 +1,51 @@ +# Copyright 2014 Mirantis, 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. + +import abc + +from oslo.utils import timeutils +import six + +from ceilometer.agent import plugin_base +from ceilometer.compute.virt import inspector as virt_inspector + + +@six.add_metaclass(abc.ABCMeta) +class BaseComputePollster(plugin_base.PollsterBase): + + @property + def inspector(self): + try: + inspector = self._inspector + except AttributeError: + inspector = virt_inspector.get_hypervisor_inspector() + BaseComputePollster._inspector = inspector + return inspector + + @property + def default_discovery(self): + return 'local_instances' + + def _record_poll_time(self): + """Method records current time as the poll time. + + :return: time in seconds since the last poll time was recorded + """ + current_time = timeutils.utcnow() + duration = None + if hasattr(self, '_last_poll_time'): + duration = timeutils.delta_seconds(self._last_poll_time, + current_time) + self._last_poll_time = current_time + return duration diff --git a/ceilometer/compute/pollsters/cpu.py b/ceilometer/compute/pollsters/cpu.py index bf30f8c15..0c23f0f35 100644 --- a/ceilometer/compute/pollsters/cpu.py +++ b/ceilometer/compute/pollsters/cpu.py @@ -17,7 +17,7 @@ # License for the specific language governing permissions and limitations # under the License. import ceilometer -from ceilometer.compute import plugin +from ceilometer.compute import pollsters from ceilometer.compute.pollsters import util from ceilometer.compute.virt import inspector as virt_inspector from ceilometer.i18n import _ @@ -27,13 +27,13 @@ from ceilometer import sample LOG = log.getLogger(__name__) -class CPUPollster(plugin.ComputePollster): +class CPUPollster(pollsters.BaseComputePollster): def get_samples(self, manager, cache, resources): for instance in resources: LOG.debug(_('checking instance %s'), instance.id) try: - cpu_info = manager.inspector.inspect_cpus(instance) + cpu_info = self.inspector.inspect_cpus(instance) LOG.debug(_("CPUTIME USAGE: %(instance)s %(time)d"), {'instance': instance.__dict__, 'time': cpu_info.time}) @@ -52,20 +52,20 @@ class CPUPollster(plugin.ComputePollster): except ceilometer.NotImplementedError: # Selected inspector does not implement this pollster. LOG.debug(_('Obtaining CPU time is not implemented for %s' - ), manager.inspector.__class__.__name__) + ), self.inspector.__class__.__name__) except Exception as err: LOG.exception(_('could not get CPU time for %(id)s: %(e)s'), {'id': instance.id, 'e': err}) -class CPUUtilPollster(plugin.ComputePollster): +class CPUUtilPollster(pollsters.BaseComputePollster): def get_samples(self, manager, cache, resources): self._inspection_duration = self._record_poll_time() for instance in resources: LOG.debug(_('Checking CPU util for instance %s'), instance.id) try: - cpu_info = manager.inspector.inspect_cpu_util( + cpu_info = self.inspector.inspect_cpu_util( instance, self._inspection_duration) LOG.debug(_("CPU UTIL: %(instance)s %(util)d"), ({'instance': instance.__dict__, @@ -83,7 +83,7 @@ class CPUUtilPollster(plugin.ComputePollster): except ceilometer.NotImplementedError: # Selected inspector does not implement this pollster. LOG.debug(_('Obtaining CPU Util is not implemented for %s'), - manager.inspector.__class__.__name__) + self.inspector.__class__.__name__) except Exception as err: LOG.exception(_('Could not get CPU Util for %(id)s: %(e)s'), {'id': instance.id, 'e': err}) diff --git a/ceilometer/compute/pollsters/disk.py b/ceilometer/compute/pollsters/disk.py index 5990ce255..5a3ef3b99 100644 --- a/ceilometer/compute/pollsters/disk.py +++ b/ceilometer/compute/pollsters/disk.py @@ -24,7 +24,7 @@ import collections import six import ceilometer -from ceilometer.compute import plugin +from ceilometer.compute import pollsters from ceilometer.compute.pollsters import util from ceilometer.compute.virt import inspector as virt_inspector from ceilometer.i18n import _ @@ -48,7 +48,7 @@ DiskRateData = collections.namedtuple('DiskRateData', @six.add_metaclass(abc.ABCMeta) -class _Base(plugin.ComputePollster): +class _Base(pollsters.BaseComputePollster): DISKIO_USAGE_MESSAGE = ' '.join(["DISKIO USAGE:", "%s %s:", @@ -110,7 +110,7 @@ class _Base(plugin.ComputePollster): instance_name = util.instance_name(instance) try: c_data = self._populate_cache( - manager.inspector, + self.inspector, cache, instance, ) @@ -123,7 +123,7 @@ class _Base(plugin.ComputePollster): # Selected inspector does not implement this pollster. LOG.debug(_('%(inspector)s does not provide data for ' ' %(pollster)s'), - {'inspector': manager.inspector.__class__.__name__, + {'inspector': self.inspector.__class__.__name__, 'pollster': self.__class__.__name__}) except Exception as err: LOG.exception(_('Ignoring instance %(name)s: %(error)s'), @@ -263,7 +263,7 @@ class PerDeviceWriteBytesPollster(_Base): @six.add_metaclass(abc.ABCMeta) -class _DiskRatesPollsterBase(plugin.ComputePollster): +class _DiskRatesPollsterBase(pollsters.BaseComputePollster): CACHE_KEY_DISK_RATE = 'diskio-rate' @@ -315,7 +315,7 @@ class _DiskRatesPollsterBase(plugin.ComputePollster): for instance in resources: try: disk_rates_info = self._populate_cache( - manager.inspector, + self.inspector, cache, instance, ) @@ -328,7 +328,7 @@ class _DiskRatesPollsterBase(plugin.ComputePollster): # Selected inspector does not implement this pollster. LOG.debug(_('%(inspector)s does not provide data for ' ' %(pollster)s'), - {'inspector': manager.inspector.__class__.__name__, + {'inspector': self.inspector.__class__.__name__, 'pollster': self.__class__.__name__}) except Exception as err: instance_name = util.instance_name(instance) diff --git a/ceilometer/compute/pollsters/instance.py b/ceilometer/compute/pollsters/instance.py index c19f9df38..aed40dde9 100644 --- a/ceilometer/compute/pollsters/instance.py +++ b/ceilometer/compute/pollsters/instance.py @@ -17,12 +17,12 @@ # License for the specific language governing permissions and limitations # under the License. -from ceilometer.compute import plugin +from ceilometer.compute import pollsters from ceilometer.compute.pollsters import util from ceilometer import sample -class InstancePollster(plugin.ComputePollster): +class InstancePollster(pollsters.BaseComputePollster): @staticmethod def get_samples(manager, cache, resources): @@ -36,7 +36,7 @@ class InstancePollster(plugin.ComputePollster): ) -class InstanceFlavorPollster(plugin.ComputePollster): +class InstanceFlavorPollster(pollsters.BaseComputePollster): @staticmethod def get_samples(manager, cache, resources): diff --git a/ceilometer/compute/pollsters/memory.py b/ceilometer/compute/pollsters/memory.py index 569a08f80..e5e550908 100644 --- a/ceilometer/compute/pollsters/memory.py +++ b/ceilometer/compute/pollsters/memory.py @@ -13,7 +13,7 @@ # License for the specific language governing permissions and limitations # under the License. import ceilometer -from ceilometer.compute import plugin +from ceilometer.compute import pollsters from ceilometer.compute.pollsters import util from ceilometer.compute.virt import inspector as virt_inspector from ceilometer.i18n import _ @@ -23,14 +23,14 @@ from ceilometer import sample LOG = log.getLogger(__name__) -class MemoryUsagePollster(plugin.ComputePollster): +class MemoryUsagePollster(pollsters.BaseComputePollster): def get_samples(self, manager, cache, resources): self._inspection_duration = self._record_poll_time() for instance in resources: LOG.debug(_('Checking memory usage for instance %s'), instance.id) try: - memory_info = manager.inspector.inspect_memory_usage( + memory_info = self.inspector.inspect_memory_usage( instance, self._inspection_duration) LOG.debug(_("MEMORY USAGE: %(instance)s %(usage)f"), ({'instance': instance.__dict__, @@ -48,7 +48,7 @@ class MemoryUsagePollster(plugin.ComputePollster): except ceilometer.NotImplementedError: # Selected inspector does not implement this pollster. LOG.debug(_('Obtaining Memory Usage is not implemented for %s' - ), manager.inspector.__class__.__name__) + ), self.inspector.__class__.__name__) except Exception as err: LOG.exception(_('Could not get Memory Usage for ' '%(id)s: %(e)s'), {'id': instance.id, diff --git a/ceilometer/compute/pollsters/net.py b/ceilometer/compute/pollsters/net.py index dd5458722..7d50017f8 100644 --- a/ceilometer/compute/pollsters/net.py +++ b/ceilometer/compute/pollsters/net.py @@ -22,7 +22,7 @@ import copy from oslo.utils import timeutils import ceilometer -from ceilometer.compute import plugin +from ceilometer.compute import pollsters from ceilometer.compute.pollsters import util from ceilometer.compute import util as compute_util from ceilometer.compute.virt import inspector as virt_inspector @@ -33,7 +33,7 @@ from ceilometer import sample LOG = log.getLogger(__name__) -class _Base(plugin.ComputePollster): +class _Base(pollsters.BaseComputePollster): NET_USAGE_MESSAGE = ' '.join(["NETWORK USAGE:", "%s %s:", "read-bytes=%d", "write-bytes=%d"]) @@ -96,7 +96,7 @@ class _Base(plugin.ComputePollster): try: vnics = self._get_vnics_for_instance( cache, - manager.inspector, + self.inspector, instance, ) for vnic, info in vnics: @@ -111,7 +111,7 @@ class _Base(plugin.ComputePollster): # Selected inspector does not implement this pollster. LOG.debug(_('%(inspector)s does not provide data for ' ' %(pollster)s'), - {'inspector': manager.inspector.__class__.__name__, + {'inspector': self.inspector.__class__.__name__, 'pollster': self.__class__.__name__}) except Exception as err: LOG.exception(_('Ignoring instance %(name)s: %(error)s'), diff --git a/ceilometer/opts.py b/ceilometer/opts.py index fcb89ccba..06370c417 100644 --- a/ceilometer/opts.py +++ b/ceilometer/opts.py @@ -104,6 +104,7 @@ def list_opts(): ('api', itertools.chain(ceilometer.api.OPTS, ceilometer.api.app.API_OPTS,)), + # deprecated path, new one is 'polling' ('central', ceilometer.agent.manager.OPTS), ('collector', ceilometer.collector.OPTS), ('compute', ceilometer.compute.discovery.OPTS), @@ -114,6 +115,7 @@ def list_opts(): ('hardware', ceilometer.hardware.discovery.OPTS), ('impi', ceilometer.ipmi.platform.intel_node_manager.OPTS), ('notification', ceilometer.notification.OPTS), + ('polling', ceilometer.agent.manager.OPTS), ('publisher', ceilometer.publisher.utils.OPTS), ('publisher_notifier', ceilometer.publisher.messaging.NOTIFIER_OPTS), ('publisher_rpc', ceilometer.publisher.messaging.RPC_OPTS), diff --git a/ceilometer/tests/agent/agentbase.py b/ceilometer/tests/agent/agentbase.py index 0fc491df5..f589c43bd 100644 --- a/ceilometer/tests/agent/agentbase.py +++ b/ceilometer/tests/agent/agentbase.py @@ -180,7 +180,7 @@ class BaseAgentManagerTestCase(base.BaseTestCase): self.pipeline_cfg, self.transformer_manager) - def get_extension_list(self): + def create_extension_list(self): return [extension.Extension('test', None, None, @@ -198,11 +198,6 @@ class BaseAgentManagerTestCase(base.BaseTestCase): None, self.PollsterExceptionAnother(), )] - def create_pollster_manager(self): - return extension.ExtensionManager.make_test_instance( - self.get_extension_list(), - ) - def create_discovery_manager(self): return extension.ExtensionManager.make_test_instance( [ @@ -232,7 +227,7 @@ class BaseAgentManagerTestCase(base.BaseTestCase): def setUp(self): super(BaseAgentManagerTestCase, self).setUp() self.mgr = self.create_manager() - self.mgr.pollster_manager = self.create_pollster_manager() + self.mgr.extensions = self.create_extension_list() self.mgr.partition_coordinator = mock.MagicMock() fake_subset = lambda _, x: x p_coord = self.mgr.partition_coordinator @@ -404,7 +399,7 @@ class BaseAgentManagerTestCase(base.BaseTestCase): def test_agent_manager_start(self): mgr = self.create_manager() - mgr.pollster_manager = self.mgr.pollster_manager + mgr.extensions = self.mgr.extensions mgr.create_polling_task = mock.MagicMock() mgr.tg = mock.MagicMock() mgr.start() diff --git a/ceilometer/tests/agent/test_manager.py b/ceilometer/tests/agent/test_manager.py index 212818bbf..4ae02a224 100644 --- a/ceilometer/tests/agent/test_manager.py +++ b/ceilometer/tests/agent/test_manager.py @@ -17,6 +17,8 @@ """Tests for ceilometer/central/manager.py """ +import itertools + import mock from oslotest import base from oslotest import mockpatch @@ -33,7 +35,19 @@ class TestManager(base.BaseTestCase): @mock.patch('ceilometer.pipeline.setup_pipeline', mock.MagicMock()) def test_load_plugins(self): mgr = manager.AgentManager() - self.assertIsNotNone(list(mgr.pollster_manager)) + self.assertIsNotNone(list(mgr.extensions)) + + def test_load_plugins_pollster_list(self): + mgr = manager.AgentManager(pollster_list=['disk.*']) + # currently we do have 16 disk-related pollsters + self.assertEqual(16, len(list(mgr.extensions))) + + def test_load_plugins_no_intersection(self): + # Let's test nothing will be polled if namespace and pollsters + # list have no intersection. + mgr = manager.AgentManager(namespaces=['compute'], + pollster_list=['storage.*']) + self.assertEqual(0, len(list(mgr.extensions))) class TestPollsterKeystone(agentbase.TestPollster): @@ -108,6 +122,10 @@ class TestRunTasks(agentbase.BaseAgentManagerTestCase): self.mgr.pipeline_manager = pipeline.PipelineManager( self.pipeline_cfg, self.transformer_manager) + self.mgr.extensions = itertools.chain( + self.mgr.extensions, + [extension.Extension('testkeystone', None, None, + self.PollsterKeystone())]) polling_tasks = self.mgr.setup_polling_tasks() self.mgr.interval_task(polling_tasks.values()[0]) self.assertFalse(self.PollsterKeystone.samples) diff --git a/ceilometer/tests/compute/pollsters/base.py b/ceilometer/tests/compute/pollsters/base.py index 7858f60ca..42c5af15c 100644 --- a/ceilometer/tests/compute/pollsters/base.py +++ b/ceilometer/tests/compute/pollsters/base.py @@ -42,3 +42,12 @@ class TestPollsterBase(base.BaseTestCase): 'ceilometer.compute.virt.inspector.get_hypervisor_inspector', new=mock.Mock(return_value=self.inspector)) self.useFixture(patch_virt) + + # as we're having lazy hypervisor inspector singleton object in the + # base compute pollster class, that leads to the fact that we + # need to mock all this class property to avoid context sharing between + # the tests + patch_inspector = mockpatch.Patch( + 'ceilometer.compute.pollsters.BaseComputePollster.inspector', + self.inspector) + self.useFixture(patch_inspector) diff --git a/ceilometer/tests/compute/pollsters/test_cpu.py b/ceilometer/tests/compute/pollsters/test_cpu.py index c95321bec..61137ed80 100644 --- a/ceilometer/tests/compute/pollsters/test_cpu.py +++ b/ceilometer/tests/compute/pollsters/test_cpu.py @@ -21,7 +21,7 @@ import time import mock -from ceilometer.compute import manager +from ceilometer.agent import manager from ceilometer.compute.pollsters import cpu from ceilometer.compute.virt import inspector as virt_inspector from ceilometer.tests.compute.pollsters import base diff --git a/ceilometer/tests/compute/pollsters/test_diskio.py b/ceilometer/tests/compute/pollsters/test_diskio.py index 781582bdb..8a07a2a5c 100644 --- a/ceilometer/tests/compute/pollsters/test_diskio.py +++ b/ceilometer/tests/compute/pollsters/test_diskio.py @@ -21,7 +21,7 @@ import mock from oslotest import mockpatch -from ceilometer.compute import manager +from ceilometer.agent import manager from ceilometer.compute.pollsters import disk from ceilometer.compute.virt import inspector as virt_inspector import ceilometer.tests.base as base @@ -41,6 +41,15 @@ class TestBaseDiskIO(base.BaseTestCase): new=mock.Mock(return_value=self.inspector)) self.useFixture(patch_virt) + # as we're having lazy hypervisor inspector singleton object in the + # base compute pollster class, that leads to the fact that we + # need to mock all this class property to avoid context sharing between + # the tests + patch_inspector = mockpatch.Patch( + 'ceilometer.compute.pollsters.BaseComputePollster.inspector', + self.inspector) + self.useFixture(patch_inspector) + @staticmethod def _get_fake_instances(): instances = [] diff --git a/ceilometer/tests/compute/pollsters/test_instance.py b/ceilometer/tests/compute/pollsters/test_instance.py index 543643d31..5f1db840c 100644 --- a/ceilometer/tests/compute/pollsters/test_instance.py +++ b/ceilometer/tests/compute/pollsters/test_instance.py @@ -19,7 +19,7 @@ import mock -from ceilometer.compute import manager +from ceilometer.agent import manager from ceilometer.compute.pollsters import instance as pollsters_instance from ceilometer.tests.compute.pollsters import base diff --git a/ceilometer/tests/compute/pollsters/test_location_metadata.py b/ceilometer/tests/compute/pollsters/test_location_metadata.py index 4241076ae..efcae0c48 100644 --- a/ceilometer/tests/compute/pollsters/test_location_metadata.py +++ b/ceilometer/tests/compute/pollsters/test_location_metadata.py @@ -23,7 +23,7 @@ import mock from oslotest import base import six -from ceilometer.compute import manager +from ceilometer.agent import manager from ceilometer.compute.pollsters import util diff --git a/ceilometer/tests/compute/pollsters/test_memory.py b/ceilometer/tests/compute/pollsters/test_memory.py index 969518eb8..fcc3000a1 100644 --- a/ceilometer/tests/compute/pollsters/test_memory.py +++ b/ceilometer/tests/compute/pollsters/test_memory.py @@ -15,7 +15,7 @@ import mock -from ceilometer.compute import manager +from ceilometer.agent import manager from ceilometer.compute.pollsters import memory from ceilometer.compute.virt import inspector as virt_inspector from ceilometer.tests.compute.pollsters import base diff --git a/ceilometer/tests/compute/pollsters/test_net.py b/ceilometer/tests/compute/pollsters/test_net.py index d1cc05a5d..8797403c0 100644 --- a/ceilometer/tests/compute/pollsters/test_net.py +++ b/ceilometer/tests/compute/pollsters/test_net.py @@ -19,7 +19,7 @@ import mock -from ceilometer.compute import manager +from ceilometer.agent import manager from ceilometer.compute.pollsters import net from ceilometer.compute.virt import inspector as virt_inspector from ceilometer import sample diff --git a/ceilometer/tests/compute/test_manager.py b/ceilometer/tests/compute/test_manager.py deleted file mode 100644 index 5318fddd1..000000000 --- a/ceilometer/tests/compute/test_manager.py +++ /dev/null @@ -1,35 +0,0 @@ -# -# Copyright 2012 New Dream Network, LLC (DreamHost) -# -# Author: Doug Hellmann -# -# 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. -"""Tests for ceilometer/agent/manager.py -""" -import mock -from oslotest import base - -from ceilometer.compute import manager - - -class TestManager(base.BaseTestCase): - """Test that compute manager loads some pollsters. - - There is no need to test how does compute manager setups pollstering - process, as it's actually the same that is done by base manager tests. - """ - - @mock.patch('ceilometer.pipeline.setup_pipeline', mock.MagicMock()) - def test_load_plugins(self): - mgr = manager.AgentManager() - self.assertIsNotNone(list(mgr.pollster_manager)) diff --git a/ceilometer/tests/ipmi/test_manager.py b/ceilometer/tests/ipmi/test_manager.py index 5da784e80..9d4bed548 100644 --- a/ceilometer/tests/ipmi/test_manager.py +++ b/ceilometer/tests/ipmi/test_manager.py @@ -29,7 +29,7 @@ class TestManager(base.BaseTestCase): @mock.patch('ceilometer.pipeline.setup_pipeline', mock.MagicMock()) def test_load_plugins(self): mgr = manager.AgentManager() - self.assertIsNotNone(list(mgr.pollster_manager)) + self.assertIsNotNone(list(mgr.extensions)) class TestRunTasks(agentbase.BaseAgentManagerTestCase): diff --git a/setup.cfg b/setup.cfg index 3476f6f19..2bba50cf0 100755 --- a/setup.cfg +++ b/setup.cfg @@ -287,8 +287,9 @@ paste.filter_factory = console_scripts = ceilometer-api = ceilometer.cmd.api:main - ceilometer-agent-central = ceilometer.cmd.agent_central:main - ceilometer-agent-compute = ceilometer.cmd.agent_compute:main + ceilometer-agent-central = ceilometer.cmd.polling:main_central + ceilometer-agent-compute = ceilometer.cmd.polling:main_compute + ceilometer-polling = ceilometer.cmd.polling:main ceilometer-agent-notification = ceilometer.cmd.agent_notification:main ceilometer-agent-ipmi = ceilometer.cmd.agent_ipmi:main ceilometer-send-sample = ceilometer.cli:send_sample