Merge ~sajoupa/charm-telegraf:snap-support into charm-telegraf:master

Proposed by Laurent Sesquès
Status: Merged
Approved by: Joe Guo
Approved revision: ae53ba8ebee05c43a650a791e394fe31276ee239
Merged at revision: ac0af7b8cb76e77adc913ec67c2f28272f77980d
Proposed branch: ~sajoupa/charm-telegraf:snap-support
Merge into: charm-telegraf:master
Diff against target: 718 lines (+231/-82)
11 files modified
README.md (+10/-0)
config.yaml (+11/-1)
files/telegraf_exec_metrics.py (+1/-1)
layer.yaml (+1/-3)
reactive/telegraf.py (+130/-31)
tests/bundles/focal-snap.yaml (+14/-0)
tests/test_telegraf.py (+26/-10)
tests/tests.yaml (+1/-0)
unit_tests/test_mysql.py (+6/-2)
unit_tests/test_postgresql.py (+15/-3)
unit_tests/test_telegraf.py (+16/-31)
Reviewer Review Type Date Requested Status
Stuart Bishop (community) Approve
Joe Guo (community) Needs Fixing
Xav Paice (community) Needs Fixing
Paul Goins Approve
Canonical IS Reviewers Pending
Review via email: mp+386570@code.launchpad.net

Commit message

Add support for either deb or snap install (defaults to deb)

To post a comment you must log in.
Revision history for this message
Laurent Sesquès (sajoupa) wrote :

Successfully passes `make test`.

Revision history for this message
🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote :

This merge proposal is being monitored by mergebot. Change the status to Approved to merge.

Revision history for this message
Stuart Bishop (stub) wrote :

Looks great. Some minor comments inline, but nothing requiring changes.

Revision history for this message
Paul Goins (vultaire) wrote :

LGTM

review: Approve
Revision history for this message
Xav Paice (xavpaice) wrote :

Needs a rebase against master to resolve merge conflicts.

Tests all pass, including the focal/snap test.

review: Needs Fixing
Revision history for this message
Laurent Sesquès (sajoupa) wrote :

- rebase done
- fixed a few regressions introduced in recent commits in master
- followed stub's advice for {!r}
- successfully passes `make test`

Revision history for this message
Laurent Sesquès (sajoupa) wrote :

replied to the inline comments.

Revision history for this message
Joe Guo (guoqiao) wrote :

Hi Laurent,

Did you run `make test` as root?
I just ran `make unittest` as non-root, it will pop up dialogues to ask for authentication.
You may need to add this line in unit_tests/test_telegraf.py::setup:

monkeypatch.setattr(telegraf.host, 'service_pause', lambda svc: None)

review: Needs Fixing
Revision history for this message
Joe Guo (guoqiao) wrote :

Other than above, both unit and functional tests passed.

Revision history for this message
Stuart Bishop (stub) wrote :

Yup. Some trivial formatting issues, inline.

review: Approve
Revision history for this message
Laurent Sesquès (sajoupa) wrote :

> Hi Laurent,
>
> Did you run `make test` as root?
> I just ran `make unittest` as non-root, it will pop up dialogues to ask for
> authentication.
> You may need to add this line in unit_tests/test_telegraf.py::setup:
>
> monkeypatch.setattr(telegraf.host, 'service_pause', lambda svc: None)

Hi Joe,

I've always run it successfully as a normal user.
But your suggestion makes sense, I added it.

Revision history for this message
Laurent Sesquès (sajoupa) wrote :

Pushed updates addressing guoqiao's and stub's comments.
Still passes `make test` successfully.

Revision history for this message
🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote :

