Merge ~hloeung/influxdb-charm:master into influxdb-charm:master

Proposed by Haw Loeung
Status: Merged
Merged at revision: c4731b9410873ec304103f52ae3197d5e7360626
Proposed branch: ~hloeung/influxdb-charm:master
Merge into: influxdb-charm:master
Diff against target: 347 lines (+136/-67)
4 files modified
Makefile (+1/-1)
config.yaml (+11/-2)
files/influxdb.conf (+32/-40)
reactive/influxdb.py (+92/-24)
Reviewer Review Type Date Requested Status
Paul Collins lgtm Approve
Review via email: mp+333123@code.launchpad.net

Description of the change

Allow overriding configs with extra_config

There's a lot of configuration options to tune and set, instead of
implementing all of them as charm config options, we use
extra_config. This is basically section.config=value. For example, to
change/set the below:

| [http]
| auth-enabled = true

We can use this:

| extra_config:
| - http.auth-enabled=true

To post a comment you must log in.
Revision history for this message
Haw Loeung (hloeung) wrote :

$ juju config influxdb ip_address='127.0.0.1'

| ubuntu@juju-b884ff-canonistack-haw-lcy02-4:~$ diff -Naurp /etc/influxdb/{influxdb.conf.orig,influxdb.conf}
| --- /etc/influxdb/influxdb.conf.orig 2017-11-03 00:10:10.743762811 +0000
| +++ /etc/influxdb/influxdb.conf 2017-11-03 00:22:05.160094893 +0000
| @@ -201,7 +201,7 @@
| # enabled = true
|
| # The bind address used by the HTTP service.
| - # bind-address = ":8086"
| + bind-address = "127.0.0.1:8086"
|
| # Determines whether user authentication is enabled over HTTP/HTTPS.
| # auth-enabled = false
| ===

$ juju config influxdb ip_address='127.0.0.1' bind_port='8087'

| ubuntu@juju-b884ff-canonistack-haw-lcy02-4:~$ diff -Naurp /etc/influxdb/{influxdb.conf.orig,influxdb.conf}
| --- /etc/influxdb/influxdb.conf.orig 2017-11-03 00:10:10.743762811 +0000
| +++ /etc/influxdb/influxdb.conf 2017-11-03 00:24:00.227707065 +0000
| @@ -201,7 +201,7 @@
| # enabled = true
|
| # The bind address used by the HTTP service.
| - # bind-address = ":8086"
| + bind-address = "127.0.0.1:8087"
|
| # Determines whether user authentication is enabled over HTTP/HTTPS.
| # auth-enabled = false

$ juju config influxdb extra_config="- global.hostname=myhost
- http.auth-enabled=true
- data.max-series-per-database=0
"

| ubuntu@juju-b884ff-canonistack-haw-lcy02-4:~$ diff -Naurp /etc/influxdb/{influxdb.conf.orig,influxdb.conf}
| --- /etc/influxdb/influxdb.conf.orig 2017-11-03 00:10:10.743762811 +0000
| +++ /etc/influxdb/influxdb.conf 2017-11-03 00:25:45.242181284 +0000
| @@ -14,6 +14,8 @@
| # Bind address to use for the RPC service for backup and restore.
| # bind-address = "127.0.0.1:8088"
|
| +hostname = "myhost"
| +
| ###
| ### [meta]
| ###
| @@ -95,7 +97,7 @@
| # The maximum series allowed per database before writes are dropped. This limit can prevent
| # high cardinality issues at the database level. This limit can be disabled by setting it to
| # 0.
| - # max-series-per-database = 1000000
| + max-series-per-database = 0
|
| # The maximum number of tag values per tag that are allowed before writes are dropped. This limit
| # can prevent high cardinality tag values from being written to a measurement. This limit can be
| @@ -204,7 +206,7 @@
| # bind-address = ":8086"
|
| # Determines whether user authentication is enabled over HTTP/HTTPS.
| - # auth-enabled = false
| + auth-enabled = true
|
| # The default realm sent back when issuing a basic auth challenge.
| # realm = "InfluxDB"

Revision history for this message
Paul Collins (pjdc) :
review: Approve (lgtm)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/Makefile b/Makefile
2index 5dd0577..efec4a7 100644
3--- a/Makefile
4+++ b/Makefile
5@@ -12,7 +12,7 @@ clean:
6 rm -f $(REACTIVE_DIR)/*.pyc
7
8 lint:
9- @flake8 $(REACTIVE_DIR)
10+ @flake8 --max-line-length=120 $(REACTIVE_DIR)
11
12 git:
13 git push $(PERSONAL_REPO)
14diff --git a/config.yaml b/config.yaml
15index 917e93a..840eb7b 100644
16--- a/config.yaml
17+++ b/config.yaml
18@@ -62,7 +62,7 @@ options:
19 ip_address:
20 description: "Which IP to bind on"
21 type: string
22- default: "0.0.0.0"
23+ default: ""
24 bind_port:
25 description: "Which port to bind to"
26 type: int
27@@ -80,4 +80,13 @@ options:
28 default: 1000000
29 description: |
30 Maximum series allowed per database before writes are dropped.
31- Specify 0 for no limit.
32+ Specify 0 for no limit. (DEPRECATED) Please use extra_config instead.
33+ extra_config:
34+ type: string
35+ default: ""
36+ description: |
37+ YAML-formatted list of extra configuration options to override.
38+ For example:
39+ - global.hostname=myhost
40+ - http.auth-enabled=true
41+ - data.max-series-per-database=0
42diff --git a/templates/influxdb.conf b/files/influxdb.conf
43index 77ed982..23c4e03 100644
44--- a/templates/influxdb.conf
45+++ b/files/influxdb.conf
46@@ -1,8 +1,8 @@
47 ### Welcome to the InfluxDB configuration file.
48
49 # The values in this file override the default values used by the system if
50-# a config option is not specified. The commented out lines are the the configuration
51-# field and the default value used. Uncommentting a line and changing the value
52+# a config option is not specified. The commented out lines are the configuration
53+# field and the default value used. Uncommenting a line and changing the value
54 # will change the value used at runtime when the process is restarted.
55
56 # Once every 24 hours InfluxDB will report usage data to usage.influxdata.com
57@@ -11,10 +11,8 @@
58 # Change this option to true to disable reporting.
59 # reporting-disabled = false
60
61-# we'll try to get the hostname automatically, but if it the os returns something
62-# that isn't resolvable by other servers in the cluster, use this option to
63-# manually set the hostname
64-# hostname = "localhost"
65+# Bind address to use for the RPC service for backup and restore.
66+# bind-address = "127.0.0.1:8088"
67
68 ###
69 ### [meta]
70@@ -49,6 +47,18 @@
71 # The directory where the TSM storage engine stores WAL files.
72 wal-dir = "/var/lib/influxdb/wal"
73
74+ # The amount of time that a write will wait before fsyncing. A duration
75+ # greater than 0 can be used to batch up multiple fsync calls. This is useful for slower
76+ # disks or when WAL write contention is seen. A value of 0s fsyncs every write to the WAL.
77+ # Values in the range of 0-100ms are recommended for non-SSD disks.
78+ # wal-fsync-delay = "0s"
79+
80+
81+ # The type of shard index to use for new shards. The default is an in-memory index that is
82+ # recreated at startup. A value of "tsi1" will use a disk based index that supports higher
83+ # cardinality datasets.
84+ # index-version = "inmem"
85+
86 # Trace logging provides more verbose output around the tsm engine. Turning
87 # this on can provide more useful output for debugging tsm engine issues.
88 # trace-logging-enabled = false
89@@ -77,10 +87,15 @@
90 # write or delete
91 # compact-full-write-cold-duration = "4h"
92
93+ # The maximum number of concurrent full and level compactions that can run at one time. A
94+ # value of 0 results in runtime.GOMAXPROCS(0) used at runtime. This setting does not apply
95+ # to cache snapshotting.
96+ # max-concurrent-compactions = 0
97+
98 # The maximum series allowed per database before writes are dropped. This limit can prevent
99 # high cardinality issues at the database level. This limit can be disabled by setting it to
100 # 0.
101- max-series-per-database = {{max_series_per_database}}
102+ # max-series-per-database = 1000000
103
104 # The maximum number of tag values per tag that are allowed before writes are dropped. This limit
105 # can prevent high cardinality tag values from being written to a measurement. This limit can be
106@@ -106,22 +121,20 @@
107 # can help prevent run away queries. Setting the value to 0 disables the limit.
108 # query-timeout = "0s"
109
110- # The the time threshold when a query will be logged as a slow query. This limit can be set to help
111+ # The time threshold when a query will be logged as a slow query. This limit can be set to help
112 # discover slow or resource intensive queries. Setting the value to 0 disables the slow query logging.
113 # log-queries-after = "0s"
114
115- # The maximum number of points a SELECT can process. A value of 0 will make the maximum
116- # point count unlimited.
117+ # The maximum number of points a SELECT can process. A value of 0 will make
118+ # the maximum point count unlimited. This will only be checked every 10 seconds so queries will not
119+ # be aborted immediately when hitting the limit.
120 # max-select-point = 0
121
122 # The maximum number of series a SELECT can run. A value of 0 will make the maximum series
123 # count unlimited.
124-
125- # The maximum number of series a SELECT can run. A value of zero will make the maximum series
126- # count unlimited.
127 # max-select-series = 0
128
129- # The maxium number of group by time bucket a SELECt can create. A value of zero will max the maximum
130+ # The maxium number of group by time bucket a SELECT can create. A value of zero will max the maximum
131 # number of buckets unlimited.
132 # max-select-buckets = 0
133
134@@ -132,7 +145,7 @@
135 ###
136
137 [retention]
138- # Determines whether retention policy enforcment enabled.
139+ # Determines whether retention policy enforcement enabled.
140 # enabled = true
141
142 # The interval of time when retention policy enforcement checks run.
143@@ -177,27 +190,6 @@
144 # store-interval = "10s"
145
146 ###
147-### [admin]
148-###
149-### Controls the availability of the built-in, web-based admin interface. If HTTPS is
150-### enabled for the admin interface, HTTPS must also be enabled on the [http] service.
151-###
152-### NOTE: This interface is deprecated as of 1.1.0 and will be removed in a future release.
153-
154-[admin]
155- # Determines whether the admin service is enabled.
156- enabled = {{ admin }}
157-
158- # The default bind address used by the admin service.
159- # bind-address = ":8083"
160-
161- # Whether the admin service should use HTTPS.
162- # https-enabled = false
163-
164- # The SSL certificate used when HTTPS is enabled.
165- # https-certificate = "/etc/ssl/influxdb.pem"
166-
167-###
168 ### [http]
169 ###
170 ### Controls how the HTTP endpoints are configured. These are the primary
171@@ -209,15 +201,15 @@
172 # enabled = true
173
174 # The bind address used by the HTTP service.
175- bind-address = "{{ip_address}}:{{bind_port}}"
176+ # bind-address = ":8086"
177
178- # Determines whether HTTP authentication is enabled.
179+ # Determines whether user authentication is enabled over HTTP/HTTPS.
180 # auth-enabled = false
181
182 # The default realm sent back when issuing a basic auth challenge.
183 # realm = "InfluxDB"
184
185- # Determines whether HTTP request logging is enable.d
186+ # Determines whether HTTP request logging is enabled.
187 # log-enabled = true
188
189 # Determines whether detailed write logging is enabled.
190@@ -429,7 +421,7 @@
191 ###
192
193 [continuous_queries]
194- # Determiens whether the continuous query service is enabled.
195+ # Determines whether the continuous query service is enabled.
196 # enabled = true
197
198 # Controls whether queries are logged when executed by the CQ service.
199diff --git a/reactive/influxdb.py b/reactive/influxdb.py
200index 856c9bb..a8394de 100644
201--- a/reactive/influxdb.py
202+++ b/reactive/influxdb.py
203@@ -1,11 +1,13 @@
204 from charmhelpers.contrib.charmsupport import nrpe
205-from charmhelpers.core.host import service_start, service_stop
206 from charmhelpers.core import hookenv
207+from charmhelpers.core import host
208 from charmhelpers.core.templating import render
209-from charms.reactive import hook, set_state, when, when_any, when_not
210+from charms.reactive import hook, set_state, remove_state, when, when_all, when_not
211
212+import re
213 import os
214 import shutil
215+import yaml
216
217 CRONFILE = '/etc/cron.daily/influxdb-charm-backup'
218 CHECK_SRC = 'files/check_influxdb.py'
219@@ -28,29 +30,97 @@ def install_influx():
220 hookenv.open_port(8083)
221 hookenv.open_port(port)
222 config_changed()
223- service_start('influxdb')
224+ host.service_start('influxdb')
225 hookenv.status_set('active', '')
226 set_state('influxdb.configured')
227-
228-
229-@when_any('config.changed.bind_port', 'config.changed.ip_address', 'config.changed.max_series_per_database')
230+ set_state('config.changed')
231+
232+
233+def apply_configs(fh, config):
234+ new_config = []
235+
236+ section = 'global'
237+ indent = ''
238+
239+ section_keys_found = {
240+ 'global': {},
241+ }
242+ initial_comments = True
243+ for line in fh:
244+ # Start after initial comments "Welcome to the InfluxDB configur..."
245+ if initial_comments and not line.startswith('##'):
246+ initial_comments = False
247+ if line.startswith('[') or (not initial_comments and line.startswith('##')):
248+ if section in config:
249+ # If the configs weren't found in this section let's add them.
250+ for key in config[section].keys():
251+ if key in section_keys_found[section]:
252+ break
253+ section_keys_found[section][key] = ''
254+ new_config.append("{}{} = {}\n\n".format(indent, key, config[section][key]))
255+ new_config.append(line)
256+ if line.startswith('['):
257+ section = line[1:][:-2]
258+ # Apart from global config options, indent the rest.
259+ indent = ' '
260+ continue
261+ # Format is 'key = value' or '# key = value'
262+ match = re.match('^([\s#]*)(\S+)(\s*=.*)', line)
263+ if not match:
264+ new_config.append(line)
265+ continue
266+ key = match.group(2)
267+ value = match.group(3)
268+ # Store all config options we found per section.
269+ if section not in section_keys_found:
270+ section_keys_found[section] = {}
271+ section_keys_found[section][key] = ''
272+ if section not in config or key not in config[section]:
273+ # We want to keep {meta,data}.{dir,wal-dir} always.
274+ if section in ['meta', 'data'] and key in ['dir', 'wal-dir']:
275+ new_config.append(line)
276+ else:
277+ new_config.append("{}# {}{}\n".format(indent, key, value))
278+ continue
279+ new_config.append("{}{} = {}\n".format(indent, key, config[section][key]))
280+
281+ return ''.join(new_config)
282+
283+
284+@when_all('influxdb.configured', 'config.changed')
285 def config_changed():
286 config = hookenv.config()
287- port = config.get('bind_port')
288- ip_address = config.get('ip_address')
289- max_series_per_database = config.get('max_series_per_database')
290- render(source='influxdb.conf',
291- target='/etc/influxdb/influxdb.conf',
292- owner='root',
293- perms=0o644,
294- context={
295- 'admin': 'true',
296- 'bind_port': port,
297- 'ip_address': ip_address,
298- 'max_series_per_database': max_series_per_database,
299- })
300- service_stop('influxdb')
301- service_start('influxdb')
302+ conf = {
303+ 'global': {},
304+ }
305+
306+ # Only write out the bind-address if it differs from the default.
307+ if config.get('ip_address') or config.get('bind_port') != 8086:
308+ conf['http'] = {}
309+ conf['http']['bind-address'] = '"{}:{}"'.format(config.get('ip_address', ''),
310+ config.get('bind_port'))
311+
312+ # Construct our dict of configs from the extra_config charm option.
313+ if config.get('extra_config', None):
314+ for c in yaml.safe_load(config.get('extra_config', '[]')):
315+ k, value = c.split('=', 1)
316+ section, key = k.split('.', 1)
317+ if section not in conf:
318+ conf[section] = {}
319+ if str(value) in ('true', 'false') or value.isdigit():
320+ conf[section][key] = value
321+ else:
322+ conf[section][key] = '"{}"'.format(value)
323+
324+ target = '/etc/influxdb/influxdb.conf'
325+ if not os.path.exists(target):
326+ shutil.copy2('files/influxdb.conf', target)
327+ with open(target, 'r') as f:
328+ updated_config = apply_configs(f, conf)
329+ host.write_file(target, updated_config.encode("utf-8"), perms=0o644)
330+
331+ host.service_stop('influxdb')
332+ host.service_start('influxdb')
333
334
335 @when('config.changed.backup_dir')
336@@ -77,10 +147,8 @@ def create_backup_job():
337
338 @hook('upgrade-charm')
339 def upgrade_charm():
340- # Force config changed on upgrade-charm in case one of the templates changed.
341+ remove_state('influxdb.configured')
342 set_state('config.changed.backup_dir')
343- set_state('config.changed.bind_port')
344- set_state('config.changed.ip_address')
345 # If we have an NRPE relation, force run of that as well
346 if hookenv.relation_ids('nrpe-exteral-master'):
347 set_state('nrpe-external-master.available')

Subscribers

People subscribed via source and target branches

to all changes: