Merge ~brad-marshall/charm-prometheus-ceph-exporter/+git/prometheus-ceph-exporter-charm:ceph-relation into ~prometheus-charmers/charm-prometheus-ceph-exporter/+git/prometheus-ceph-exporter-charm:master

Proposed by Brad Marshall
Status: Merged
Merged at revision: 2dd00a08819c9bd6dae823816bbd64e50a379217
Proposed branch: ~brad-marshall/charm-prometheus-ceph-exporter/+git/prometheus-ceph-exporter-charm:ceph-relation
Merge into: ~prometheus-charmers/charm-prometheus-ceph-exporter/+git/prometheus-ceph-exporter-charm:master
Diff against target: 504 lines (+113/-205)
9 files modified
README.md (+1/-0)
config.yaml (+9/-27)
dev/null (+0/-133)
layer.yaml (+10/-15)
metadata.yaml (+5/-1)
reactive/prometheus-ceph-exporter.py (+47/-29)
templates/ceph.conf (+19/-0)
templates/ceph.keyring (+5/-0)
templates/daemon_arguments (+17/-0)
Reviewer Review Type Date Requested Status
Barry Price Approve
Paul Gear (community) Needs Fixing
Review via email: mp+328059@code.launchpad.net

Description of the change

Add in ceph-client relationship so we no longer have to target a ceph-mon node, tidy up the code etc.

To post a comment you must log in.
Revision history for this message
Paul Gear (paulgear) wrote :

This chrm needs disentangling from the snap layer and turning into its own layer before we move forward with it.

review: Needs Fixing
Revision history for this message
Barry Price (barryprice) wrote :

+1 LGTM