Change successfully merged at revision ac0af7b8cb76e77adc913ec67c2f28272f77980d

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/README.md b/README.md
index d5ae81e..636dcda 100644
--- a/README.md
+++ b/README.md
@@ -28,6 +28,16 @@ address rather than the unit's private address.
2828
29# Configuration29# Configuration
3030
31## Installation method: deb or snap
32
33The charm can deploy using either a deb (default) or a snap installation.
34 juju config telegraf install_method=deb # to use the debian package
35 juju config telegraf install_method=snap # to use the snap
36Only the needed package (deb or snap) will be installed.
37
38To change the snap channel:
39 juju config telegraf snap_channel=beta
40
31## Prometheus Output41## Prometheus Output
3242
33By default, Prometheus output is presented available for scraping.43By default, Prometheus output is presented available for scraping.
diff --git a/config.yaml b/config.yaml
index 215baff..454e461 100644
--- a/config.yaml
+++ b/config.yaml
@@ -97,6 +97,16 @@ options:
97 # description and type comes from the apt layer.97 # description and type comes from the apt layer.
98 default: |98 default: |
99 - null99 - null
100 install_method:
101 type: string
102 default: "deb"
103 description: >
104 Installation method. Valid values are "deb" or "snap".
105 snap_channel:
106 default: "stable"
107 type: string
108 description: |
109 Snap Store channel from which to install the telegraf snap.
100 extra_options:110 extra_options:
101 default: ""111 default: ""
102 type: string112 type: string
@@ -125,7 +135,7 @@ options:
125 type: string135 type: string
126 description: |136 description: |
127 Extra plugins, manually configured. This is expected to be a string137 Extra plugins, manually configured. This is expected to be a string
128 and will be saved "as is" in /etc/telegraf/telegraf.d/extra_plugins.conf138 and will be saved "as is" in telegraf.d/extra_plugins.conf
129 disabled_plugins:139 disabled_plugins:
130 type: string140 type: string
131 default: ""141 default: ""
diff --git a/files/telegraf_exec_metrics.py b/files/telegraf_exec_metrics.py
index 8525e0e..0a08c13 100755
--- a/files/telegraf_exec_metrics.py
+++ b/files/telegraf_exec_metrics.py
@@ -203,7 +203,7 @@ class NetNSCmdMetric(CmdMetric):
203 name_override = "{name}"203 name_override = "{name}"
204 data_format = "json"204 data_format = "json"
205 tag_keys = ["namespace", "id"]205 tag_keys = ["namespace", "id"]
206 interval = 600206 interval = "600s"
207 ''')207 ''')
208208
209 def parse(self, content):209 def parse(self, content):
diff --git a/layer.yaml b/layer.yaml
index 346e4d8..057a4c2 100644
--- a/layer.yaml
+++ b/layer.yaml
@@ -20,6 +20,7 @@ includes:
20 - layer:leadership20 - layer:leadership
21 - layer:ntpmon21 - layer:ntpmon
22 - layer:promreg-client22 - layer:promreg-client
23 - layer:snap
23 - interface:elasticsearch24 - interface:elasticsearch
24 - interface:grafana-dashboard25 - interface:grafana-dashboard
25 - interface:http26 - interface:http
@@ -41,7 +42,4 @@ options:
41 - sysstat42 - sysstat
42 - python3-yaml43 - python3-yaml
43 - python3-netifaces44 - python3-netifaces
44 apt:
45 packages:
46 - telegraf
47repo: https://git.launchpad.net/telegraf-charm45repo: https://git.launchpad.net/telegraf-charm
diff --git a/reactive/telegraf.py b/reactive/telegraf.py
index 28ee023..d62efd2 100644
--- a/reactive/telegraf.py
+++ b/reactive/telegraf.py
@@ -28,6 +28,8 @@ import re
28import netifaces28import netifaces
29import subprocess29import subprocess
3030
31from charms import apt
32from charms.layer import snap
31from charms.reactive import (33from charms.reactive import (
32 endpoint_from_flag,34 endpoint_from_flag,
33 helpers,35 helpers,
@@ -45,11 +47,11 @@ from charmhelpers.core import hookenv, host, unitdata
45from charmhelpers.core.templating import render47from charmhelpers.core.templating import render
46from charmhelpers.core.host import is_container48from charmhelpers.core.host import is_container
47from charmhelpers.contrib.charmsupport import nrpe49from charmhelpers.contrib.charmsupport import nrpe
48from charmhelpers.fetch import apt_cache
49import charms.promreg50import charms.promreg
50from jinja2 import Template, Environment, FileSystemLoader, exceptions51from jinja2 import Template, Environment, FileSystemLoader, exceptions
5152
52BASE_DIR = '/etc/telegraf'53DEB_BASE_DIR = '/etc/telegraf'
54SNAP_BASE_DIR = '/var/snap/telegraf/current'
5355
54CONFIG_FILE = 'telegraf.conf'56CONFIG_FILE = 'telegraf.conf'
5557
@@ -59,16 +61,51 @@ GRAFANA_DASHBOARD_TELEGRAF_FILE_NAME = 'Telegraf.json.j2'
5961
60GRAFANA_DASHBOARD_NAME = 'telegraf'62GRAFANA_DASHBOARD_NAME = 'telegraf'
6163
64SNAP_SERVICE = 'snap.telegraf.telegraf'
65DEB_SERVICE = 'telegraf'
66
62# Utilities #67# Utilities #
6368
6469
65def exec_timeout_supported():70class InvalidInstallMethod(Exception):
66 cache = apt_cache()71 pass
67 pkg = cache['telegraf']72
68 timeout_support = True73
69 if '0.12' in pkg.current_ver.ver_str:74def get_install_method():
70 timeout_support = False75 config = hookenv.config()
71 return timeout_support76 if config['install_method'] in ['deb', 'snap']:
77 return config['install_method']
78 else:
79 hookenv.log(
80 "Invalid install_method for telegraf: {}".format(config['install_method']),
81 level=hookenv.ERROR)
82 raise InvalidInstallMethod()
83
84
85def get_base_dir():
86 config = hookenv.config()
87 if config['install_method'] == 'deb':
88 return DEB_BASE_DIR
89 elif config['install_method'] == 'snap':
90 return SNAP_BASE_DIR
91 else:
92 hookenv.log(
93 "Invalid install_method for telegraf: {}".format(config['install_method']),
94 level=hookenv.ERROR)
95 raise InvalidInstallMethod()
96
97
98def get_service():
99 config = hookenv.config()
100 if config['install_method'] == 'deb':
101 return DEB_SERVICE
102 elif config['install_method'] == 'snap':
103 return SNAP_SERVICE
104 else:
105 hookenv.log(
106 "Invalid install_method for telegraf: {}".format(config['install_method']),
107 level=hookenv.ERROR)
108 raise InvalidInstallMethod()
72109
73110
74def get_templates_dir():111def get_templates_dir():
@@ -76,11 +113,11 @@ def get_templates_dir():
76113
77114
78def get_main_config_path():115def get_main_config_path():
79 return os.path.join(BASE_DIR, CONFIG_FILE)116 return os.path.join(get_base_dir(), CONFIG_FILE)
80117
81118
82def get_configs_dir():119def get_configs_dir():
83 return os.path.join(BASE_DIR, CONFIG_DIR)120 return os.path.join(get_base_dir(), CONFIG_DIR)
84121
85122
86def get_files_dir():123def get_files_dir():
@@ -314,13 +351,15 @@ def update_sysstat_config_with_sdac_xall(path='/etc/sysstat/sysstat'):
314 hookenv.log("sysstat config file not found: {}".format(path), level=hookenv.WARNING)351 hookenv.log("sysstat config file not found: {}".format(path), level=hookenv.WARNING)
315352
316353
317# States354def configure_telegraf(): # noqa: C901
318
319@when('apt.installed.telegraf')
320@when_not('telegraf.configured')
321def configure_telegraf(): # noqa: C901 (compexity 15)
322 update_sysstat_config_with_sdac_xall()355 update_sysstat_config_with_sdac_xall()
323 config_path = get_main_config_path()356 config = hookenv.config()
357 context = config.copy()
358 try:
359 config_path = get_main_config_path()
360 except InvalidInstallMethod:
361 hookenv.status_set('blocked', 'Wrong install_method provided: {!r}'.format(config['install_method']))
362 return
324 if get_remote_unit_name() is None:363 if get_remote_unit_name() is None:
325 hookenv.status_set('waiting', 'Waiting for juju-info relation')364 hookenv.status_set('waiting', 'Waiting for juju-info relation')
326 # if UNIT_NAME in hostname config and relation not yet available,365 # if UNIT_NAME in hostname config and relation not yet available,
@@ -329,8 +368,6 @@ def configure_telegraf(): # noqa: C901 (compexity 15)
329 os.unlink(config_path)368 os.unlink(config_path)
330 return369 return
331370
332 config = hookenv.config()
333 context = config.copy()
334 inputs = config.get('inputs_config', '')371 inputs = config.get('inputs_config', '')
335 outputs = config.get('outputs_config', '')372 outputs = config.get('outputs_config', '')
336 # just for the migration out of base64373 # just for the migration out of base64
@@ -370,8 +407,10 @@ def configure_telegraf(): # noqa: C901 (compexity 15)
370 context["hostname"] = get_hostname_label()407 context["hostname"] = get_hostname_label()
371408
372 logfile_path = os.path.normpath(context["logfile"])409 logfile_path = os.path.normpath(context["logfile"])
373 if context["logfile"] and not logfile_path.startswith("/var/log/"):410 if (context["logfile"] and not logfile_path.startswith("/var/log/") and not
374 # only allow logging in /var/log or in syslog411 (config["install_method"] == 'snap' and
412 logfile_path.startswith("/var/snap/telegraf/common/"))):
413 # only allow logging in /var/log, syslog, or /var/snap/telegraf/common
375 hookenv.log("logfile value reset to stderr."414 hookenv.log("logfile value reset to stderr."
376 " Original value: {}".format(context["logfile"]),415 " Original value: {}".format(context["logfile"]),
377 hookenv.DEBUG)416 hookenv.DEBUG)
@@ -401,10 +440,64 @@ def configure_telegraf(): # noqa: C901 (compexity 15)
401 hookenv.log("Updating main config file")440 hookenv.log("Updating main config file")
402 render(source='telegraf.conf.tmpl', templates_dir=get_templates_dir(),441 render(source='telegraf.conf.tmpl', templates_dir=get_templates_dir(),
403 target=config_path, context=context)442 target=config_path, context=context)
404 host.service_resume('telegraf') # unmask and enable service, start it if not yet443 for service in [DEB_SERVICE, SNAP_SERVICE]:
405 host.service_reload('telegraf') # reload or restart service, to apply config changes444 if service == get_service():
445 host.service_resume(service)
446 host.service_reload(service)
447 else:
448 try:
449 host.service_pause(service)
450 except ValueError:
451 # On machines not supporting snaps, it won't find the service
452 # If we're using the snap, and the deb failed to install, it's fine too
453 pass
406 set_flag('telegraf.configured')454 set_flag('telegraf.configured')
407 set_flag('telegraf.needs_reload')455 set_flag('telegraf.needs_reload')
456 if config["install_method"] == 'deb':
457 set_flag('telegraf.apt.configured')
458 else:
459 set_flag('telegraf.snap.configured')
460
461
462# States
463
464@when_not('telegraf.installed')
465def install_telegraf():
466 try:
467 install_method = get_install_method()
468 except InvalidInstallMethod:
469 hookenv.status_set('blocked', "Wrong install_method provided. Expected either 'deb' or 'snap'.")
470 return
471 if install_method == 'deb':
472 try:
473 snap.remove('telegraf')
474 except Exception:
475 # the snap may already be absent, or snaps may not even be supported in this environment
476 pass
477 apt.queue_install(['telegraf'])
478 elif install_method == 'snap':
479 apt.purge('telegraf')
480 config = hookenv.config()
481 snap_channel = config.get('snap_channel')
482 snap.install('telegraf', channel=snap_channel, classic=True)
483 if install_method:
484 set_flag('telegraf.installed')
485
486
487@when('telegraf.installed')
488@when('apt.installed.telegraf')
489@when_not('telegraf.configured')
490@when_not('telegraf.apt.configured')
491def configure_telegraf_deb():
492 configure_telegraf()
493
494
495@when('telegraf.installed')
496@when('snap.installed.telegraf')
497@when_not('telegraf.configured')
498@when_not('telegraf.snap.configured')
499def configure_telegraf_snap():
500 configure_telegraf()
408501
409502
410@hook('upgrade-charm')503@hook('upgrade-charm')
@@ -413,6 +506,8 @@ def upgrade_charm():
413 clear_flag('plugins.{}.configured'.format(plugin))506 clear_flag('plugins.{}.configured'.format(plugin))
414 clear_flag('extra_plugins.configured')507 clear_flag('extra_plugins.configured')
415 clear_flag('telegraf.configured')508 clear_flag('telegraf.configured')
509 clear_flag('telegraf.apt.configured')
510 clear_flag('telegraf.snap.configured')
416511
417512
418@when('config.changed')513@when('config.changed')
@@ -424,7 +519,11 @@ def handle_config_changes():
424 # if something else changed, let's reconfigure telegraf itself just in case519 # if something else changed, let's reconfigure telegraf itself just in case
425 if config.changed('extra_plugins'):520 if config.changed('extra_plugins'):
426 clear_flag('extra_plugins.configured')521 clear_flag('extra_plugins.configured')
522 if config.changed('install_method') or config.changed('snap_channel') or config.changed('install_sources'):
523 clear_flag('telegraf.installed')
427 clear_flag('telegraf.configured')524 clear_flag('telegraf.configured')
525 clear_flag('telegraf.apt.configured')
526 clear_flag('telegraf.snap.configured')
428 clear_flag('telegraf.nagios-setup.complete')527 clear_flag('telegraf.nagios-setup.complete')
429528
430529
@@ -788,11 +887,8 @@ def exec_input(exec_rel):
788 if not commands:887 if not commands:
789 hookenv.log("No Commands defined in the exec relation, doing nothing.")888 hookenv.log("No Commands defined in the exec relation, doing nothing.")
790 return889 return
791 timeout_support = exec_timeout_supported()
792 pre_proc_cmds = []890 pre_proc_cmds = []
793 for command in commands:891 for command in commands:
794 if not timeout_support:
795 command.pop('timeout')
796 run_on_this_unit = command.pop('run_on_this_unit')892 run_on_this_unit = command.pop('run_on_this_unit')
797 if run_on_this_unit:893 if run_on_this_unit:
798 pre_proc_cmds.append(command)894 pre_proc_cmds.append(command)
@@ -1089,12 +1185,13 @@ def start_or_restart():
1089 states = sorted([k for k in get_states().keys()1185 states = sorted([k for k in get_states().keys()
1090 if k.startswith('plugins') or k.startswith('extra_plugins')])1186 if k.startswith('plugins') or k.startswith('extra_plugins')])
10911187
1188 service = get_service()
1092 config_files_changed = helpers.any_file_changed(list_config_files())1189 config_files_changed = helpers.any_file_changed(list_config_files())
1093 active_plugins_changed = helpers.data_changed('active_plugins', states or '')1190 active_plugins_changed = helpers.data_changed('active_plugins', states or '')
1094 if not host.service_running('telegraf') \1191 if not host.service_running(service) \
1095 or config_files_changed or active_plugins_changed:1192 or config_files_changed or active_plugins_changed:
1096 hookenv.log("Restarting telegraf")1193 hookenv.log("Restarting telegraf")
1097 host.service_restart('telegraf')1194 host.service_restart(service)
1098 else:1195 else:
1099 hookenv.log("Not restarting: active_plugins_changed={} | "1196 hookenv.log("Not restarting: active_plugins_changed={} | "
1100 "config_files_changed={}".format(active_plugins_changed,1197 "config_files_changed={}".format(active_plugins_changed,
@@ -1102,10 +1199,10 @@ def start_or_restart():
11021199
1103 # Give telegraf time to restart.1200 # Give telegraf time to restart.
1104 timeout = time.time() + 151201 timeout = time.time() + 15
1105 while not host.service_running('telegraf') and time.time() < timeout:1202 while not host.service_running(service) and time.time() < timeout:
1106 time.sleep(0.1)1203 time.sleep(0.1)
11071204
1108 if host.service_running('telegraf'):1205 if host.service_running(service):
1109 hookenv.status_set('active',1206 hookenv.status_set('active',
1110 'Monitoring {}'.format(get_remote_unit_name()))1207 'Monitoring {}'.format(get_remote_unit_name()))
1111 clear_flag('telegraf.needs_reload')1208 clear_flag('telegraf.needs_reload')
@@ -1130,10 +1227,12 @@ def update_status():
1130 hash_type='sha256')1227 hash_type='sha256')
1131 if changed:1228 if changed:
1132 clear_flag('telegraf.configured')1229 clear_flag('telegraf.configured')
1230 clear_flag('telegraf.apt.configured')
1231 clear_flag('telegraf.snap.configured')
11331232
11341233
1135@when('nrpe-external-master.available')1234@when('nrpe-external-master.available')
1136@when('apt.installed.telegraf')1235@when('telegraf.installed')
1137@when('telegraf.configured')1236@when('telegraf.configured')
1138@when_not('telegraf.nagios-setup.complete')1237@when_not('telegraf.nagios-setup.complete')
1139def configure_nagios(nagios):1238def configure_nagios(nagios):
diff --git a/tests/bundles/focal-snap.yaml b/tests/bundles/focal-snap.yaml
1140new file mode 1006441239new file mode 100644
index 0000000..cfd7e2a
--- /dev/null
+++ b/tests/bundles/focal-snap.yaml
@@ -0,0 +1,14 @@
1series: focal
2
3applications:
4 telegraf:
5 num_units: 0
6 options:
7 install_method: 'snap'
8 ubuntu:
9 charm: cs:ubuntu
10 num_units: 1
11
12relations:
13 - - ubuntu:juju-info
14 - telegraf:juju-info
diff --git a/tests/test_telegraf.py b/tests/test_telegraf.py
index 592f415..19feb41 100644
--- a/tests/test_telegraf.py
+++ b/tests/test_telegraf.py
@@ -29,7 +29,8 @@ DEFAULT_HTTPGET_TIMEOUT = 10
29DEFAULT_RETRIES = 1229DEFAULT_RETRIES = 12
30DEFAULT_RETRIES_TIMEOUT = 530DEFAULT_RETRIES_TIMEOUT = 5
31DEFAULT_TELEGRAF_EXPORTER_PORT = "9103"31DEFAULT_TELEGRAF_EXPORTER_PORT = "9103"
32TELEGRAF_CONF = "/etc/telegraf/telegraf.conf"32DEB_TELEGRAF_CONF = "/etc/telegraf/telegraf.conf"
33SNAP_TELEGRAF_CONF = "/var/snap/telegraf/current/telegraf.conf"
3334
3435
35class BaseTelegrafTest(unittest.TestCase):36class BaseTelegrafTest(unittest.TestCase):
@@ -53,11 +54,6 @@ class TestTelegraf(BaseTelegrafTest):
53 # findall returns a list, [] when no match54 # findall returns a list, [] when no match
54 self.assertTrue(re.findall(re_pattern, text, flags=re.M))55 self.assertTrue(re.findall(re_pattern, text, flags=re.M))
5556
56 def check_re_pattern(self, re_pattern, text):
57 logging.info('checking metrics %s', re_pattern)
58 # findall returns a list, [] when no match
59 self.assertTrue(re.findall(re_pattern, text, flags=re.M))
60
61 def test_01_service(self):57 def test_01_service(self):
62 principal_units = (model.get_units(app)58 principal_units = (model.get_units(app)
63 for app in juju.get_principle_applications(self.application_name))59 for app in juju.get_principle_applications(self.application_name))
@@ -99,15 +95,35 @@ class TestTelegraf(BaseTelegrafTest):
99 self.fail(msg)95 self.fail(msg)
10096
101 def test_02_telegraf_logfile(self):97 def test_02_telegraf_logfile(self):
102 """Check logfile parameter exists in /etc/telegraf/telegraf.conf."""98 """Check logfile parameter exists in ${BASE_DIR}/telegraf.conf."""
103 cmd = "cat {}".format(TELEGRAF_CONF)99 install_method = model.get_application_config('telegraf')['install_method']['value']
100 if install_method == 'deb':
101 telegraf_conf = DEB_TELEGRAF_CONF
102 else:
103 telegraf_conf = SNAP_TELEGRAF_CONF
104 cmd = "cat {}".format(telegraf_conf)
104 response = model.run_on_unit(self.lead_unit_name, cmd)105 response = model.run_on_unit(self.lead_unit_name, cmd)
105 if response["Code"] != "0":106 if response["Code"] != "0":
106 self.fail("test_02_telegraf_logfile: could not read file {}".format(TELEGRAF_CONF))107 self.fail("test_02_telegraf_logfile: could not read file {}".format(telegraf_conf))
107108
108 for line in response["Stdout"].splitlines():109 for line in response["Stdout"].splitlines():
109 if line.strip() == 'logfile = "/var/log/telegraf/telegraf.log"':110 if line.strip() == 'logfile = "/var/log/telegraf/telegraf.log"':
110 logging.info("test_02_telegraf_logfile: logfile config parameter found")111 logging.info("test_02_telegraf_logfile: logfile config parameter found")
111 return112 return
112113
113 self.fail("test_02_telegraf_logfile: logfile parameter not found in {}".format(TELEGRAF_CONF))114 self.fail("test_02_telegraf_logfile: logfile parameter not found in {}".format(telegraf_conf))
115
116 def test_03_system_service(self):
117 """Check that the right service is running, e.g. either the deb's or the snap's."""
118 install_method = model.get_application_config('telegraf')['install_method']['value']
119 services = {'deb': 'telegraf', 'snap': 'snap.telegraf.telegraf'}
120 for method in services.keys():
121 service = services[method]
122 cmd = "service {} status".format(service)
123 response = model.run_on_unit(self.lead_unit_name, cmd)
124 if install_method == method and response["Code"] != "0":
125 self.fail("test_03_system_service: service {} should be running on {} but is not. "
126 "install_method is {}.".format(service, self.lead_unit_name, install_method))
127 elif install_method != method and response["Code"] == "0":
128 self.fail("test_03_system_service: service {} is running on {} but shouldn't. "
129 "install_method is {}.".format(service, self.lead_unit_name, install_method))
diff --git a/tests/tests.yaml b/tests/tests.yaml
index 57e7325..2230082 100644
--- a/tests/tests.yaml
+++ b/tests/tests.yaml
@@ -6,6 +6,7 @@ gate_bundles:
6 - bionic-postgres6 - bionic-postgres
7 - bionic-monitoring7 - bionic-monitoring
8 - focal8 - focal
9 - focal-snap
9smoke_bundles:10smoke_bundles:
10 - bionic-postgres11 - bionic-postgres
11 - focal12 - focal
diff --git a/unit_tests/test_mysql.py b/unit_tests/test_mysql.py
index e28973c..0904e94 100644
--- a/unit_tests/test_mysql.py
+++ b/unit_tests/test_mysql.py
@@ -61,8 +61,10 @@ class TestMySQL(unittest.TestCase):
61 @patch('reactive.telegraf.render_extra_options')61 @patch('reactive.telegraf.render_extra_options')
62 @patch('charmhelpers.core.host.write_file')62 @patch('charmhelpers.core.host.write_file')
63 @patch('reactive.telegraf.get_templates_dir')63 @patch('reactive.telegraf.get_templates_dir')
64 def test_render_mysql_tmpl(self, get_templates_dir, write_file,64 @patch('reactive.telegraf.get_base_dir')
65 def test_render_mysql_tmpl(self, get_base_dir, get_templates_dir, write_file,
65 extra_options):66 extra_options):
67 get_base_dir.return_value = '/etc/telegraf'
66 get_templates_dir.return_value = os.path.join(68 get_templates_dir.return_value = os.path.join(
67 os.path.dirname(__file__), '..', 'templates')69 os.path.dirname(__file__), '..', 'templates')
68 extra_options.return_value = ''70 extra_options.return_value = ''
@@ -81,8 +83,10 @@ class TestMySQL(unittest.TestCase):
8183
82 @patch('os.unlink')84 @patch('os.unlink')
83 @patch('os.path.exists')85 @patch('os.path.exists')
84 def test_render_mysql_tmpl_no_context(self, exists, unlink):86 @patch('reactive.telegraf.get_base_dir')
87 def test_render_mysql_tmpl_no_context(self, get_base_dir, exists, unlink):
85 exists.return_value = False88 exists.return_value = False
89 get_base_dir.return_value = '/etc/telegraf'
86 reactive.telegraf.render_mysql_tmpl([])90 reactive.telegraf.render_mysql_tmpl([])
87 exists.assert_called_once_with(91 exists.assert_called_once_with(
88 '/etc/telegraf/telegraf.d/mysql.conf'92 '/etc/telegraf/telegraf.d/mysql.conf'
diff --git a/unit_tests/test_postgresql.py b/unit_tests/test_postgresql.py
index 1c56a0c..a0423c7 100644
--- a/unit_tests/test_postgresql.py
+++ b/unit_tests/test_postgresql.py
@@ -21,8 +21,14 @@ from unittest.mock import ANY, call, MagicMock, patch, sentinel
2121
22# Mock layer modules22# Mock layer modules
23import charms23import charms
24apt = MagicMock()
25layer = MagicMock()
24promreg = MagicMock()26promreg = MagicMock()
27charms.apt = apt
28charms.layer = layer
25charms.promreg = promreg29charms.promreg = promreg
30sys.modules['charms.apt'] = apt
31sys.modules['charms.layer'] = layer
26sys.modules['charms.promreg'] = promreg32sys.modules['charms.promreg'] = promreg
2733
28import reactive34import reactive
@@ -88,9 +94,11 @@ class TestPostgreSQL(unittest.TestCase):
8894
89 @patch('charmhelpers.core.host.write_file')95 @patch('charmhelpers.core.host.write_file')
90 @patch('reactive.telegraf.get_templates_dir')96 @patch('reactive.telegraf.get_templates_dir')
91 def test_render_postgresql_tmpl(self, get_templates_dir, write_file):97 @patch('reactive.telegraf.get_base_dir')
98 def test_render_postgresql_tmpl(self, get_base_dir, get_templates_dir, write_file):
92 get_templates_dir.return_value = os.path.join(99 get_templates_dir.return_value = os.path.join(
93 os.path.dirname(__file__), '..', 'templates')100 os.path.dirname(__file__), '..', 'templates')
101 get_base_dir.return_value = '/etc/telegraf'
94102
95 reactive.telegraf.render_postgresql_tmpl([103 reactive.telegraf.render_postgresql_tmpl([
96 {'replica': 'master',104 {'replica': 'master',
@@ -104,10 +112,12 @@ class TestPostgreSQL(unittest.TestCase):
104112
105 @patch('charmhelpers.core.host.write_file')113 @patch('charmhelpers.core.host.write_file')
106 @patch('reactive.telegraf.get_templates_dir')114 @patch('reactive.telegraf.get_templates_dir')
107 def test_render_postgresql_tmpl_extra_options(self, get_templates_dir,115 @patch('reactive.telegraf.get_base_dir')
116 def test_render_postgresql_tmpl_extra_options(self, get_base_dir, get_templates_dir,
108 write_file):117 write_file):
109 get_templates_dir.return_value = os.path.join(118 get_templates_dir.return_value = os.path.join(
110 os.path.dirname(__file__), '..', 'templates')119 os.path.dirname(__file__), '..', 'templates')
120 get_base_dir.return_value = '/etc/telegraf'
111121
112 pg_extra_opts = {122 pg_extra_opts = {
113 "tagexclude": ["server"],123 "tagexclude": ["server"],
@@ -144,8 +154,10 @@ class TestPostgreSQL(unittest.TestCase):
144154
145 @patch('os.unlink')155 @patch('os.unlink')
146 @patch('os.path.exists')156 @patch('os.path.exists')
147 def test_render_postgresql_tmpl_no_context(self, exists, unlink):157 @patch('reactive.telegraf.get_base_dir')
158 def test_render_postgresql_tmpl_no_context(self, get_base_dir, exists, unlink):
148 exists.return_value = False159 exists.return_value = False
160 get_base_dir.return_value = '/etc/telegraf'
149 reactive.telegraf.render_postgresql_tmpl([])161 reactive.telegraf.render_postgresql_tmpl([])
150 exists.assert_called_once_with(162 exists.assert_called_once_with(
151 '/etc/telegraf/telegraf.d/postgresql.conf'163 '/etc/telegraf/telegraf.d/postgresql.conf'
diff --git a/unit_tests/test_telegraf.py b/unit_tests/test_telegraf.py
index b4860ac..71af731 100644
--- a/unit_tests/test_telegraf.py
+++ b/unit_tests/test_telegraf.py
@@ -46,18 +46,19 @@ from reactive import telegraf
46UNIT_TESTS_DIR = os.path.dirname(os.path.abspath(__file__))46UNIT_TESTS_DIR = os.path.dirname(os.path.abspath(__file__))
47UNIT_TESTS_DATA_DIR = os.path.join(UNIT_TESTS_DIR, 'data')47UNIT_TESTS_DATA_DIR = os.path.join(UNIT_TESTS_DIR, 'data')
4848
49
49@pytest.fixture(autouse=True)50@pytest.fixture(autouse=True)
50def setup(monkeypatch, tmpdir):51def setup(monkeypatch, tmpdir):
51 monkeypatch.setitem(os.environ, 'JUJU_UNIT_NAME', 'telegraf/0')52 monkeypatch.setitem(os.environ, 'JUJU_UNIT_NAME', 'telegraf/0')
52 monkeypatch.setitem(os.environ, 'JUJU_MODEL_NAME', 'telegraf-test-model')53 monkeypatch.setitem(os.environ, 'JUJU_MODEL_NAME', 'telegraf-test-model')
53 monkeypatch.setattr(telegraf, 'get_remote_unit_name', lambda: 'remote-unit/0')54 monkeypatch.setattr(telegraf, 'get_remote_unit_name', lambda: 'remote-unit/0')
54 monkeypatch.setattr(telegraf, 'exec_timeout_supported', lambda: True)
55 # mock this to avoid permission errors55 # mock this to avoid permission errors
56 monkeypatch.setattr(telegraf, 'update_sysstat_config_with_sdac_xall', lambda: True)56 monkeypatch.setattr(telegraf, 'update_sysstat_config_with_sdac_xall', lambda: True)
57 monkeypatch.setattr(telegraf.hookenv, 'status_set', lambda status, msg: None)57 monkeypatch.setattr(telegraf.hookenv, 'status_set', lambda status, msg: None)
58 monkeypatch.setattr(telegraf.hookenv, 'log', lambda msg, **kw: None)58 monkeypatch.setattr(telegraf.hookenv, 'log', lambda msg, **kw: None)
59 monkeypatch.setattr(telegraf.host, 'service_resume', lambda svc: None)59 monkeypatch.setattr(telegraf.host, 'service_resume', lambda svc: None)
60 monkeypatch.setattr(telegraf.host, 'service_reload', lambda svc: None)60 monkeypatch.setattr(telegraf.host, 'service_reload', lambda svc: None)
61 monkeypatch.setattr(telegraf.host, 'service_pause', lambda svc: None)
6162
62 # patch host.write for non-root63 # patch host.write for non-root
63 user = getpass.getuser()64 user = getpass.getuser()
@@ -113,7 +114,7 @@ def temp_charm_dir(monkeypatch, tmpdir):
113def temp_config_dir(monkeypatch, tmpdir):114def temp_config_dir(monkeypatch, tmpdir):
114 base_dir = tmpdir.mkdir("etc_telegraf")115 base_dir = tmpdir.mkdir("etc_telegraf")
115 base_dir.mkdir(telegraf.CONFIG_DIR)116 base_dir.mkdir(telegraf.CONFIG_DIR)
116 monkeypatch.setattr(telegraf, 'BASE_DIR', base_dir.strpath)117 monkeypatch.setattr(telegraf, 'DEB_BASE_DIR', base_dir.strpath)
117118
118119
119@pytest.fixture(autouse=True)120@pytest.fixture(autouse=True)
@@ -127,7 +128,7 @@ def config(monkeypatch, temp_charm_dir):
127128
128# utilities129# utilities
129def base_dir():130def base_dir():
130 return py.path.local(telegraf.BASE_DIR)131 return py.path.local(telegraf.DEB_BASE_DIR)
131132
132133
133def configs_dir():134def configs_dir():
@@ -872,24 +873,6 @@ def test_exec_input_leader_no_more(mocker, monkeypatch):
872 assert not configs_dir().join('exec.conf').exists()873 assert not configs_dir().join('exec.conf').exists()
873874
874875
875def test_exec_input_no_timeout_support(mocker, monkeypatch):
876 interface = mocker.Mock(spec=RelationBase)
877 interface.commands = mocker.Mock()
878 commands = [{'commands': ['/srv/bin/test.sh', '/bin/true'],
879 'data_format': 'json',
880 'timeout': '5s',
881 'run_on_this_unit': True}]
882 interface.commands.return_value = commands
883 expected = """
884[[inputs.exec]]
885 commands = ['/srv/bin/test.sh', '/bin/true']
886 data_format = "json"
887"""
888 monkeypatch.setattr(telegraf, 'exec_timeout_supported', lambda: False)
889 telegraf.exec_input(interface)
890 assert configs_dir().join('exec.conf').read().strip() == expected.strip()
891
892
893def test_exec_input_departed(mocker, monkeypatch):876def test_exec_input_departed(mocker, monkeypatch):
894 configs_dir().join('exec.conf').write('empty')877 configs_dir().join('exec.conf').write('empty')
895 relations = [1]878 relations = [1]
@@ -969,7 +952,7 @@ def test_basic_config(mocker, monkeypatch, config):
969 bus.dispatch()952 bus.dispatch()
970 assert 'telegraf.configured' in bus.get_states().keys()953 assert 'telegraf.configured' in bus.get_states().keys()
971 assert base_dir().join('telegraf.conf').exists()954 assert base_dir().join('telegraf.conf').exists()
972 service_restart.assert_called_once_with('telegraf')955 service_restart.assert_called_once_with(telegraf.DEB_SERVICE)
973 check_prometheus_port.assert_called_once_with('prometheus_output', 9103)956 check_prometheus_port.assert_called_once_with('prometheus_output', 9103)
974957
975958
@@ -984,7 +967,7 @@ def test_config_no_prometheus(mocker, monkeypatch, config):
984 bus.dispatch()967 bus.dispatch()
985 assert 'telegraf.configured' in bus.get_states().keys()968 assert 'telegraf.configured' in bus.get_states().keys()
986 assert base_dir().join('telegraf.conf').exists()969 assert base_dir().join('telegraf.conf').exists()
987 service_restart.assert_called_once_with('telegraf')970 service_restart.assert_called_once_with(telegraf.DEB_SERVICE)
988 assert not check_prometheus_port.called971 assert not check_prometheus_port.called
989972
990973
@@ -996,7 +979,7 @@ def test_config_changed_apt(mocker, monkeypatch, config):
996 set_flag('apt.installed.telegraf')979 set_flag('apt.installed.telegraf')
997 set_flag('config.changed')980 set_flag('config.changed')
998 bus.dispatch()981 bus.dispatch()
999 service_restart.assert_called_once_with('telegraf')982 service_restart.assert_called_once_with(telegraf.DEB_SERVICE)
1000983
1001984
1002def test_config_changed_extra_options(mocker, monkeypatch, config):985def test_config_changed_extra_options(mocker, monkeypatch, config):
@@ -1004,7 +987,7 @@ def test_config_changed_extra_options(mocker, monkeypatch, config):
1004 monkeypatch.setattr(telegraf.host, 'service_running',987 monkeypatch.setattr(telegraf.host, 'service_running',
1005 lambda n: True)988 lambda n: True)
1006 mocker.patch('reactive.telegraf.check_prometheus_port')989 mocker.patch('reactive.telegraf.check_prometheus_port')
1007 set_flag('telegraf.installed')990 set_flag('apt.telegraf.installed')
1008 set_flag('plugins.haproxy.configured')991 set_flag('plugins.haproxy.configured')
1009 config.save()992 config.save()
1010 config.load_previous()993 config.load_previous()
@@ -1013,7 +996,7 @@ def test_config_changed_extra_options(mocker, monkeypatch, config):
1013 set_flag('config.changed')996 set_flag('config.changed')
1014 bus.dispatch()997 bus.dispatch()
1015 assert 'plugins.haproxy.configured' not in bus.get_states().keys()998 assert 'plugins.haproxy.configured' not in bus.get_states().keys()
1016 service_restart.assert_called_once_with('telegraf')999 service_restart.assert_called_once_with(telegraf.DEB_SERVICE)
10171000
10181001
1019def test_config_changed_extra_plugins(mocker, monkeypatch, config):1002def test_config_changed_extra_plugins(mocker, monkeypatch, config):
@@ -1021,7 +1004,7 @@ def test_config_changed_extra_plugins(mocker, monkeypatch, config):
1021 monkeypatch.setattr(telegraf.host, 'service_running',1004 monkeypatch.setattr(telegraf.host, 'service_running',
1022 lambda n: True)1005 lambda n: True)
1023 mocker.patch('reactive.telegraf.check_prometheus_port')1006 mocker.patch('reactive.telegraf.check_prometheus_port')
1024 set_flag('telegraf.installed')1007 set_flag('apt.telegraf.installed')
1025 assert not configs_dir().join('extra_plugins.conf').exists()1008 assert not configs_dir().join('extra_plugins.conf').exists()
1026 config.save()1009 config.save()
1027 config.load_previous()1010 config.load_previous()
@@ -1037,7 +1020,7 @@ def test_config_changed_extra_plugins(mocker, monkeypatch, config):
1037 bus.dispatch()1020 bus.dispatch()
1038 assert configs_dir().join('extra_plugins.conf').exists()1021 assert configs_dir().join('extra_plugins.conf').exists()
1039 assert configs_dir().join('extra_plugins.conf').read() == config['extra_plugins']1022 assert configs_dir().join('extra_plugins.conf').read() == config['extra_plugins']
1040 service_restart.assert_called_with('telegraf')1023 service_restart.assert_called_with(telegraf.DEB_SERVICE)
10411024
10421025
1043def test_restart_on_output_plugin_relation_departed(mocker, monkeypatch, config):1026def test_restart_on_output_plugin_relation_departed(mocker, monkeypatch, config):
@@ -1056,7 +1039,7 @@ def test_restart_on_output_plugin_relation_departed(mocker, monkeypatch, config)
1056 return_value={"ingress_addresses": ["1.2.3.4"]})1039 return_value={"ingress_addresses": ["1.2.3.4"]})
1057 config['prometheus_output_port'] = ''1040 config['prometheus_output_port'] = ''
1058 bus.discover()1041 bus.discover()
1059 set_flag('telegraf.installed')1042 set_flag('snap.telegraf.installed')
1060 set_flag('telegraf.configured')1043 set_flag('telegraf.configured')
1061 interface = mocker.Mock(spec=RelationBase)1044 interface = mocker.Mock(spec=RelationBase)
1062 interface.configure = mocker.Mock()1045 interface.configure = mocker.Mock()
@@ -1065,7 +1048,7 @@ def test_restart_on_output_plugin_relation_departed(mocker, monkeypatch, config)
1065 # dispatch, file should be gone and telegraf restarted.1048 # dispatch, file should be gone and telegraf restarted.
1066 bus.dispatch()1049 bus.dispatch()
1067 assert not configs_dir().join('prometheus-client.conf').exists()1050 assert not configs_dir().join('prometheus-client.conf').exists()
1068 service_restart.assert_called_with('telegraf')1051 service_restart.assert_called_with(telegraf.DEB_SERVICE)
10691052
10701053
1071def test_upgrade_charm(mocker):1054def test_upgrade_charm(mocker):
@@ -1074,10 +1057,12 @@ def test_upgrade_charm(mocker):
1074 list_plugins.return_value = ['foo', 'bar']1057 list_plugins.return_value = ['foo', 'bar']
1075 telegraf.upgrade_charm()1058 telegraf.upgrade_charm()
1076 clear_flag.assert_any_call('telegraf.configured')1059 clear_flag.assert_any_call('telegraf.configured')
1060 clear_flag.assert_any_call('telegraf.apt.configured')
1061 clear_flag.assert_any_call('telegraf.snap.configured')
1077 clear_flag.assert_any_call('plugins.foo.configured')1062 clear_flag.assert_any_call('plugins.foo.configured')
1078 clear_flag.assert_any_call('plugins.bar.configured')1063 clear_flag.assert_any_call('plugins.bar.configured')
1079 clear_flag.assert_any_call('extra_plugins.configured')1064 clear_flag.assert_any_call('extra_plugins.configured')
1080 assert clear_flag.call_count == 41065 assert clear_flag.call_count == 6
10811066
10821067
1083def test_get_socket_listener_port(monkeypatch, config):1068def test_get_socket_listener_port(monkeypatch, config):

Subscribers

People subscribed via source and target branches

to all changes: