diff --git a/config.yaml b/config.yaml index 27a9e4c..9e1b24e 100644 --- a/config.yaml +++ b/config.yaml @@ -22,6 +22,19 @@ options: Openstack mostly defaults to using public endpoints for internal communication between services. If set to True this option will configure services to use internal endpoints where possible. + polling-interval: + type: int + default: 300 + description: | + Number of seconds between Ceilometer compute agent pollster collections. This + setting only takes effect from Queens onwards. + enable-all-pollsters: + type: boolean + default: False + description: | + The default ceilometer pollster collection runs a limited set of pollsters. + Enable this to run all the available pollsters. This setting only takes effect + from Queens onwards. rabbit-user: type: string default: ceilometer diff --git a/hooks/ceilometer_contexts.py b/hooks/ceilometer_contexts.py index 196a575..a07791f 100644 --- a/hooks/ceilometer_contexts.py +++ b/hooks/ceilometer_contexts.py @@ -16,6 +16,7 @@ import base64 import os from charmhelpers.core.hookenv import ( + config, relation_ids, relation_get, related_units, @@ -84,3 +85,13 @@ class CeilometerServiceContext(OSContextGenerator): conf['rabbit_ssl_ca'] = ca_path return conf return {} + + +class CeilometerAgentContext(OSContextGenerator): + def __call__(self): + ctxt = { + 'polling_interval': int(config('polling-interval')), + 'enable_all_pollsters': config('enable-all-pollsters'), + } + + return ctxt diff --git a/hooks/ceilometer_utils.py b/hooks/ceilometer_utils.py index e7ea5ef..dea0976 100644 --- a/hooks/ceilometer_utils.py +++ b/hooks/ceilometer_utils.py @@ -18,6 +18,7 @@ from charmhelpers.contrib.openstack import ( templating, ) from ceilometer_contexts import ( + CeilometerAgentContext, CeilometerServiceContext, ) from charmhelpers.contrib.openstack.utils import ( @@ -49,6 +50,7 @@ from charmhelpers.fetch import ( CEILOMETER_CONF_DIR = "/etc/ceilometer" CEILOMETER_CONF = "%s/ceilometer.conf" % CEILOMETER_CONF_DIR +POLLING_CONF = "%s/polling.yaml" % CEILOMETER_CONF_DIR CEILOMETER_AGENT_SERVICES = ['ceilometer-agent-compute'] @@ -95,6 +97,17 @@ CONFIG_FILES = { 'services': CEILOMETER_AGENT_SERVICES }, } + +QUEENS_CONFIG_FILES = deepcopy(CONFIG_FILES) +QUEENS_CONFIG_FILES.update({ + POLLING_CONF: { + 'hook_contexts': [ + CeilometerAgentContext() + ], + 'services': CEILOMETER_AGENT_SERVICES + } +}) + TEMPLATES = 'templates' REQUIRED_INTERFACES = { @@ -117,8 +130,13 @@ def register_configs(): configs = templating.OSConfigRenderer(templates_dir=TEMPLATES, openstack_release=release) - for conf in CONFIG_FILES: - configs.register(conf, CONFIG_FILES[conf]['hook_contexts']) + if CompareOpenStackReleases(release) >= 'queens': + _config_files = QUEENS_CONFIG_FILES + else: + _config_files = CONFIG_FILES + + for conf in _config_files: + configs.register(conf, _config_files[conf]['hook_contexts']) if enable_memcache(release=release): configs.register( @@ -192,8 +210,14 @@ def restart_map(): ''' release = (get_os_codename_package('ceilometer-common', fatal=False) or 'icehouse') + + if CompareOpenStackReleases(release) >= 'queens': + _config_files = QUEENS_CONFIG_FILES + else: + _config_files = CONFIG_FILES + _map = {} - for f, ctxt in CONFIG_FILES.items(): + for f, ctxt in _config_files.items(): svcs = [] for svc in ctxt['services']: svcs.append(svc) diff --git a/templates/polling.yaml b/templates/polling.yaml new file mode 100644 index 0000000..5fb8d73 --- /dev/null +++ b/templates/polling.yaml @@ -0,0 +1,31 @@ +--- +sources: + - name: juju_pollsters + interval: {{ polling_interval }} + meters: +{%- if enable_all_pollsters %} + - "*" +{%- else %} + - cpu + - cpu_l3_cache + - memory.usage + - network.incoming.bytes + - network.incoming.packets + - network.outgoing.bytes + - network.outgoing.packets + - disk.device.read.bytes + - disk.device.read.requests + - disk.device.write.bytes + - disk.device.write.requests + - hardware.cpu.util + - hardware.memory.used + - hardware.memory.total + - hardware.memory.buffer + - hardware.memory.cached + - hardware.memory.swap.avail + - hardware.memory.swap.total + - hardware.system_stats.io.outgoing.blocks + - hardware.system_stats.io.incoming.blocks + - hardware.network.ip.incoming.datagrams + - hardware.network.ip.outgoing.datagrams +{%- endif %} diff --git a/unit_tests/test_ceilometer_contexts.py b/unit_tests/test_ceilometer_contexts.py index 793fd26..6cbc5aa 100644 --- a/unit_tests/test_ceilometer_contexts.py +++ b/unit_tests/test_ceilometer_contexts.py @@ -16,6 +16,7 @@ import ceilometer_contexts as contexts from test_utils import CharmTestCase TO_PATCH = [ + 'config', 'relation_get', 'relation_ids', 'related_units', @@ -26,6 +27,7 @@ class CeilometerContextsTest(CharmTestCase): def setUp(self): super(CeilometerContextsTest, self).setUp(contexts, TO_PATCH) + self.config.side_effect = self.test_config.get self.relation_get.side_effect = self.test_relation.get def tearDown(self): @@ -65,3 +67,23 @@ class CeilometerContextsTest(CharmTestCase): def test_ceilometer_service_context_not_related(self): self.relation_ids.return_value = [] self.assertEqual(contexts.CeilometerServiceContext()(), {}) + + def test_ceilometer_context(self): + self.assertEqual(contexts.CeilometerAgentContext()(), { + 'polling_interval': 300, + 'enable_all_pollsters': False, + }) + + def test_ceilometer_context_enable_all_pollsters(self): + self.test_config.set('enable-all-pollsters', True) + self.assertEqual(contexts.CeilometerAgentContext()(), { + 'polling_interval': 300, + 'enable_all_pollsters': True, + }) + + def test_ceilometer_context_polling_interval(self): + self.test_config.set('polling-interval', 600) + self.assertEqual(contexts.CeilometerAgentContext()(), { + 'polling_interval': 600, + 'enable_all_pollsters': False, + }) diff --git a/unit_tests/test_ceilometer_utils.py b/unit_tests/test_ceilometer_utils.py index 5707e07..5a51f96 100644 --- a/unit_tests/test_ceilometer_utils.py +++ b/unit_tests/test_ceilometer_utils.py @@ -53,6 +53,7 @@ class CeilometerUtilsTest(CharmTestCase): super(CeilometerUtilsTest, self).tearDown() def test_register_configs(self): + self.get_os_codename_package.return_value = 'icehouse' self.enable_memcache.return_value = False configs = utils.register_configs() registered_configs = [c[0][0] for c in configs.register.call_args_list] @@ -60,6 +61,7 @@ class CeilometerUtilsTest(CharmTestCase): self.assertFalse(utils.MEMCACHED_CONF in registered_configs) def test_register_configs_newton(self): + self.get_os_codename_package.return_value = 'newton' self.enable_memcache.return_value = True configs = utils.register_configs() registered_configs = [c[0][0] for c in configs.register.call_args_list] @@ -67,18 +69,31 @@ class CeilometerUtilsTest(CharmTestCase): self.assertTrue(config in registered_configs) def test_restart_map(self): + self.get_os_codename_package.return_value = 'icehouse' self.enable_memcache.return_value = False restart_map = utils.restart_map() - self.assertEqual(restart_map, - {'/etc/ceilometer/ceilometer.conf': [ - 'ceilometer-agent-compute']}) + self.assertEqual(restart_map, { + '/etc/ceilometer/ceilometer.conf': ['ceilometer-agent-compute'], + }) def test_restart_map_newton(self): + self.get_os_codename_package.return_value = 'newton' self.enable_memcache.return_value = True restart_map = utils.restart_map() expect = { '/etc/ceilometer/ceilometer.conf': ['ceilometer-agent-compute'], - '/etc/memcached.conf': ['memcached']} + '/etc/memcached.conf': ['memcached'], + } + self.assertEqual(restart_map, expect) + + def test_restart_map_queens(self): + self.get_os_codename_package.return_value = 'queens' + restart_map = utils.restart_map() + expect = { + '/etc/ceilometer/ceilometer.conf': ['ceilometer-agent-compute'], + '/etc/memcached.conf': ['memcached'], + '/etc/ceilometer/polling.yaml': ['ceilometer-agent-compute'], + } self.assertEqual(restart_map, expect) def test_assess_status(self):