review: Approve

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 2559ee3..59a0103 100644
--- a/README.md
+++ b/README.md
@@ -22,6 +22,7 @@ From the MAAS host:
22# Deploy the charm22# Deploy the charm
2323
24 juju deploy local:xenial/prometheus-ceph-exporter24 juju deploy local:xenial/prometheus-ceph-exporter
25 juju add-relation prometheus-ceph-exporter ceph-mon:client
2526
26To change the port, refer to the daemon_arguments provided by the snap package at:27To change the port, refer to the daemon_arguments provided by the snap package at:
27 /var/snap/prometheus-ceph-exporter/current/daemon_arguments28 /var/snap/prometheus-ceph-exporter/current/daemon_arguments
diff --git a/bin/layer_option b/bin/layer_option
28deleted file mode 10075529deleted file mode 100755
index 90dc400..0000000
--- a/bin/layer_option
+++ /dev/null
@@ -1,24 +0,0 @@
1#!/usr/bin/env python3
2
3import sys
4sys.path.append('lib')
5
6import argparse
7from charms.layer import options
8
9
10parser = argparse.ArgumentParser(description='Access layer options.')
11parser.add_argument('section',
12 help='the section, or layer, the option is from')
13parser.add_argument('option',
14 help='the option to access')
15
16args = parser.parse_args()
17value = options(args.section).get(args.option, '')
18if isinstance(value, bool):
19 sys.exit(0 if value else 1)
20elif isinstance(value, list):
21 for val in value:
22 print(val)
23else:
24 print(value)
diff --git a/config.yaml b/config.yaml
index 05b882e..4cf7a63 100644
--- a/config.yaml
+++ b/config.yaml
@@ -1,27 +1,9 @@
1# Copyright 2016 Canonical Ltd.1options:
2#2 username:
3# This file is part of the Snap layer for Juju.3 description: Username to use for ceph mons - defaults to prometheus-ceph-exporter.
4#4 type: string
5# Licensed under the Apache License, Version 2.0 (the "License");5 default: "prometheus-ceph-exporter"
6# you may not use this file except in compliance with the License.6 daemon_arguments:
7# You may obtain a copy of the License at7 description: Daemon arguments to pass to the exporter.
8#8 type: string
9# http://www.apache.org/licenses/LICENSE-2.09 default: ""
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16"options":
17 "snap_proxy":
18 "description": "HTTP/HTTPS web proxy for Snappy to use when accessing the snap\
19 \ store.\n"
20 "type": "string"
21 "default": ""
22 "snap_channel":
23 "default": "stable"
24 "type": "string"
25 "description": |
26 If install_method is set to "snap" this option controlls channel name.
27 Supported values are: "stable", "candidate", "beta" and "edge"
diff --git a/layer.yaml b/layer.yaml
index a3d662a..96ddd93 100644
--- a/layer.yaml
+++ b/layer.yaml
@@ -1,15 +1,10 @@
1"options":1includes: ['layer:basic', 'interface:http', 'layer:snap', 'interface:ceph-client']
2 "basic":2repo: 'https://git.launchpad.net/prometheus-ceph-exporter-charm'
3 "use_venv": !!bool "true"3ignore: ['.*.swp' ]
4 "packages": []4options:
5 "include_system_packages": !!bool "false"5 basic:
6 "snap": {}6 use_venv: true
7 "prometheus-ceph-exporter": {}7 include_system_packages: true
8"includes":8 snap:
9- "layer:basic"9 prometheus-ceph-exporter:
10- "interface:http"10 channel: stable
11- "layer:snap"
12"repo": "https://git.launchpad.net/prometheus-ceph-exporter-charm"
13"ignore":
14 "prometheus-ceph-exporter": [".*.swp"]
15"is": "prometheus-ceph-exporter"
diff --git a/metadata.yaml b/metadata.yaml
index e76e3ef..55f3cf5 100644
--- a/metadata.yaml
+++ b/metadata.yaml
@@ -1,6 +1,6 @@
1name: prometheus-ceph-exporter1name: prometheus-ceph-exporter
2summary: Ceph exporter for Prometheus2summary: Ceph exporter for Prometheus
3maintainer: Giorgio Di Guardia <giorgio.diguardia@canonical.com>3maintainer: Prometheus Charmers <prometheus-charmers@lists.launchpad.net>
4description: |4description: |
5 This is an exporter that exposes information gathered from Ceph5 This is an exporter that exposes information gathered from Ceph
6 for use by the Prometheus monitoring system.6 for use by the Prometheus monitoring system.
@@ -9,7 +9,11 @@ tags:
9 - prometheus9 - prometheus
10series:10series:
11 - xenial11 - xenial
12 - trusty
12subordinate: false13subordinate: false
13provides:14provides:
14 ceph-exporter:15 ceph-exporter:
15 interface: http16 interface: http
17requires:
18 ceph:
19 interface: ceph-client
diff --git a/reactive/__init__.py b/reactive/__init__.py
16deleted file mode 10064420deleted file mode 100644
index e69de29..0000000
--- a/reactive/__init__.py
+++ /dev/null
diff --git a/reactive/prometheus-ceph-exporter.py b/reactive/prometheus-ceph-exporter.py
index c6ba0c9..41e9e69 100644
--- a/reactive/prometheus-ceph-exporter.py
+++ b/reactive/prometheus-ceph-exporter.py
@@ -13,7 +13,7 @@
13# limitations under the License.13# limitations under the License.
1414
15import yaml15import yaml
16import subprocess16import os
1717
18from charmhelpers.core import host, hookenv18from charmhelpers.core import host, hookenv
19from charmhelpers.core.templating import render19from charmhelpers.core.templating import render
@@ -21,37 +21,30 @@ from charms.reactive import (
21 when, when_not, set_state, remove_state21 when, when_not, set_state, remove_state
22)22)
23from charms.reactive.helpers import any_file_changed, data_changed23from charms.reactive.helpers import any_file_changed, data_changed
24from charms.layer import snap24# from charms.layer import snap
2525
26from charmhelpers.fetch import (
27 apt_install,
28)
2629
27SNAP_NAME = 'prometheus-ceph-exporter'30SNAP_NAME = 'prometheus-ceph-exporter'
28SVC_NAME = 'snap.prometheus-ceph-exporter.ceph-exporter'31SVC_NAME = 'snap.prometheus-ceph-exporter.ceph-exporter'
29SNAP_DATA = '/var/snap/' + SNAP_NAME + '/current/'32SNAP_DATA = '/var/snap/' + SNAP_NAME + '/current/'
30PORT_DEF = 912833PORT_DEF = 9128
3134
35
32def templates_changed(tmpl_list):36def templates_changed(tmpl_list):
33 return any_file_changed(['templates/{}'.format(x) for x in tmpl_list])37 return any_file_changed(['templates/{}'.format(x) for x in tmpl_list])
3438
3539
36@when_not('ceph-exporter.installed')
37def install_packages():
38 hookenv.status_set('maintenance', 'Installing software')
39 config = hookenv.config()
40 channel = config.get('snap_channel', 'stable')
41 snap.install(SNAP_NAME, channel=channel, force_dangerous=False)
42 set_state('ceph-exporter.do-auth-config')
43 set_state('ceph-exporter.installed')
44 set_state('ceph-exporter.do-check-reconfig')
45
46
47def validate_config(filename):40def validate_config(filename):
48 return yaml.safe_load(open(filename))41 return yaml.safe_load(open(filename))
4942
5043
51@when('ceph-exporter.installed')44@when('snap.installed.prometheus-ceph-exporter')
52@when('ceph-exporter.do-reconfig-yaml')45@when('ceph-exporter.do-reconfig-yaml')
53def write_ceph_exporter_config_yaml():46def write_ceph_exporter_config_yaml():
54 config = hookenv.config()47 # config = hookenv.config()
55 hookenv.open_port(PORT_DEF)48 hookenv.open_port(PORT_DEF)
56 set_state('ceph-exporter.do-restart')49 set_state('ceph-exporter.do-restart')
57 remove_state('ceph-exporter.do-reconfig-yaml')50 remove_state('ceph-exporter.do-reconfig-yaml')
@@ -71,19 +64,44 @@ def check_reconfig_ceph_exporter():
71 remove_state('ceph-exporter.do-check-reconfig')64 remove_state('ceph-exporter.do-check-reconfig')
7265
7366
74@when('ceph-exporter.do-auth-config')67@when('ceph.connected')
75def ceph_auth_config():68def ceph_connected(ceph_client):
76 # Working around snap confinement, creating ceph user, moving conf to snap confined environment ($SNAP_DATA)69 apt_install(['ceph-common', 'python-ceph'])
77 hookenv.status_set('maintenance', 'Creating ceph user')70
78 hookenv.log('Creating exporter ceph user')71
79 subprocess.check_call(['ceph', 'auth', 'add', 'client.exporter', 'mon', "allow r"])72@when('ceph.available')
80 hookenv.log('Creating exporter keyring file onto {}'.format(SNAP_DATA))73def ceph_ready(ceph_client):
81 subprocess.check_call(['ceph', 'auth', 'get', 'client.exporter', '-o', SNAP_DATA + 'ceph.client.exporter.keyring'])74 username = hookenv.config('username')
82 hookenv.log('Copying ceph.conf onto {}'.format(SNAP_DATA))75 daemon_conf = os.path.join(os.sep, SNAP_DATA, 'daemon_arguments')
83 subprocess.check_call(['cp', '/etc/ceph/ceph.conf', SNAP_DATA + 'ceph.conf'])76 charm_ceph_conf = os.path.join(os.sep, SNAP_DATA, 'ceph.conf')
84 hookenv.log('Modifying snap ceph.conf to point to $SNAP_DATA')77 cephx_key = os.path.join(os.sep, SNAP_DATA, 'ceph.client.%s.keyring' % (username))
85 subprocess.check_call(['sed', '-i', 's=/etc/ceph/=' + SNAP_DATA + '=g', SNAP_DATA + 'ceph.conf'])78
86 remove_state('ceph-exporter.do-auth-config')79 ceph_context = {
80 'auth_supported': ceph_client.auth(),
81 'mon_hosts': ceph_client.mon_hosts(),
82 'service_name': username,
83 'ringpath': SNAP_DATA,
84 }
85
86 # Write out the ceph.conf
87 render('ceph.conf', charm_ceph_conf, ceph_context)
88
89 ceph_key_context = {
90 'key': str(ceph_client.key()),
91 'username': username,
92 }
93
94 # Write out the cephx_key also
95 render('ceph.keyring', cephx_key, ceph_key_context)
96
97 daemon_context = {
98 'daemon_arguments': hookenv.config('daemon_arguments'),
99 'username': username,
100 }
101
102 # Write out the daemon.arguments file
103 render('daemon_arguments', daemon_conf, daemon_context)
104
87105
88@when('ceph-exporter.do-restart')106@when('ceph-exporter.do-restart')
89def restart_ceph_exporter():107def restart_ceph_exporter():
@@ -100,6 +118,6 @@ def restart_ceph_exporter():
100118
101# Relations119# Relations
102@when('ceph-exporter.started')120@when('ceph-exporter.started')
103@when('ceph-exporter.available') # Relation name is "ceph-exporter"121@when('ceph-exporter.available') # Relation name is "ceph-exporter"
104def configure_ceph_exporter_relation(target):122def configure_ceph_exporter_relation(target):
105 target.configure(PORT_DEF)123 target.configure(PORT_DEF)
diff --git a/reactive/snap.py b/reactive/snap.py
106deleted file mode 100644124deleted file mode 100644
index d357e05..0000000
--- a/reactive/snap.py
+++ /dev/null
@@ -1,133 +0,0 @@
1# Copyright 2016 Canonical Ltd.
2#
3# This file is part of the Snap layer for Juju.
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16'''
17charms.reactive helpers for dealing with Snap packages.
18'''
19import os.path
20import shutil
21import subprocess
22from textwrap import dedent
23import time
24
25from charmhelpers.core import hookenv, host
26from charms import layer
27from charms import reactive
28from charms.layer import snap
29from charms.reactive import hook
30from charms.reactive.helpers import data_changed
31
32
33def install():
34 opts = layer.options('snap')
35 for snapname, snap_opts in opts.items():
36 snap.install(snapname, **snap_opts)
37 if data_changed('snap.install.opts', opts):
38 snap.connect_all()
39
40
41def refresh():
42 opts = layer.options('snap')
43 for snapname, snap_opts in opts.items():
44 snap.refresh(snapname, **snap_opts)
45 snap.connect_all()
46
47
48@hook('upgrade-charm')
49def upgrade_charm():
50 refresh()
51
52
53def get_series():
54 return subprocess.check_output(['lsb_release', '-sc'],
55 universal_newlines=True).strip()
56
57
58def ensure_snapd():
59 # I don't use the apt layer, because that would tie this layer
60 # too closely to apt packaging. Perhaps this is a snap-only system.
61 if not shutil.which('snap'):
62 cmd = ['apt', 'install', '-y', 'snapd']
63 subprocess.check_call(cmd, universal_newlines=True)
64 # Work around lp:1628289. Remove this stanza once snapd depends
65 # on the necessary package and snaps work in lxd xenial containers
66 # without the workaround.
67 if get_series() == 'xenial' and not shutil.which('squashfuse'):
68 cmd = ['apt', 'install', '-y', 'squashfuse']
69 subprocess.check_call(cmd, universal_newlines=True)
70
71
72def update_snap_proxy():
73 # This is a hack based on
74 # https://bugs.launchpad.net/layer-snap/+bug/1533899/comments/1
75 # Do it properly when Bug #1533899 is addressed.
76 # Note we can't do this in a standard reactive handler as we need
77 # to ensure proxies are configured before attempting installs or
78 # updates.
79 proxy = hookenv.config()['snap_proxy']
80 if not data_changed('snap.proxy', proxy):
81 return # Short circuit avoids unnecessary restarts.
82
83 path = '/etc/systemd/system/snapd.service.d/snap_layer_proxy.conf'
84 if proxy:
85 create_snap_proxy_conf(path, proxy)
86 else:
87 remove_snap_proxy_conf(path)
88 subprocess.check_call(['systemctl', 'daemon-reload'],
89 universal_newlines=True)
90 time.sleep(2)
91 subprocess.check_call(['systemctl', 'restart', 'snapd.service'],
92 universal_newlines=True)
93
94
95def create_snap_proxy_conf(path, proxy):
96 host.mkdir(os.path.dirname(path))
97 content = dedent('''\
98 # Managed by Juju
99 [Service]
100 Environment=http_proxy={}
101 Environment=https_proxy={}
102 ''').format(proxy, proxy)
103 host.write_file(path, content.encode())
104
105
106def remove_snap_proxy_conf(path):
107 if os.path.exists(path):
108 os.remove(path)
109
110
111def ensure_path():
112 # Per Bug #1662856, /snap/bin may be missing from $PATH. Fix this.
113 if '/snap/bin' not in os.environ['PATH'].split(':'):
114 os.environ['PATH'] += ':/snap/bin'
115
116
117# Per https://github.com/juju-solutions/charms.reactive/issues/33,
118# this module may be imported multiple times so ensure the
119# initialization hook is only registered once. I have to piggy back
120# onto the namespace of a module imported before reactive discovery
121# to do this.
122if not hasattr(reactive, '_snap_registered'):
123 # We need to register this to run every hook, not just during install
124 # and config-changed, to protect against race conditions. If we don't
125 # do this, then the config in the hook environment may show updates
126 # to running hooks well before the config-changed hook has been invoked
127 # and the intialization provided an opertunity to be run.
128 hookenv.atstart(hookenv.log, 'Initializing Snap Layer')
129 hookenv.atstart(ensure_snapd)
130 hookenv.atstart(ensure_path)
131 hookenv.atstart(update_snap_proxy)
132 hookenv.atstart(install)
133 reactive._snap_registered = True
diff --git a/templates/ceph.conf b/templates/ceph.conf
134new file mode 1006440new file mode 100644
index 0000000..91459c6
--- /dev/null
+++ b/templates/ceph.conf
@@ -0,0 +1,19 @@
1###############################################################################
2# [ WARNING ]
3# glance configuration file maintained by Juju
4# local changes may be overwritten.
5###############################################################################
6[global]
7{% if auth_supported -%}
8 auth_supported = {{ auth_supported }}
9 #keyring = /etc/ceph/$cluster.$name.keyring
10 keyring = {{ ringpath }}ceph.client.{{ service_name }}.keyring
11 mon host = {{ mon_hosts | join(' ') }}
12
13{% endif -%}
14{% if use_syslog -%}
15 log to syslog = {{ use_syslog }}
16 err to syslog = {{ use_syslog }}
17 clog to syslog = {{ use_syslog }}
18{% endif -%}
19
diff --git a/templates/ceph.keyring b/templates/ceph.keyring
0new file mode 10064420new file mode 100644
index 0000000..3781aa1
--- /dev/null
+++ b/templates/ceph.keyring
@@ -0,0 +1,5 @@
1[client.{{ username }}]
2 key = {{ key }}
3 caps mon = "allow r"
4 caps osd = "allow rwx"
5
diff --git a/templates/daemon_arguments b/templates/daemon_arguments
0new file mode 1006446new file mode 100644
index 0000000..bb40eef
--- /dev/null
+++ b/templates/daemon_arguments
@@ -0,0 +1,17 @@
1# Set the command-line arguments to pass to the ceph_exporter daemon
2{% if username is defined %}
3ARGS="-ceph.user {{ username }} {{ daemon_arguments }}"
4{%- else -%}
5ARGS="{{ daemon_arguments }}"
6{% endif %}
7
8# Example of the commands:
9# -ceph.config string
10# path to ceph config file
11# -ceph.user string
12# Ceph user to connect to cluster. (default "admin")
13# -telemetry.addr string
14# host:port for ceph exporter (default ":9128")
15# -telemetry.path string
16# URL path for surfacing collected metrics (default "/metrics")
17
diff --git a/wheelhouse/Jinja2-2.9.5.tar.gz b/wheelhouse/Jinja2-2.9.5.tar.gz
0deleted file mode 10064418deleted file mode 100644
index 82ae159..0000000
1Binary files a/wheelhouse/Jinja2-2.9.5.tar.gz and /dev/null differ19Binary files a/wheelhouse/Jinja2-2.9.5.tar.gz and /dev/null differ
diff --git a/wheelhouse/MarkupSafe-0.23.tar.gz b/wheelhouse/MarkupSafe-0.23.tar.gz
2deleted file mode 10064420deleted file mode 100644
index 6b19006..0000000
3Binary files a/wheelhouse/MarkupSafe-0.23.tar.gz and /dev/null differ21Binary files a/wheelhouse/MarkupSafe-0.23.tar.gz and /dev/null differ
diff --git a/wheelhouse/PyYAML-3.12.tar.gz b/wheelhouse/PyYAML-3.12.tar.gz
4deleted file mode 10064422deleted file mode 100644
index aabee39..0000000
5Binary files a/wheelhouse/PyYAML-3.12.tar.gz and /dev/null differ23Binary files a/wheelhouse/PyYAML-3.12.tar.gz and /dev/null differ
diff --git a/wheelhouse/Tempita-0.5.2.tar.gz b/wheelhouse/Tempita-0.5.2.tar.gz
6deleted file mode 10064424deleted file mode 100644
index 755befc..0000000
7Binary files a/wheelhouse/Tempita-0.5.2.tar.gz and /dev/null differ25Binary files a/wheelhouse/Tempita-0.5.2.tar.gz and /dev/null differ
diff --git a/wheelhouse/charmhelpers-0.13.0.tar.gz b/wheelhouse/charmhelpers-0.13.0.tar.gz
8deleted file mode 10064426deleted file mode 100644
index c862e55..0000000
9Binary files a/wheelhouse/charmhelpers-0.13.0.tar.gz and /dev/null differ27Binary files a/wheelhouse/charmhelpers-0.13.0.tar.gz and /dev/null differ
diff --git a/wheelhouse/charms.reactive-0.4.5.tar.gz b/wheelhouse/charms.reactive-0.4.5.tar.gz
10deleted file mode 10064428deleted file mode 100644
index ff4e308..0000000
11Binary files a/wheelhouse/charms.reactive-0.4.5.tar.gz and /dev/null differ29Binary files a/wheelhouse/charms.reactive-0.4.5.tar.gz and /dev/null differ
diff --git a/wheelhouse/netaddr-0.7.19.tar.gz b/wheelhouse/netaddr-0.7.19.tar.gz
12deleted file mode 10064430deleted file mode 100644
index cc31d9d..0000000
13Binary files a/wheelhouse/netaddr-0.7.19.tar.gz and /dev/null differ31Binary files a/wheelhouse/netaddr-0.7.19.tar.gz and /dev/null differ
diff --git a/wheelhouse/pip-8.1.2.tar.gz b/wheelhouse/pip-8.1.2.tar.gz
14deleted file mode 10064432deleted file mode 100644
index e7a1a3c..0000000
15Binary files a/wheelhouse/pip-8.1.2.tar.gz and /dev/null differ33Binary files a/wheelhouse/pip-8.1.2.tar.gz and /dev/null differ
diff --git a/wheelhouse/pyaml-16.12.2.tar.gz b/wheelhouse/pyaml-16.12.2.tar.gz
16deleted file mode 10064434deleted file mode 100644
index 2ff0b0a..0000000
17Binary files a/wheelhouse/pyaml-16.12.2.tar.gz and /dev/null differ35Binary files a/wheelhouse/pyaml-16.12.2.tar.gz and /dev/null differ
diff --git a/wheelhouse/six-1.10.0.tar.gz b/wheelhouse/six-1.10.0.tar.gz
18deleted file mode 10064436deleted file mode 100644
index ac8eec5..0000000
19Binary files a/wheelhouse/six-1.10.0.tar.gz and /dev/null differ37Binary files a/wheelhouse/six-1.10.0.tar.gz and /dev/null differ

Subscribers

People subscribed via source and target branches