Merge lp:~gnuoy/charms/trusty/ceilometer-agent/add-nrpe-checks into lp:~openstack-charmers-archive/charms/trusty/ceilometer-agent/next

Proposed by Liam Young on 2015-01-26
Status: Merged
Merged at revision: 46
Proposed branch: lp:~gnuoy/charms/trusty/ceilometer-agent/add-nrpe-checks
Merge into: lp:~openstack-charmers-archive/charms/trusty/ceilometer-agent/next
Diff against target: 1817 lines (+1256/-23)
49 files modified
charm-helpers.yaml (+1/-0)
config.yaml (+10/-0)
hooks/ceilometer_hooks.py (+18/-1)
hooks/ceilometer_utils.py (+8/-0)
hooks/charmhelpers/__init__.py (+16/-0)
hooks/charmhelpers/contrib/__init__.py (+15/-0)
hooks/charmhelpers/contrib/charmsupport/__init__.py (+15/-0)
hooks/charmhelpers/contrib/charmsupport/nrpe.py (+324/-0)
hooks/charmhelpers/contrib/charmsupport/volumes.py (+175/-0)
hooks/charmhelpers/contrib/hahelpers/__init__.py (+15/-0)
hooks/charmhelpers/contrib/hahelpers/apache.py (+16/-0)
hooks/charmhelpers/contrib/hahelpers/cluster.py (+21/-1)
hooks/charmhelpers/contrib/network/__init__.py (+15/-0)
hooks/charmhelpers/contrib/network/ip.py (+16/-0)
hooks/charmhelpers/contrib/openstack/__init__.py (+15/-0)
hooks/charmhelpers/contrib/openstack/alternatives.py (+16/-0)
hooks/charmhelpers/contrib/openstack/amulet/__init__.py (+15/-0)
hooks/charmhelpers/contrib/openstack/amulet/deployment.py (+16/-0)
hooks/charmhelpers/contrib/openstack/amulet/utils.py (+16/-0)
hooks/charmhelpers/contrib/openstack/context.py (+34/-14)
hooks/charmhelpers/contrib/openstack/ip.py (+16/-0)
hooks/charmhelpers/contrib/openstack/neutron.py (+16/-0)
hooks/charmhelpers/contrib/openstack/templates/__init__.py (+16/-0)
hooks/charmhelpers/contrib/openstack/templating.py (+16/-0)
hooks/charmhelpers/contrib/openstack/utils.py (+16/-0)
hooks/charmhelpers/contrib/python/__init__.py (+15/-0)
hooks/charmhelpers/contrib/python/packages.py (+20/-1)
hooks/charmhelpers/contrib/storage/__init__.py (+15/-0)
hooks/charmhelpers/contrib/storage/linux/__init__.py (+15/-0)
hooks/charmhelpers/contrib/storage/linux/ceph.py (+27/-0)
hooks/charmhelpers/contrib/storage/linux/loopback.py (+16/-0)
hooks/charmhelpers/contrib/storage/linux/lvm.py (+16/-0)
hooks/charmhelpers/contrib/storage/linux/utils.py (+16/-0)
hooks/charmhelpers/core/__init__.py (+15/-0)
hooks/charmhelpers/core/decorators.py (+16/-0)
hooks/charmhelpers/core/fstab.py (+16/-0)
hooks/charmhelpers/core/hookenv.py (+16/-0)
hooks/charmhelpers/core/host.py (+31/-4)
hooks/charmhelpers/core/services/__init__.py (+16/-0)
hooks/charmhelpers/core/services/base.py (+16/-0)
hooks/charmhelpers/core/services/helpers.py (+16/-0)
hooks/charmhelpers/core/sysctl.py (+16/-0)
hooks/charmhelpers/core/templating.py (+16/-0)
hooks/charmhelpers/fetch/__init__.py (+16/-0)
hooks/charmhelpers/fetch/archiveurl.py (+16/-0)
hooks/charmhelpers/fetch/bzrurl.py (+25/-1)
hooks/charmhelpers/fetch/giturl.py (+20/-0)
metadata.yaml (+3/-0)
unit_tests/test_ceilometer_hooks.py (+5/-1)
To merge this branch: bzr merge lp:~gnuoy/charms/trusty/ceilometer-agent/add-nrpe-checks
Reviewer Review Type Date Requested Status
James Page 2015-01-26 Approve on 2015-01-26
Review via email: mp+247562@code.launchpad.net
To post a comment you must log in.

charm_lint_check #1138 ceilometer-agent-next for gnuoy mp247562
    LINT OK: passed

Build: http://10.245.162.77:8080/job/charm_lint_check/1138/

charm_unit_test #1130 ceilometer-agent-next for gnuoy mp247562
    UNIT OK: passed

Build: http://10.245.162.77:8080/job/charm_unit_test/1130/

charm_amulet_test #1301 ceilometer-agent-next for gnuoy mp247562
    AMULET FAIL: amulet-test missing

AMULET Results (max last 2 lines):
INFO:root:Search string not found in makefile target commands.
ERROR:root:No make target was executed.

Full amulet test output: http://paste.ubuntu.com/9879203/
Build: http://10.245.162.77:8080/job/charm_amulet_test/1301/

James Page (james-page) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'charm-helpers.yaml'
2--- charm-helpers.yaml 2014-12-10 15:45:40 +0000
3+++ charm-helpers.yaml 2015-01-26 09:01:00 +0000
4@@ -8,3 +8,4 @@
5 - contrib.storage.linux
6 - contrib.network.ip
7 - contrib.python.packages
8+ - contrib.charmsupport
9
10=== modified file 'config.yaml'
11--- config.yaml 2014-03-31 13:51:46 +0000
12+++ config.yaml 2015-01-26 09:01:00 +0000
13@@ -14,3 +14,13 @@
14 Note that updating this setting to a source that is known to
15 provide a later version of OpenStack will trigger a software
16 upgrade.
17+ nagios_context:
18+ default: "juju"
19+ type: string
20+ description: |
21+ Used by the nrpe-external-master subordinate charm.
22+ A string that will be prepended to instance name to set the host name
23+ in nagios. So for instance the hostname would be something like:
24+ juju-myservice-0
25+ If you're running multiple environments with the same services in them
26+ this allows you to differentiate between them.
27
28=== modified file 'hooks/ceilometer_hooks.py'
29--- hooks/ceilometer_hooks.py 2014-04-01 16:53:45 +0000
30+++ hooks/ceilometer_hooks.py 2015-01-26 09:01:00 +0000
31@@ -10,7 +10,7 @@
32 config,
33 Hooks, UnregisteredHookError,
34 log,
35- relation_set
36+ relation_set,
37 )
38 from charmhelpers.core.host import (
39 restart_on_change,
40@@ -22,11 +22,13 @@
41 )
42 from ceilometer_utils import (
43 restart_map,
44+ services,
45 register_configs,
46 CEILOMETER_AGENT_PACKAGES,
47 NOVA_SETTINGS,
48 do_openstack_upgrade
49 )
50+from charmhelpers.contrib.charmsupport import nrpe
51
52 hooks = Hooks()
53 CONFIGS = register_configs()
54@@ -55,6 +57,7 @@
55 @restart_on_change(restart_map())
56 def ceilometer_changed():
57 CONFIGS.write_all()
58+ update_nrpe_config()
59
60
61 @hooks.hook('config-changed')
62@@ -62,8 +65,22 @@
63 def config_changed():
64 if openstack_upgrade_available('ceilometer-common'):
65 do_openstack_upgrade(CONFIGS)
66+ update_nrpe_config()
67 CONFIGS.write_all()
68
69+
70+@hooks.hook('nrpe-external-master-relation-joined',
71+ 'nrpe-external-master-relation-changed')
72+def update_nrpe_config():
73+ # python-dbus is used by check_upstart_job
74+ apt_install('python-dbus')
75+ hostname = nrpe.get_nagios_hostname()
76+ current_unit = nrpe.get_nagios_unit_name()
77+ nrpe_setup = nrpe.NRPE(hostname=hostname)
78+ nrpe.add_init_service_checks(nrpe_setup, services(), current_unit)
79+ nrpe_setup.write()
80+
81+
82 if __name__ == '__main__':
83 try:
84 hooks.execute(sys.argv)
85
86=== modified file 'hooks/ceilometer_utils.py'
87--- hooks/ceilometer_utils.py 2014-04-01 16:53:45 +0000
88+++ hooks/ceilometer_utils.py 2015-01-26 09:01:00 +0000
89@@ -94,6 +94,14 @@
90 return _map
91
92
93+def services():
94+ ''' Returns a list of services associate with this charm '''
95+ _services = []
96+ for v in restart_map().values():
97+ _services = _services + v
98+ return list(set(_services))
99+
100+
101 def do_openstack_upgrade(configs):
102 """
103 Perform an upgrade. Takes care of upgrading packages, rewriting
104
105=== modified file 'hooks/charmhelpers/__init__.py'
106--- hooks/charmhelpers/__init__.py 2014-12-11 17:46:56 +0000
107+++ hooks/charmhelpers/__init__.py 2015-01-26 09:01:00 +0000
108@@ -1,3 +1,19 @@
109+# Copyright 2014-2015 Canonical Limited.
110+#
111+# This file is part of charm-helpers.
112+#
113+# charm-helpers is free software: you can redistribute it and/or modify
114+# it under the terms of the GNU Lesser General Public License version 3 as
115+# published by the Free Software Foundation.
116+#
117+# charm-helpers is distributed in the hope that it will be useful,
118+# but WITHOUT ANY WARRANTY; without even the implied warranty of
119+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
120+# GNU Lesser General Public License for more details.
121+#
122+# You should have received a copy of the GNU Lesser General Public License
123+# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
124+
125 # Bootstrap charm-helpers, installing its dependencies if necessary using
126 # only standard libraries.
127 import subprocess
128
129=== modified file 'hooks/charmhelpers/__init__.pyc'
130Binary files hooks/charmhelpers/__init__.pyc 2015-01-13 10:09:13 +0000 and hooks/charmhelpers/__init__.pyc 2015-01-26 09:01:00 +0000 differ
131=== modified file 'hooks/charmhelpers/contrib/__init__.py'
132--- hooks/charmhelpers/contrib/__init__.py 2013-10-14 16:10:30 +0000
133+++ hooks/charmhelpers/contrib/__init__.py 2015-01-26 09:01:00 +0000
134@@ -0,0 +1,15 @@
135+# Copyright 2014-2015 Canonical Limited.
136+#
137+# This file is part of charm-helpers.
138+#
139+# charm-helpers is free software: you can redistribute it and/or modify
140+# it under the terms of the GNU Lesser General Public License version 3 as
141+# published by the Free Software Foundation.
142+#
143+# charm-helpers is distributed in the hope that it will be useful,
144+# but WITHOUT ANY WARRANTY; without even the implied warranty of
145+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
146+# GNU Lesser General Public License for more details.
147+#
148+# You should have received a copy of the GNU Lesser General Public License
149+# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
150
151=== added directory 'hooks/charmhelpers/contrib/charmsupport'
152=== added file 'hooks/charmhelpers/contrib/charmsupport/__init__.py'
153--- hooks/charmhelpers/contrib/charmsupport/__init__.py 1970-01-01 00:00:00 +0000
154+++ hooks/charmhelpers/contrib/charmsupport/__init__.py 2015-01-26 09:01:00 +0000
155@@ -0,0 +1,15 @@
156+# Copyright 2014-2015 Canonical Limited.
157+#
158+# This file is part of charm-helpers.
159+#
160+# charm-helpers is free software: you can redistribute it and/or modify
161+# it under the terms of the GNU Lesser General Public License version 3 as
162+# published by the Free Software Foundation.
163+#
164+# charm-helpers is distributed in the hope that it will be useful,
165+# but WITHOUT ANY WARRANTY; without even the implied warranty of
166+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
167+# GNU Lesser General Public License for more details.
168+#
169+# You should have received a copy of the GNU Lesser General Public License
170+# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
171
172=== added file 'hooks/charmhelpers/contrib/charmsupport/nrpe.py'
173--- hooks/charmhelpers/contrib/charmsupport/nrpe.py 1970-01-01 00:00:00 +0000
174+++ hooks/charmhelpers/contrib/charmsupport/nrpe.py 2015-01-26 09:01:00 +0000
175@@ -0,0 +1,324 @@
176+# Copyright 2014-2015 Canonical Limited.
177+#
178+# This file is part of charm-helpers.
179+#
180+# charm-helpers is free software: you can redistribute it and/or modify
181+# it under the terms of the GNU Lesser General Public License version 3 as
182+# published by the Free Software Foundation.
183+#
184+# charm-helpers is distributed in the hope that it will be useful,
185+# but WITHOUT ANY WARRANTY; without even the implied warranty of
186+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
187+# GNU Lesser General Public License for more details.
188+#
189+# You should have received a copy of the GNU Lesser General Public License
190+# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
191+
192+"""Compatibility with the nrpe-external-master charm"""
193+# Copyright 2012 Canonical Ltd.
194+#
195+# Authors:
196+# Matthew Wedgwood <matthew.wedgwood@canonical.com>
197+
198+import subprocess
199+import pwd
200+import grp
201+import os
202+import re
203+import shlex
204+import yaml
205+
206+from charmhelpers.core.hookenv import (
207+ config,
208+ local_unit,
209+ log,
210+ relation_ids,
211+ relation_set,
212+ relations_of_type,
213+)
214+
215+from charmhelpers.core.host import service
216+
217+# This module adds compatibility with the nrpe-external-master and plain nrpe
218+# subordinate charms. To use it in your charm:
219+#
220+# 1. Update metadata.yaml
221+#
222+# provides:
223+# (...)
224+# nrpe-external-master:
225+# interface: nrpe-external-master
226+# scope: container
227+#
228+# and/or
229+#
230+# provides:
231+# (...)
232+# local-monitors:
233+# interface: local-monitors
234+# scope: container
235+
236+#
237+# 2. Add the following to config.yaml
238+#
239+# nagios_context:
240+# default: "juju"
241+# type: string
242+# description: |
243+# Used by the nrpe subordinate charms.
244+# A string that will be prepended to instance name to set the host name
245+# in nagios. So for instance the hostname would be something like:
246+# juju-myservice-0
247+# If you're running multiple environments with the same services in them
248+# this allows you to differentiate between them.
249+# nagios_servicegroups:
250+# default: ""
251+# type: string
252+# description: |
253+# A comma-separated list of nagios servicegroups.
254+# If left empty, the nagios_context will be used as the servicegroup
255+#
256+# 3. Add custom checks (Nagios plugins) to files/nrpe-external-master
257+#
258+# 4. Update your hooks.py with something like this:
259+#
260+# from charmsupport.nrpe import NRPE
261+# (...)
262+# def update_nrpe_config():
263+# nrpe_compat = NRPE()
264+# nrpe_compat.add_check(
265+# shortname = "myservice",
266+# description = "Check MyService",
267+# check_cmd = "check_http -w 2 -c 10 http://localhost"
268+# )
269+# nrpe_compat.add_check(
270+# "myservice_other",
271+# "Check for widget failures",
272+# check_cmd = "/srv/myapp/scripts/widget_check"
273+# )
274+# nrpe_compat.write()
275+#
276+# def config_changed():
277+# (...)
278+# update_nrpe_config()
279+#
280+# def nrpe_external_master_relation_changed():
281+# update_nrpe_config()
282+#
283+# def local_monitors_relation_changed():
284+# update_nrpe_config()
285+#
286+# 5. ln -s hooks.py nrpe-external-master-relation-changed
287+# ln -s hooks.py local-monitors-relation-changed
288+
289+
290+class CheckException(Exception):
291+ pass
292+
293+
294+class Check(object):
295+ shortname_re = '[A-Za-z0-9-_]+$'
296+ service_template = ("""
297+#---------------------------------------------------
298+# This file is Juju managed
299+#---------------------------------------------------
300+define service {{
301+ use active-service
302+ host_name {nagios_hostname}
303+ service_description {nagios_hostname}[{shortname}] """
304+ """{description}
305+ check_command check_nrpe!{command}
306+ servicegroups {nagios_servicegroup}
307+}}
308+""")
309+
310+ def __init__(self, shortname, description, check_cmd):
311+ super(Check, self).__init__()
312+ # XXX: could be better to calculate this from the service name
313+ if not re.match(self.shortname_re, shortname):
314+ raise CheckException("shortname must match {}".format(
315+ Check.shortname_re))
316+ self.shortname = shortname
317+ self.command = "check_{}".format(shortname)
318+ # Note: a set of invalid characters is defined by the
319+ # Nagios server config
320+ # The default is: illegal_object_name_chars=`~!$%^&*"|'<>?,()=
321+ self.description = description
322+ self.check_cmd = self._locate_cmd(check_cmd)
323+
324+ def _locate_cmd(self, check_cmd):
325+ search_path = (
326+ '/usr/lib/nagios/plugins',
327+ '/usr/local/lib/nagios/plugins',
328+ )
329+ parts = shlex.split(check_cmd)
330+ for path in search_path:
331+ if os.path.exists(os.path.join(path, parts[0])):
332+ command = os.path.join(path, parts[0])
333+ if len(parts) > 1:
334+ command += " " + " ".join(parts[1:])
335+ return command
336+ log('Check command not found: {}'.format(parts[0]))
337+ return ''
338+
339+ def write(self, nagios_context, hostname, nagios_servicegroups=None):
340+ nrpe_check_file = '/etc/nagios/nrpe.d/{}.cfg'.format(
341+ self.command)
342+ with open(nrpe_check_file, 'w') as nrpe_check_config:
343+ nrpe_check_config.write("# check {}\n".format(self.shortname))
344+ nrpe_check_config.write("command[{}]={}\n".format(
345+ self.command, self.check_cmd))
346+
347+ if not os.path.exists(NRPE.nagios_exportdir):
348+ log('Not writing service config as {} is not accessible'.format(
349+ NRPE.nagios_exportdir))
350+ else:
351+ self.write_service_config(nagios_context, hostname,
352+ nagios_servicegroups)
353+
354+ def write_service_config(self, nagios_context, hostname,
355+ nagios_servicegroups=None):
356+ for f in os.listdir(NRPE.nagios_exportdir):
357+ if re.search('.*{}.cfg'.format(self.command), f):
358+ os.remove(os.path.join(NRPE.nagios_exportdir, f))
359+
360+ if not nagios_servicegroups:
361+ nagios_servicegroups = nagios_context
362+
363+ templ_vars = {
364+ 'nagios_hostname': hostname,
365+ 'nagios_servicegroup': nagios_servicegroups,
366+ 'description': self.description,
367+ 'shortname': self.shortname,
368+ 'command': self.command,
369+ }
370+ nrpe_service_text = Check.service_template.format(**templ_vars)
371+ nrpe_service_file = '{}/service__{}_{}.cfg'.format(
372+ NRPE.nagios_exportdir, hostname, self.command)
373+ with open(nrpe_service_file, 'w') as nrpe_service_config:
374+ nrpe_service_config.write(str(nrpe_service_text))
375+
376+ def run(self):
377+ subprocess.call(self.check_cmd)
378+
379+
380+class NRPE(object):
381+ nagios_logdir = '/var/log/nagios'
382+ nagios_exportdir = '/var/lib/nagios/export'
383+ nrpe_confdir = '/etc/nagios/nrpe.d'
384+
385+ def __init__(self, hostname=None):
386+ super(NRPE, self).__init__()
387+ self.config = config()
388+ self.nagios_context = self.config['nagios_context']
389+ if 'nagios_servicegroups' in self.config:
390+ self.nagios_servicegroups = self.config['nagios_servicegroups']
391+ else:
392+ self.nagios_servicegroups = 'juju'
393+ self.unit_name = local_unit().replace('/', '-')
394+ if hostname:
395+ self.hostname = hostname
396+ else:
397+ self.hostname = "{}-{}".format(self.nagios_context, self.unit_name)
398+ self.checks = []
399+
400+ def add_check(self, *args, **kwargs):
401+ self.checks.append(Check(*args, **kwargs))
402+
403+ def write(self):
404+ try:
405+ nagios_uid = pwd.getpwnam('nagios').pw_uid
406+ nagios_gid = grp.getgrnam('nagios').gr_gid
407+ except:
408+ log("Nagios user not set up, nrpe checks not updated")
409+ return
410+
411+ if not os.path.exists(NRPE.nagios_logdir):
412+ os.mkdir(NRPE.nagios_logdir)
413+ os.chown(NRPE.nagios_logdir, nagios_uid, nagios_gid)
414+
415+ nrpe_monitors = {}
416+ monitors = {"monitors": {"remote": {"nrpe": nrpe_monitors}}}
417+ for nrpecheck in self.checks:
418+ nrpecheck.write(self.nagios_context, self.hostname,
419+ self.nagios_servicegroups)
420+ nrpe_monitors[nrpecheck.shortname] = {
421+ "command": nrpecheck.command,
422+ }
423+
424+ service('restart', 'nagios-nrpe-server')
425+
426+ for rid in relation_ids("local-monitors"):
427+ relation_set(relation_id=rid, monitors=yaml.dump(monitors))
428+
429+
430+def get_nagios_hostcontext(relation_name='nrpe-external-master'):
431+ """
432+ Query relation with nrpe subordinate, return the nagios_host_context
433+
434+ :param str relation_name: Name of relation nrpe sub joined to
435+ """
436+ for rel in relations_of_type(relation_name):
437+ if 'nagios_hostname' in rel:
438+ return rel['nagios_host_context']
439+
440+
441+def get_nagios_hostname(relation_name='nrpe-external-master'):
442+ """
443+ Query relation with nrpe subordinate, return the nagios_hostname
444+
445+ :param str relation_name: Name of relation nrpe sub joined to
446+ """
447+ for rel in relations_of_type(relation_name):
448+ if 'nagios_hostname' in rel:
449+ return rel['nagios_hostname']
450+
451+
452+def get_nagios_unit_name(relation_name='nrpe-external-master'):
453+ """
454+ Return the nagios unit name prepended with host_context if needed
455+
456+ :param str relation_name: Name of relation nrpe sub joined to
457+ """
458+ host_context = get_nagios_hostcontext(relation_name)
459+ if host_context:
460+ unit = "%s:%s" % (host_context, local_unit())
461+ else:
462+ unit = local_unit()
463+ return unit
464+
465+
466+def add_init_service_checks(nrpe, services, unit_name):
467+ """
468+ Add checks for each service in list
469+
470+ :param NRPE nrpe: NRPE object to add check to
471+ :param list services: List of services to check
472+ :param str unit_name: Unit name to use in check description
473+ """
474+ for svc in services:
475+ upstart_init = '/etc/init/%s.conf' % svc
476+ sysv_init = '/etc/init.d/%s' % svc
477+ if os.path.exists(upstart_init):
478+ nrpe.add_check(
479+ shortname=svc,
480+ description='process check {%s}' % unit_name,
481+ check_cmd='check_upstart_job %s' % svc
482+ )
483+ elif os.path.exists(sysv_init):
484+ cronpath = '/etc/cron.d/nagios-service-check-%s' % svc
485+ cron_file = ('*/5 * * * * root '
486+ '/usr/local/lib/nagios/plugins/check_exit_status.pl '
487+ '-s /etc/init.d/%s status > '
488+ '/var/lib/nagios/service-check-%s.txt\n' % (svc,
489+ svc)
490+ )
491+ f = open(cronpath, 'w')
492+ f.write(cron_file)
493+ f.close()
494+ nrpe.add_check(
495+ shortname=svc,
496+ description='process check {%s}' % unit_name,
497+ check_cmd='check_status_file.py -f '
498+ '/var/lib/nagios/service-check-%s.txt' % svc,
499+ )
500
501=== added file 'hooks/charmhelpers/contrib/charmsupport/volumes.py'
502--- hooks/charmhelpers/contrib/charmsupport/volumes.py 1970-01-01 00:00:00 +0000
503+++ hooks/charmhelpers/contrib/charmsupport/volumes.py 2015-01-26 09:01:00 +0000
504@@ -0,0 +1,175 @@
505+# Copyright 2014-2015 Canonical Limited.
506+#
507+# This file is part of charm-helpers.
508+#
509+# charm-helpers is free software: you can redistribute it and/or modify
510+# it under the terms of the GNU Lesser General Public License version 3 as
511+# published by the Free Software Foundation.
512+#
513+# charm-helpers is distributed in the hope that it will be useful,
514+# but WITHOUT ANY WARRANTY; without even the implied warranty of
515+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
516+# GNU Lesser General Public License for more details.
517+#
518+# You should have received a copy of the GNU Lesser General Public License
519+# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
520+
521+'''
522+Functions for managing volumes in juju units. One volume is supported per unit.
523+Subordinates may have their own storage, provided it is on its own partition.
524+
525+Configuration stanzas::
526+
527+ volume-ephemeral:
528+ type: boolean
529+ default: true
530+ description: >
531+ If false, a volume is mounted as sepecified in "volume-map"
532+ If true, ephemeral storage will be used, meaning that log data
533+ will only exist as long as the machine. YOU HAVE BEEN WARNED.
534+ volume-map:
535+ type: string
536+ default: {}
537+ description: >
538+ YAML map of units to device names, e.g:
539+ "{ rsyslog/0: /dev/vdb, rsyslog/1: /dev/vdb }"
540+ Service units will raise a configure-error if volume-ephemeral
541+ is 'true' and no volume-map value is set. Use 'juju set' to set a
542+ value and 'juju resolved' to complete configuration.
543+
544+Usage::
545+
546+ from charmsupport.volumes import configure_volume, VolumeConfigurationError
547+ from charmsupport.hookenv import log, ERROR
548+ def post_mount_hook():
549+ stop_service('myservice')
550+ def post_mount_hook():
551+ start_service('myservice')
552+
553+ if __name__ == '__main__':
554+ try:
555+ configure_volume(before_change=pre_mount_hook,
556+ after_change=post_mount_hook)
557+ except VolumeConfigurationError:
558+ log('Storage could not be configured', ERROR)
559+
560+'''
561+
562+# XXX: Known limitations
563+# - fstab is neither consulted nor updated
564+
565+import os
566+from charmhelpers.core import hookenv
567+from charmhelpers.core import host
568+import yaml
569+
570+
571+MOUNT_BASE = '/srv/juju/volumes'
572+
573+
574+class VolumeConfigurationError(Exception):
575+ '''Volume configuration data is missing or invalid'''
576+ pass
577+
578+
579+def get_config():
580+ '''Gather and sanity-check volume configuration data'''
581+ volume_config = {}
582+ config = hookenv.config()
583+
584+ errors = False
585+
586+ if config.get('volume-ephemeral') in (True, 'True', 'true', 'Yes', 'yes'):
587+ volume_config['ephemeral'] = True
588+ else:
589+ volume_config['ephemeral'] = False
590+
591+ try:
592+ volume_map = yaml.safe_load(config.get('volume-map', '{}'))
593+ except yaml.YAMLError as e:
594+ hookenv.log("Error parsing YAML volume-map: {}".format(e),
595+ hookenv.ERROR)
596+ errors = True
597+ if volume_map is None:
598+ # probably an empty string
599+ volume_map = {}
600+ elif not isinstance(volume_map, dict):
601+ hookenv.log("Volume-map should be a dictionary, not {}".format(
602+ type(volume_map)))
603+ errors = True
604+
605+ volume_config['device'] = volume_map.get(os.environ['JUJU_UNIT_NAME'])
606+ if volume_config['device'] and volume_config['ephemeral']:
607+ # asked for ephemeral storage but also defined a volume ID
608+ hookenv.log('A volume is defined for this unit, but ephemeral '
609+ 'storage was requested', hookenv.ERROR)
610+ errors = True
611+ elif not volume_config['device'] and not volume_config['ephemeral']:
612+ # asked for permanent storage but did not define volume ID
613+ hookenv.log('Ephemeral storage was requested, but there is no volume '
614+ 'defined for this unit.', hookenv.ERROR)
615+ errors = True
616+
617+ unit_mount_name = hookenv.local_unit().replace('/', '-')
618+ volume_config['mountpoint'] = os.path.join(MOUNT_BASE, unit_mount_name)
619+
620+ if errors:
621+ return None
622+ return volume_config
623+
624+
625+def mount_volume(config):
626+ if os.path.exists(config['mountpoint']):
627+ if not os.path.isdir(config['mountpoint']):
628+ hookenv.log('Not a directory: {}'.format(config['mountpoint']))
629+ raise VolumeConfigurationError()
630+ else:
631+ host.mkdir(config['mountpoint'])
632+ if os.path.ismount(config['mountpoint']):
633+ unmount_volume(config)
634+ if not host.mount(config['device'], config['mountpoint'], persist=True):
635+ raise VolumeConfigurationError()
636+
637+
638+def unmount_volume(config):
639+ if os.path.ismount(config['mountpoint']):
640+ if not host.umount(config['mountpoint'], persist=True):
641+ raise VolumeConfigurationError()
642+
643+
644+def managed_mounts():
645+ '''List of all mounted managed volumes'''
646+ return filter(lambda mount: mount[0].startswith(MOUNT_BASE), host.mounts())
647+
648+
649+def configure_volume(before_change=lambda: None, after_change=lambda: None):
650+ '''Set up storage (or don't) according to the charm's volume configuration.
651+ Returns the mount point or "ephemeral". before_change and after_change
652+ are optional functions to be called if the volume configuration changes.
653+ '''
654+
655+ config = get_config()
656+ if not config:
657+ hookenv.log('Failed to read volume configuration', hookenv.CRITICAL)
658+ raise VolumeConfigurationError()
659+
660+ if config['ephemeral']:
661+ if os.path.ismount(config['mountpoint']):
662+ before_change()
663+ unmount_volume(config)
664+ after_change()
665+ return 'ephemeral'
666+ else:
667+ # persistent storage
668+ if os.path.ismount(config['mountpoint']):
669+ mounts = dict(managed_mounts())
670+ if mounts.get(config['mountpoint']) != config['device']:
671+ before_change()
672+ unmount_volume(config)
673+ mount_volume(config)
674+ after_change()
675+ else:
676+ before_change()
677+ mount_volume(config)
678+ after_change()
679+ return config['mountpoint']
680
681=== modified file 'hooks/charmhelpers/contrib/hahelpers/__init__.py'
682--- hooks/charmhelpers/contrib/hahelpers/__init__.py 2013-10-18 15:58:17 +0000
683+++ hooks/charmhelpers/contrib/hahelpers/__init__.py 2015-01-26 09:01:00 +0000
684@@ -0,0 +1,15 @@
685+# Copyright 2014-2015 Canonical Limited.
686+#
687+# This file is part of charm-helpers.
688+#
689+# charm-helpers is free software: you can redistribute it and/or modify
690+# it under the terms of the GNU Lesser General Public License version 3 as
691+# published by the Free Software Foundation.
692+#
693+# charm-helpers is distributed in the hope that it will be useful,
694+# but WITHOUT ANY WARRANTY; without even the implied warranty of
695+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
696+# GNU Lesser General Public License for more details.
697+#
698+# You should have received a copy of the GNU Lesser General Public License
699+# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
700
701=== modified file 'hooks/charmhelpers/contrib/hahelpers/apache.py'
702--- hooks/charmhelpers/contrib/hahelpers/apache.py 2014-12-10 20:28:40 +0000
703+++ hooks/charmhelpers/contrib/hahelpers/apache.py 2015-01-26 09:01:00 +0000
704@@ -1,3 +1,19 @@
705+# Copyright 2014-2015 Canonical Limited.
706+#
707+# This file is part of charm-helpers.
708+#
709+# charm-helpers is free software: you can redistribute it and/or modify
710+# it under the terms of the GNU Lesser General Public License version 3 as
711+# published by the Free Software Foundation.
712+#
713+# charm-helpers is distributed in the hope that it will be useful,
714+# but WITHOUT ANY WARRANTY; without even the implied warranty of
715+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
716+# GNU Lesser General Public License for more details.
717+#
718+# You should have received a copy of the GNU Lesser General Public License
719+# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
720+
721 #
722 # Copyright 2012 Canonical Ltd.
723 #
724
725=== modified file 'hooks/charmhelpers/contrib/hahelpers/cluster.py'
726--- hooks/charmhelpers/contrib/hahelpers/cluster.py 2015-01-13 10:09:13 +0000
727+++ hooks/charmhelpers/contrib/hahelpers/cluster.py 2015-01-26 09:01:00 +0000
728@@ -1,3 +1,19 @@
729+# Copyright 2014-2015 Canonical Limited.
730+#
731+# This file is part of charm-helpers.
732+#
733+# charm-helpers is free software: you can redistribute it and/or modify
734+# it under the terms of the GNU Lesser General Public License version 3 as
735+# published by the Free Software Foundation.
736+#
737+# charm-helpers is distributed in the hope that it will be useful,
738+# but WITHOUT ANY WARRANTY; without even the implied warranty of
739+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
740+# GNU Lesser General Public License for more details.
741+#
742+# You should have received a copy of the GNU Lesser General Public License
743+# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
744+
745 #
746 # Copyright 2012 Canonical Ltd.
747 #
748@@ -205,19 +221,23 @@
749 return public_port - (i * 10)
750
751
752-def get_hacluster_config():
753+def get_hacluster_config(exclude_keys=None):
754 '''
755 Obtains all relevant configuration from charm configuration required
756 for initiating a relation to hacluster:
757
758 ha-bindiface, ha-mcastport, vip
759
760+ param: exclude_keys: list of setting key(s) to be excluded.
761 returns: dict: A dict containing settings keyed by setting name.
762 raises: HAIncompleteConfig if settings are missing.
763 '''
764 settings = ['ha-bindiface', 'ha-mcastport', 'vip']
765 conf = {}
766 for setting in settings:
767+ if exclude_keys and setting in exclude_keys:
768+ continue
769+
770 conf[setting] = config_get(setting)
771 missing = []
772 [missing.append(s) for s, v in six.iteritems(conf) if v is None]
773
774=== modified file 'hooks/charmhelpers/contrib/network/__init__.py'
775--- hooks/charmhelpers/contrib/network/__init__.py 2014-08-13 13:43:25 +0000
776+++ hooks/charmhelpers/contrib/network/__init__.py 2015-01-26 09:01:00 +0000
777@@ -0,0 +1,15 @@
778+# Copyright 2014-2015 Canonical Limited.
779+#
780+# This file is part of charm-helpers.
781+#
782+# charm-helpers is free software: you can redistribute it and/or modify
783+# it under the terms of the GNU Lesser General Public License version 3 as
784+# published by the Free Software Foundation.
785+#
786+# charm-helpers is distributed in the hope that it will be useful,
787+# but WITHOUT ANY WARRANTY; without even the implied warranty of
788+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
789+# GNU Lesser General Public License for more details.
790+#
791+# You should have received a copy of the GNU Lesser General Public License
792+# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
793
794=== modified file 'hooks/charmhelpers/contrib/network/ip.py'
795--- hooks/charmhelpers/contrib/network/ip.py 2014-12-10 20:28:40 +0000
796+++ hooks/charmhelpers/contrib/network/ip.py 2015-01-26 09:01:00 +0000
797@@ -1,3 +1,19 @@
798+# Copyright 2014-2015 Canonical Limited.
799+#
800+# This file is part of charm-helpers.
801+#
802+# charm-helpers is free software: you can redistribute it and/or modify
803+# it under the terms of the GNU Lesser General Public License version 3 as
804+# published by the Free Software Foundation.
805+#
806+# charm-helpers is distributed in the hope that it will be useful,
807+# but WITHOUT ANY WARRANTY; without even the implied warranty of
808+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
809+# GNU Lesser General Public License for more details.
810+#
811+# You should have received a copy of the GNU Lesser General Public License
812+# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
813+
814 import glob
815 import re
816 import subprocess
817
818=== modified file 'hooks/charmhelpers/contrib/openstack/__init__.py'
819--- hooks/charmhelpers/contrib/openstack/__init__.py 2013-10-14 16:10:30 +0000
820+++ hooks/charmhelpers/contrib/openstack/__init__.py 2015-01-26 09:01:00 +0000
821@@ -0,0 +1,15 @@
822+# Copyright 2014-2015 Canonical Limited.
823+#
824+# This file is part of charm-helpers.
825+#
826+# charm-helpers is free software: you can redistribute it and/or modify
827+# it under the terms of the GNU Lesser General Public License version 3 as
828+# published by the Free Software Foundation.
829+#
830+# charm-helpers is distributed in the hope that it will be useful,
831+# but WITHOUT ANY WARRANTY; without even the implied warranty of
832+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
833+# GNU Lesser General Public License for more details.
834+#
835+# You should have received a copy of the GNU Lesser General Public License
836+# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
837
838=== modified file 'hooks/charmhelpers/contrib/openstack/alternatives.py'
839--- hooks/charmhelpers/contrib/openstack/alternatives.py 2013-12-17 15:33:22 +0000
840+++ hooks/charmhelpers/contrib/openstack/alternatives.py 2015-01-26 09:01:00 +0000
841@@ -1,3 +1,19 @@
842+# Copyright 2014-2015 Canonical Limited.
843+#
844+# This file is part of charm-helpers.
845+#
846+# charm-helpers is free software: you can redistribute it and/or modify
847+# it under the terms of the GNU Lesser General Public License version 3 as
848+# published by the Free Software Foundation.
849+#
850+# charm-helpers is distributed in the hope that it will be useful,
851+# but WITHOUT ANY WARRANTY; without even the implied warranty of
852+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
853+# GNU Lesser General Public License for more details.
854+#
855+# You should have received a copy of the GNU Lesser General Public License
856+# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
857+
858 ''' Helper for managing alternatives for file conflict resolution '''
859
860 import subprocess
861
862=== modified file 'hooks/charmhelpers/contrib/openstack/amulet/__init__.py'
863--- hooks/charmhelpers/contrib/openstack/amulet/__init__.py 2014-08-13 13:10:01 +0000
864+++ hooks/charmhelpers/contrib/openstack/amulet/__init__.py 2015-01-26 09:01:00 +0000
865@@ -0,0 +1,15 @@
866+# Copyright 2014-2015 Canonical Limited.
867+#
868+# This file is part of charm-helpers.
869+#
870+# charm-helpers is free software: you can redistribute it and/or modify
871+# it under the terms of the GNU Lesser General Public License version 3 as
872+# published by the Free Software Foundation.
873+#
874+# charm-helpers is distributed in the hope that it will be useful,
875+# but WITHOUT ANY WARRANTY; without even the implied warranty of
876+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
877+# GNU Lesser General Public License for more details.
878+#
879+# You should have received a copy of the GNU Lesser General Public License
880+# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
881
882=== modified file 'hooks/charmhelpers/contrib/openstack/amulet/deployment.py'
883--- hooks/charmhelpers/contrib/openstack/amulet/deployment.py 2014-12-10 20:28:40 +0000
884+++ hooks/charmhelpers/contrib/openstack/amulet/deployment.py 2015-01-26 09:01:00 +0000
885@@ -1,3 +1,19 @@
886+# Copyright 2014-2015 Canonical Limited.
887+#
888+# This file is part of charm-helpers.
889+#
890+# charm-helpers is free software: you can redistribute it and/or modify
891+# it under the terms of the GNU Lesser General Public License version 3 as
892+# published by the Free Software Foundation.
893+#
894+# charm-helpers is distributed in the hope that it will be useful,
895+# but WITHOUT ANY WARRANTY; without even the implied warranty of
896+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
897+# GNU Lesser General Public License for more details.
898+#
899+# You should have received a copy of the GNU Lesser General Public License
900+# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
901+
902 import six
903 from charmhelpers.contrib.amulet.deployment import (
904 AmuletDeployment
905
906=== modified file 'hooks/charmhelpers/contrib/openstack/amulet/utils.py'
907--- hooks/charmhelpers/contrib/openstack/amulet/utils.py 2014-12-10 20:28:40 +0000
908+++ hooks/charmhelpers/contrib/openstack/amulet/utils.py 2015-01-26 09:01:00 +0000
909@@ -1,3 +1,19 @@
910+# Copyright 2014-2015 Canonical Limited.
911+#
912+# This file is part of charm-helpers.
913+#
914+# charm-helpers is free software: you can redistribute it and/or modify
915+# it under the terms of the GNU Lesser General Public License version 3 as
916+# published by the Free Software Foundation.
917+#
918+# charm-helpers is distributed in the hope that it will be useful,
919+# but WITHOUT ANY WARRANTY; without even the implied warranty of
920+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
921+# GNU Lesser General Public License for more details.
922+#
923+# You should have received a copy of the GNU Lesser General Public License
924+# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
925+
926 import logging
927 import os
928 import time
929
930=== modified file 'hooks/charmhelpers/contrib/openstack/context.py'
931--- hooks/charmhelpers/contrib/openstack/context.py 2015-01-13 10:09:13 +0000
932+++ hooks/charmhelpers/contrib/openstack/context.py 2015-01-26 09:01:00 +0000
933@@ -1,3 +1,19 @@
934+# Copyright 2014-2015 Canonical Limited.
935+#
936+# This file is part of charm-helpers.
937+#
938+# charm-helpers is free software: you can redistribute it and/or modify
939+# it under the terms of the GNU Lesser General Public License version 3 as
940+# published by the Free Software Foundation.
941+#
942+# charm-helpers is distributed in the hope that it will be useful,
943+# but WITHOUT ANY WARRANTY; without even the implied warranty of
944+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
945+# GNU Lesser General Public License for more details.
946+#
947+# You should have received a copy of the GNU Lesser General Public License
948+# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
949+
950 import json
951 import os
952 import time
953@@ -468,21 +484,25 @@
954 _unit = unit.replace('/', '-')
955 cluster_hosts[laddr]['backends'][_unit] = _laddr
956
957- # NOTE(jamespage) no split configurations found, just use
958- # private addresses
959- if not cluster_hosts:
960- netmask = get_netmask_for_address(addr)
961- cluster_hosts[addr] = {'network': "{}/{}".format(addr, netmask),
962- 'backends': {l_unit: addr}}
963- for rid in relation_ids('cluster'):
964- for unit in related_units(rid):
965- _laddr = relation_get('private-address',
966- rid=rid, unit=unit)
967- if _laddr:
968- _unit = unit.replace('/', '-')
969- cluster_hosts[addr]['backends'][_unit] = _laddr
970+ # NOTE(jamespage) add backend based on private address - this
971+ # with either be the only backend or the fallback if no acls
972+ # match in the frontend
973+ cluster_hosts[addr] = {}
974+ netmask = get_netmask_for_address(addr)
975+ cluster_hosts[addr] = {'network': "{}/{}".format(addr, netmask),
976+ 'backends': {l_unit: addr}}
977+ for rid in relation_ids('cluster'):
978+ for unit in related_units(rid):
979+ _laddr = relation_get('private-address',
980+ rid=rid, unit=unit)
981+ if _laddr:
982+ _unit = unit.replace('/', '-')
983+ cluster_hosts[addr]['backends'][_unit] = _laddr
984
985- ctxt = {'frontends': cluster_hosts}
986+ ctxt = {
987+ 'frontends': cluster_hosts,
988+ 'default_backend': addr
989+ }
990
991 if config('haproxy-server-timeout'):
992 ctxt['haproxy_server_timeout'] = config('haproxy-server-timeout')
993
994=== modified file 'hooks/charmhelpers/contrib/openstack/ip.py'
995--- hooks/charmhelpers/contrib/openstack/ip.py 2014-12-10 20:28:40 +0000
996+++ hooks/charmhelpers/contrib/openstack/ip.py 2015-01-26 09:01:00 +0000
997@@ -1,3 +1,19 @@
998+# Copyright 2014-2015 Canonical Limited.
999+#
1000+# This file is part of charm-helpers.
1001+#
1002+# charm-helpers is free software: you can redistribute it and/or modify
1003+# it under the terms of the GNU Lesser General Public License version 3 as
1004+# published by the Free Software Foundation.
1005+#
1006+# charm-helpers is distributed in the hope that it will be useful,
1007+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1008+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1009+# GNU Lesser General Public License for more details.
1010+#
1011+# You should have received a copy of the GNU Lesser General Public License
1012+# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
1013+
1014 from charmhelpers.core.hookenv import (
1015 config,
1016 unit_get,
1017
1018=== modified file 'hooks/charmhelpers/contrib/openstack/neutron.py'
1019--- hooks/charmhelpers/contrib/openstack/neutron.py 2015-01-13 10:09:13 +0000
1020+++ hooks/charmhelpers/contrib/openstack/neutron.py 2015-01-26 09:01:00 +0000
1021@@ -1,3 +1,19 @@
1022+# Copyright 2014-2015 Canonical Limited.
1023+#
1024+# This file is part of charm-helpers.
1025+#
1026+# charm-helpers is free software: you can redistribute it and/or modify
1027+# it under the terms of the GNU Lesser General Public License version 3 as
1028+# published by the Free Software Foundation.
1029+#
1030+# charm-helpers is distributed in the hope that it will be useful,
1031+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1032+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1033+# GNU Lesser General Public License for more details.
1034+#
1035+# You should have received a copy of the GNU Lesser General Public License
1036+# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
1037+
1038 # Various utilies for dealing with Neutron and the renaming from Quantum.
1039
1040 from subprocess import check_output
1041
1042=== modified file 'hooks/charmhelpers/contrib/openstack/templates/__init__.py'
1043--- hooks/charmhelpers/contrib/openstack/templates/__init__.py 2013-10-14 16:10:30 +0000
1044+++ hooks/charmhelpers/contrib/openstack/templates/__init__.py 2015-01-26 09:01:00 +0000
1045@@ -1,2 +1,18 @@
1046+# Copyright 2014-2015 Canonical Limited.
1047+#
1048+# This file is part of charm-helpers.
1049+#
1050+# charm-helpers is free software: you can redistribute it and/or modify
1051+# it under the terms of the GNU Lesser General Public License version 3 as
1052+# published by the Free Software Foundation.
1053+#
1054+# charm-helpers is distributed in the hope that it will be useful,
1055+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1056+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1057+# GNU Lesser General Public License for more details.
1058+#
1059+# You should have received a copy of the GNU Lesser General Public License
1060+# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
1061+
1062 # dummy __init__.py to fool syncer into thinking this is a syncable python
1063 # module
1064
1065=== modified file 'hooks/charmhelpers/contrib/openstack/templating.py'
1066--- hooks/charmhelpers/contrib/openstack/templating.py 2014-12-10 20:28:40 +0000
1067+++ hooks/charmhelpers/contrib/openstack/templating.py 2015-01-26 09:01:00 +0000
1068@@ -1,3 +1,19 @@
1069+# Copyright 2014-2015 Canonical Limited.
1070+#
1071+# This file is part of charm-helpers.
1072+#
1073+# charm-helpers is free software: you can redistribute it and/or modify
1074+# it under the terms of the GNU Lesser General Public License version 3 as
1075+# published by the Free Software Foundation.
1076+#
1077+# charm-helpers is distributed in the hope that it will be useful,
1078+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1079+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1080+# GNU Lesser General Public License for more details.
1081+#
1082+# You should have received a copy of the GNU Lesser General Public License
1083+# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
1084+
1085 import os
1086
1087 import six
1088
1089=== modified file 'hooks/charmhelpers/contrib/openstack/utils.py'
1090--- hooks/charmhelpers/contrib/openstack/utils.py 2015-01-13 10:09:13 +0000
1091+++ hooks/charmhelpers/contrib/openstack/utils.py 2015-01-26 09:01:00 +0000
1092@@ -1,5 +1,21 @@
1093 #!/usr/bin/python
1094
1095+# Copyright 2014-2015 Canonical Limited.
1096+#
1097+# This file is part of charm-helpers.
1098+#
1099+# charm-helpers is free software: you can redistribute it and/or modify
1100+# it under the terms of the GNU Lesser General Public License version 3 as
1101+# published by the Free Software Foundation.
1102+#
1103+# charm-helpers is distributed in the hope that it will be useful,
1104+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1105+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1106+# GNU Lesser General Public License for more details.
1107+#
1108+# You should have received a copy of the GNU Lesser General Public License
1109+# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
1110+
1111 # Common python helper functions used for OpenStack charms.
1112 from collections import OrderedDict
1113 from functools import wraps
1114
1115=== modified file 'hooks/charmhelpers/contrib/python/__init__.py'
1116--- hooks/charmhelpers/contrib/python/__init__.py 2014-12-10 20:28:40 +0000
1117+++ hooks/charmhelpers/contrib/python/__init__.py 2015-01-26 09:01:00 +0000
1118@@ -0,0 +1,15 @@
1119+# Copyright 2014-2015 Canonical Limited.
1120+#
1121+# This file is part of charm-helpers.
1122+#
1123+# charm-helpers is free software: you can redistribute it and/or modify
1124+# it under the terms of the GNU Lesser General Public License version 3 as
1125+# published by the Free Software Foundation.
1126+#
1127+# charm-helpers is distributed in the hope that it will be useful,
1128+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1129+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1130+# GNU Lesser General Public License for more details.
1131+#
1132+# You should have received a copy of the GNU Lesser General Public License
1133+# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
1134
1135=== modified file 'hooks/charmhelpers/contrib/python/packages.py'
1136--- hooks/charmhelpers/contrib/python/packages.py 2014-12-10 20:28:40 +0000
1137+++ hooks/charmhelpers/contrib/python/packages.py 2015-01-26 09:01:00 +0000
1138@@ -1,6 +1,22 @@
1139 #!/usr/bin/env python
1140 # coding: utf-8
1141
1142+# Copyright 2014-2015 Canonical Limited.
1143+#
1144+# This file is part of charm-helpers.
1145+#
1146+# charm-helpers is free software: you can redistribute it and/or modify
1147+# it under the terms of the GNU Lesser General Public License version 3 as
1148+# published by the Free Software Foundation.
1149+#
1150+# charm-helpers is distributed in the hope that it will be useful,
1151+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1152+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1153+# GNU Lesser General Public License for more details.
1154+#
1155+# You should have received a copy of the GNU Lesser General Public License
1156+# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
1157+
1158 __author__ = "Jorge Niedbalski <jorge.niedbalski@canonical.com>"
1159
1160 from charmhelpers.fetch import apt_install, apt_update
1161@@ -35,7 +51,7 @@
1162 pip_execute(command)
1163
1164
1165-def pip_install(package, fatal=False, **options):
1166+def pip_install(package, fatal=False, upgrade=False, **options):
1167 """Install a python package"""
1168 command = ["install"]
1169
1170@@ -43,6 +59,9 @@
1171 for option in parse_options(options, available_options):
1172 command.append(option)
1173
1174+ if upgrade:
1175+ command.append('--upgrade')
1176+
1177 if isinstance(package, list):
1178 command.extend(package)
1179 else:
1180
1181=== modified file 'hooks/charmhelpers/contrib/storage/__init__.py'
1182--- hooks/charmhelpers/contrib/storage/__init__.py 2013-11-06 01:23:03 +0000
1183+++ hooks/charmhelpers/contrib/storage/__init__.py 2015-01-26 09:01:00 +0000
1184@@ -0,0 +1,15 @@
1185+# Copyright 2014-2015 Canonical Limited.
1186+#
1187+# This file is part of charm-helpers.
1188+#
1189+# charm-helpers is free software: you can redistribute it and/or modify
1190+# it under the terms of the GNU Lesser General Public License version 3 as
1191+# published by the Free Software Foundation.
1192+#
1193+# charm-helpers is distributed in the hope that it will be useful,
1194+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1195+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1196+# GNU Lesser General Public License for more details.
1197+#
1198+# You should have received a copy of the GNU Lesser General Public License
1199+# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
1200
1201=== modified file 'hooks/charmhelpers/contrib/storage/linux/__init__.py'
1202--- hooks/charmhelpers/contrib/storage/linux/__init__.py 2013-11-06 01:23:03 +0000
1203+++ hooks/charmhelpers/contrib/storage/linux/__init__.py 2015-01-26 09:01:00 +0000
1204@@ -0,0 +1,15 @@
1205+# Copyright 2014-2015 Canonical Limited.
1206+#
1207+# This file is part of charm-helpers.
1208+#
1209+# charm-helpers is free software: you can redistribute it and/or modify
1210+# it under the terms of the GNU Lesser General Public License version 3 as
1211+# published by the Free Software Foundation.
1212+#
1213+# charm-helpers is distributed in the hope that it will be useful,
1214+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1215+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1216+# GNU Lesser General Public License for more details.
1217+#
1218+# You should have received a copy of the GNU Lesser General Public License
1219+# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
1220
1221=== modified file 'hooks/charmhelpers/contrib/storage/linux/ceph.py'
1222--- hooks/charmhelpers/contrib/storage/linux/ceph.py 2015-01-13 10:09:13 +0000
1223+++ hooks/charmhelpers/contrib/storage/linux/ceph.py 2015-01-26 09:01:00 +0000
1224@@ -1,3 +1,19 @@
1225+# Copyright 2014-2015 Canonical Limited.
1226+#
1227+# This file is part of charm-helpers.
1228+#
1229+# charm-helpers is free software: you can redistribute it and/or modify
1230+# it under the terms of the GNU Lesser General Public License version 3 as
1231+# published by the Free Software Foundation.
1232+#
1233+# charm-helpers is distributed in the hope that it will be useful,
1234+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1235+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1236+# GNU Lesser General Public License for more details.
1237+#
1238+# You should have received a copy of the GNU Lesser General Public License
1239+# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
1240+
1241 #
1242 # Copyright 2012 Canonical Ltd.
1243 #
1244@@ -157,6 +173,17 @@
1245 log('Created new ceph keyring at %s.' % keyring, level=DEBUG)
1246
1247
1248+def delete_keyring(service):
1249+ """Delete an existing Ceph keyring."""
1250+ keyring = _keyring_path(service)
1251+ if not os.path.exists(keyring):
1252+ log('Keyring does not exist at %s' % keyring, level=WARNING)
1253+ return
1254+
1255+ os.remove(keyring)
1256+ log('Deleted ring at %s.' % keyring, level=INFO)
1257+
1258+
1259 def create_key_file(service, key):
1260 """Create a file containing key."""
1261 keyfile = _keyfile_path(service)
1262
1263=== modified file 'hooks/charmhelpers/contrib/storage/linux/loopback.py'
1264--- hooks/charmhelpers/contrib/storage/linux/loopback.py 2014-12-10 20:28:40 +0000
1265+++ hooks/charmhelpers/contrib/storage/linux/loopback.py 2015-01-26 09:01:00 +0000
1266@@ -1,3 +1,19 @@
1267+# Copyright 2014-2015 Canonical Limited.
1268+#
1269+# This file is part of charm-helpers.
1270+#
1271+# charm-helpers is free software: you can redistribute it and/or modify
1272+# it under the terms of the GNU Lesser General Public License version 3 as
1273+# published by the Free Software Foundation.
1274+#
1275+# charm-helpers is distributed in the hope that it will be useful,
1276+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1277+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1278+# GNU Lesser General Public License for more details.
1279+#
1280+# You should have received a copy of the GNU Lesser General Public License
1281+# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
1282+
1283 import os
1284 import re
1285 from subprocess import (
1286
1287=== modified file 'hooks/charmhelpers/contrib/storage/linux/lvm.py'
1288--- hooks/charmhelpers/contrib/storage/linux/lvm.py 2014-12-10 20:28:40 +0000
1289+++ hooks/charmhelpers/contrib/storage/linux/lvm.py 2015-01-26 09:01:00 +0000
1290@@ -1,3 +1,19 @@
1291+# Copyright 2014-2015 Canonical Limited.
1292+#
1293+# This file is part of charm-helpers.
1294+#
1295+# charm-helpers is free software: you can redistribute it and/or modify
1296+# it under the terms of the GNU Lesser General Public License version 3 as
1297+# published by the Free Software Foundation.
1298+#
1299+# charm-helpers is distributed in the hope that it will be useful,
1300+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1301+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1302+# GNU Lesser General Public License for more details.
1303+#
1304+# You should have received a copy of the GNU Lesser General Public License
1305+# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
1306+
1307 from subprocess import (
1308 CalledProcessError,
1309 check_call,
1310
1311=== modified file 'hooks/charmhelpers/contrib/storage/linux/utils.py'
1312--- hooks/charmhelpers/contrib/storage/linux/utils.py 2014-12-10 20:28:40 +0000
1313+++ hooks/charmhelpers/contrib/storage/linux/utils.py 2015-01-26 09:01:00 +0000
1314@@ -1,3 +1,19 @@
1315+# Copyright 2014-2015 Canonical Limited.
1316+#
1317+# This file is part of charm-helpers.
1318+#
1319+# charm-helpers is free software: you can redistribute it and/or modify
1320+# it under the terms of the GNU Lesser General Public License version 3 as
1321+# published by the Free Software Foundation.
1322+#
1323+# charm-helpers is distributed in the hope that it will be useful,
1324+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1325+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1326+# GNU Lesser General Public License for more details.
1327+#
1328+# You should have received a copy of the GNU Lesser General Public License
1329+# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
1330+
1331 import os
1332 import re
1333 from stat import S_ISBLK
1334
1335=== modified file 'hooks/charmhelpers/core/__init__.py'
1336--- hooks/charmhelpers/core/__init__.py 2013-10-14 16:10:30 +0000
1337+++ hooks/charmhelpers/core/__init__.py 2015-01-26 09:01:00 +0000
1338@@ -0,0 +1,15 @@
1339+# Copyright 2014-2015 Canonical Limited.
1340+#
1341+# This file is part of charm-helpers.
1342+#
1343+# charm-helpers is free software: you can redistribute it and/or modify
1344+# it under the terms of the GNU Lesser General Public License version 3 as
1345+# published by the Free Software Foundation.
1346+#
1347+# charm-helpers is distributed in the hope that it will be useful,
1348+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1349+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1350+# GNU Lesser General Public License for more details.
1351+#
1352+# You should have received a copy of the GNU Lesser General Public License
1353+# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
1354
1355=== modified file 'hooks/charmhelpers/core/decorators.py'
1356--- hooks/charmhelpers/core/decorators.py 2015-01-13 10:09:13 +0000
1357+++ hooks/charmhelpers/core/decorators.py 2015-01-26 09:01:00 +0000
1358@@ -1,3 +1,19 @@
1359+# Copyright 2014-2015 Canonical Limited.
1360+#
1361+# This file is part of charm-helpers.
1362+#
1363+# charm-helpers is free software: you can redistribute it and/or modify
1364+# it under the terms of the GNU Lesser General Public License version 3 as
1365+# published by the Free Software Foundation.
1366+#
1367+# charm-helpers is distributed in the hope that it will be useful,
1368+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1369+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1370+# GNU Lesser General Public License for more details.
1371+#
1372+# You should have received a copy of the GNU Lesser General Public License
1373+# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
1374+
1375 #
1376 # Copyright 2014 Canonical Ltd.
1377 #
1378
1379=== modified file 'hooks/charmhelpers/core/fstab.py'
1380--- hooks/charmhelpers/core/fstab.py 2014-12-10 20:28:40 +0000
1381+++ hooks/charmhelpers/core/fstab.py 2015-01-26 09:01:00 +0000
1382@@ -1,6 +1,22 @@
1383 #!/usr/bin/env python
1384 # -*- coding: utf-8 -*-
1385
1386+# Copyright 2014-2015 Canonical Limited.
1387+#
1388+# This file is part of charm-helpers.
1389+#
1390+# charm-helpers is free software: you can redistribute it and/or modify
1391+# it under the terms of the GNU Lesser General Public License version 3 as
1392+# published by the Free Software Foundation.
1393+#
1394+# charm-helpers is distributed in the hope that it will be useful,
1395+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1396+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1397+# GNU Lesser General Public License for more details.
1398+#
1399+# You should have received a copy of the GNU Lesser General Public License
1400+# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
1401+
1402 __author__ = 'Jorge Niedbalski R. <jorge.niedbalski@canonical.com>'
1403
1404 import io
1405
1406=== modified file 'hooks/charmhelpers/core/hookenv.py'
1407--- hooks/charmhelpers/core/hookenv.py 2014-12-11 17:46:56 +0000
1408+++ hooks/charmhelpers/core/hookenv.py 2015-01-26 09:01:00 +0000
1409@@ -1,3 +1,19 @@
1410+# Copyright 2014-2015 Canonical Limited.
1411+#
1412+# This file is part of charm-helpers.
1413+#
1414+# charm-helpers is free software: you can redistribute it and/or modify
1415+# it under the terms of the GNU Lesser General Public License version 3 as
1416+# published by the Free Software Foundation.
1417+#
1418+# charm-helpers is distributed in the hope that it will be useful,
1419+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1420+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1421+# GNU Lesser General Public License for more details.
1422+#
1423+# You should have received a copy of the GNU Lesser General Public License
1424+# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
1425+
1426 "Interactions with the Juju environment"
1427 # Copyright 2013 Canonical Ltd.
1428 #
1429
1430=== modified file 'hooks/charmhelpers/core/host.py'
1431--- hooks/charmhelpers/core/host.py 2015-01-13 10:09:13 +0000
1432+++ hooks/charmhelpers/core/host.py 2015-01-26 09:01:00 +0000
1433@@ -1,3 +1,19 @@
1434+# Copyright 2014-2015 Canonical Limited.
1435+#
1436+# This file is part of charm-helpers.
1437+#
1438+# charm-helpers is free software: you can redistribute it and/or modify
1439+# it under the terms of the GNU Lesser General Public License version 3 as
1440+# published by the Free Software Foundation.
1441+#
1442+# charm-helpers is distributed in the hope that it will be useful,
1443+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1444+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1445+# GNU Lesser General Public License for more details.
1446+#
1447+# You should have received a copy of the GNU Lesser General Public License
1448+# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
1449+
1450 """Tools for working with the host system"""
1451 # Copyright 2012 Canonical Ltd.
1452 #
1453@@ -168,10 +184,10 @@
1454 log("Removing non-directory file {} prior to mkdir()".format(path))
1455 os.unlink(realpath)
1456 os.makedirs(realpath, perms)
1457- os.chown(realpath, uid, gid)
1458 elif not path_exists:
1459 os.makedirs(realpath, perms)
1460- os.chown(realpath, uid, gid)
1461+ os.chown(realpath, uid, gid)
1462+ os.chmod(realpath, perms)
1463
1464
1465 def write_file(path, content, owner='root', group='root', perms=0o444):
1466@@ -389,6 +405,9 @@
1467 * 0 => Installed revno is the same as supplied arg
1468 * -1 => Installed revno is less than supplied arg
1469
1470+ This function imports apt_cache function from charmhelpers.fetch if
1471+ the pkgcache argument is None. Be sure to add charmhelpers.fetch if
1472+ you call this function, or pass an apt_pkg.Cache() instance.
1473 '''
1474 import apt_pkg
1475 if not pkgcache:
1476@@ -407,13 +426,21 @@
1477 os.chdir(cur)
1478
1479
1480-def chownr(path, owner, group):
1481+def chownr(path, owner, group, follow_links=True):
1482 uid = pwd.getpwnam(owner).pw_uid
1483 gid = grp.getgrnam(group).gr_gid
1484+ if follow_links:
1485+ chown = os.chown
1486+ else:
1487+ chown = os.lchown
1488
1489 for root, dirs, files in os.walk(path):
1490 for name in dirs + files:
1491 full = os.path.join(root, name)
1492 broken_symlink = os.path.lexists(full) and not os.path.exists(full)
1493 if not broken_symlink:
1494- os.chown(full, uid, gid)
1495+ chown(full, uid, gid)
1496+
1497+
1498+def lchownr(path, owner, group):
1499+ chownr(path, owner, group, follow_links=False)
1500
1501=== modified file 'hooks/charmhelpers/core/services/__init__.py'
1502--- hooks/charmhelpers/core/services/__init__.py 2014-12-10 20:28:40 +0000
1503+++ hooks/charmhelpers/core/services/__init__.py 2015-01-26 09:01:00 +0000
1504@@ -1,2 +1,18 @@
1505+# Copyright 2014-2015 Canonical Limited.
1506+#
1507+# This file is part of charm-helpers.
1508+#
1509+# charm-helpers is free software: you can redistribute it and/or modify
1510+# it under the terms of the GNU Lesser General Public License version 3 as
1511+# published by the Free Software Foundation.
1512+#
1513+# charm-helpers is distributed in the hope that it will be useful,
1514+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1515+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1516+# GNU Lesser General Public License for more details.
1517+#
1518+# You should have received a copy of the GNU Lesser General Public License
1519+# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
1520+
1521 from .base import * # NOQA
1522 from .helpers import * # NOQA
1523
1524=== modified file 'hooks/charmhelpers/core/services/base.py'
1525--- hooks/charmhelpers/core/services/base.py 2014-12-10 20:28:40 +0000
1526+++ hooks/charmhelpers/core/services/base.py 2015-01-26 09:01:00 +0000
1527@@ -1,3 +1,19 @@
1528+# Copyright 2014-2015 Canonical Limited.
1529+#
1530+# This file is part of charm-helpers.
1531+#
1532+# charm-helpers is free software: you can redistribute it and/or modify
1533+# it under the terms of the GNU Lesser General Public License version 3 as
1534+# published by the Free Software Foundation.
1535+#
1536+# charm-helpers is distributed in the hope that it will be useful,
1537+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1538+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1539+# GNU Lesser General Public License for more details.
1540+#
1541+# You should have received a copy of the GNU Lesser General Public License
1542+# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
1543+
1544 import os
1545 import re
1546 import json
1547
1548=== modified file 'hooks/charmhelpers/core/services/helpers.py'
1549--- hooks/charmhelpers/core/services/helpers.py 2014-12-10 20:28:40 +0000
1550+++ hooks/charmhelpers/core/services/helpers.py 2015-01-26 09:01:00 +0000
1551@@ -1,3 +1,19 @@
1552+# Copyright 2014-2015 Canonical Limited.
1553+#
1554+# This file is part of charm-helpers.
1555+#
1556+# charm-helpers is free software: you can redistribute it and/or modify
1557+# it under the terms of the GNU Lesser General Public License version 3 as
1558+# published by the Free Software Foundation.
1559+#
1560+# charm-helpers is distributed in the hope that it will be useful,
1561+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1562+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1563+# GNU Lesser General Public License for more details.
1564+#
1565+# You should have received a copy of the GNU Lesser General Public License
1566+# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
1567+
1568 import os
1569 import yaml
1570 from charmhelpers.core import hookenv
1571
1572=== modified file 'hooks/charmhelpers/core/sysctl.py'
1573--- hooks/charmhelpers/core/sysctl.py 2014-12-10 20:28:40 +0000
1574+++ hooks/charmhelpers/core/sysctl.py 2015-01-26 09:01:00 +0000
1575@@ -1,6 +1,22 @@
1576 #!/usr/bin/env python
1577 # -*- coding: utf-8 -*-
1578
1579+# Copyright 2014-2015 Canonical Limited.
1580+#
1581+# This file is part of charm-helpers.
1582+#
1583+# charm-helpers is free software: you can redistribute it and/or modify
1584+# it under the terms of the GNU Lesser General Public License version 3 as
1585+# published by the Free Software Foundation.
1586+#
1587+# charm-helpers is distributed in the hope that it will be useful,
1588+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1589+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1590+# GNU Lesser General Public License for more details.
1591+#
1592+# You should have received a copy of the GNU Lesser General Public License
1593+# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
1594+
1595 __author__ = 'Jorge Niedbalski R. <jorge.niedbalski@canonical.com>'
1596
1597 import yaml
1598
1599=== modified file 'hooks/charmhelpers/core/templating.py'
1600--- hooks/charmhelpers/core/templating.py 2014-12-15 09:23:16 +0000
1601+++ hooks/charmhelpers/core/templating.py 2015-01-26 09:01:00 +0000
1602@@ -1,3 +1,19 @@
1603+# Copyright 2014-2015 Canonical Limited.
1604+#
1605+# This file is part of charm-helpers.
1606+#
1607+# charm-helpers is free software: you can redistribute it and/or modify
1608+# it under the terms of the GNU Lesser General Public License version 3 as
1609+# published by the Free Software Foundation.
1610+#
1611+# charm-helpers is distributed in the hope that it will be useful,
1612+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1613+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1614+# GNU Lesser General Public License for more details.
1615+#
1616+# You should have received a copy of the GNU Lesser General Public License
1617+# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
1618+
1619 import os
1620
1621 from charmhelpers.core import host
1622
1623=== modified file 'hooks/charmhelpers/fetch/__init__.py'
1624--- hooks/charmhelpers/fetch/__init__.py 2015-01-13 10:09:13 +0000
1625+++ hooks/charmhelpers/fetch/__init__.py 2015-01-26 09:01:00 +0000
1626@@ -1,3 +1,19 @@
1627+# Copyright 2014-2015 Canonical Limited.
1628+#
1629+# This file is part of charm-helpers.
1630+#
1631+# charm-helpers is free software: you can redistribute it and/or modify
1632+# it under the terms of the GNU Lesser General Public License version 3 as
1633+# published by the Free Software Foundation.
1634+#
1635+# charm-helpers is distributed in the hope that it will be useful,
1636+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1637+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1638+# GNU Lesser General Public License for more details.
1639+#
1640+# You should have received a copy of the GNU Lesser General Public License
1641+# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
1642+
1643 import importlib
1644 from tempfile import NamedTemporaryFile
1645 import time
1646
1647=== modified file 'hooks/charmhelpers/fetch/archiveurl.py'
1648--- hooks/charmhelpers/fetch/archiveurl.py 2014-12-10 20:28:40 +0000
1649+++ hooks/charmhelpers/fetch/archiveurl.py 2015-01-26 09:01:00 +0000
1650@@ -1,3 +1,19 @@
1651+# Copyright 2014-2015 Canonical Limited.
1652+#
1653+# This file is part of charm-helpers.
1654+#
1655+# charm-helpers is free software: you can redistribute it and/or modify
1656+# it under the terms of the GNU Lesser General Public License version 3 as
1657+# published by the Free Software Foundation.
1658+#
1659+# charm-helpers is distributed in the hope that it will be useful,
1660+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1661+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1662+# GNU Lesser General Public License for more details.
1663+#
1664+# You should have received a copy of the GNU Lesser General Public License
1665+# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
1666+
1667 import os
1668 import hashlib
1669 import re
1670
1671=== modified file 'hooks/charmhelpers/fetch/bzrurl.py'
1672--- hooks/charmhelpers/fetch/bzrurl.py 2014-12-10 20:28:40 +0000
1673+++ hooks/charmhelpers/fetch/bzrurl.py 2015-01-26 09:01:00 +0000
1674@@ -1,3 +1,19 @@
1675+# Copyright 2014-2015 Canonical Limited.
1676+#
1677+# This file is part of charm-helpers.
1678+#
1679+# charm-helpers is free software: you can redistribute it and/or modify
1680+# it under the terms of the GNU Lesser General Public License version 3 as
1681+# published by the Free Software Foundation.
1682+#
1683+# charm-helpers is distributed in the hope that it will be useful,
1684+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1685+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1686+# GNU Lesser General Public License for more details.
1687+#
1688+# You should have received a copy of the GNU Lesser General Public License
1689+# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
1690+
1691 import os
1692 from charmhelpers.fetch import (
1693 BaseFetchHandler,
1694@@ -11,10 +27,12 @@
1695
1696 try:
1697 from bzrlib.branch import Branch
1698+ from bzrlib import bzrdir, workingtree, errors
1699 except ImportError:
1700 from charmhelpers.fetch import apt_install
1701 apt_install("python-bzrlib")
1702 from bzrlib.branch import Branch
1703+ from bzrlib import bzrdir, workingtree, errors
1704
1705
1706 class BzrUrlFetchHandler(BaseFetchHandler):
1707@@ -35,8 +53,14 @@
1708 from bzrlib.plugin import load_plugins
1709 load_plugins()
1710 try:
1711+ local_branch = bzrdir.BzrDir.create_branch_convenience(dest)
1712+ except errors.AlreadyControlDirError:
1713+ local_branch = Branch.open(dest)
1714+ try:
1715 remote_branch = Branch.open(source)
1716- remote_branch.bzrdir.sprout(dest).open_branch()
1717+ remote_branch.push(local_branch)
1718+ tree = workingtree.WorkingTree.open(dest)
1719+ tree.update()
1720 except Exception as e:
1721 raise e
1722
1723
1724=== modified file 'hooks/charmhelpers/fetch/giturl.py'
1725--- hooks/charmhelpers/fetch/giturl.py 2014-12-10 20:28:40 +0000
1726+++ hooks/charmhelpers/fetch/giturl.py 2015-01-26 09:01:00 +0000
1727@@ -1,3 +1,19 @@
1728+# Copyright 2014-2015 Canonical Limited.
1729+#
1730+# This file is part of charm-helpers.
1731+#
1732+# charm-helpers is free software: you can redistribute it and/or modify
1733+# it under the terms of the GNU Lesser General Public License version 3 as
1734+# published by the Free Software Foundation.
1735+#
1736+# charm-helpers is distributed in the hope that it will be useful,
1737+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1738+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1739+# GNU Lesser General Public License for more details.
1740+#
1741+# You should have received a copy of the GNU Lesser General Public License
1742+# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
1743+
1744 import os
1745 from charmhelpers.fetch import (
1746 BaseFetchHandler,
1747@@ -16,6 +32,8 @@
1748 apt_install("python-git")
1749 from git import Repo
1750
1751+from git.exc import GitCommandError
1752+
1753
1754 class GitUrlFetchHandler(BaseFetchHandler):
1755 """Handler for git branches via generic and github URLs"""
1756@@ -46,6 +64,8 @@
1757 mkdir(dest_dir, perms=0o755)
1758 try:
1759 self.clone(source, dest_dir, branch)
1760+ except GitCommandError as e:
1761+ raise UnhandledSource(e.message)
1762 except OSError as e:
1763 raise UnhandledSource(e.strerror)
1764 return dest_dir
1765
1766=== added symlink 'hooks/nrpe-external-master-relation-changed'
1767=== target is u'ceilometer_hooks.py'
1768=== added symlink 'hooks/nrpe-external-master-relation-joined'
1769=== target is u'ceilometer_hooks.py'
1770=== modified file 'metadata.yaml'
1771--- metadata.yaml 2013-11-29 15:34:44 +0000
1772+++ metadata.yaml 2015-01-26 09:01:00 +0000
1773@@ -15,6 +15,9 @@
1774 - miscellaneous
1775 - openstack
1776 provides:
1777+ nrpe-external-master:
1778+ interface: nrpe-external-master
1779+ scope: container
1780 nova-ceilometer:
1781 interface: nova-ceilometer
1782 scope: container
1783
1784=== modified file 'unit_tests/test_ceilometer_hooks.py'
1785--- unit_tests/test_ceilometer_hooks.py 2014-12-11 02:46:41 +0000
1786+++ unit_tests/test_ceilometer_hooks.py 2015-01-26 09:01:00 +0000
1787@@ -22,7 +22,8 @@
1788 'CONFIGS',
1789 'relation_set',
1790 'openstack_upgrade_available',
1791- 'do_openstack_upgrade'
1792+ 'do_openstack_upgrade',
1793+ 'update_nrpe_config',
1794 ]
1795
1796
1797@@ -53,6 +54,7 @@
1798 def test_ceilometer_changed(self, mock_config):
1799 hooks.hooks.execute(['hooks/ceilometer-service-relation-changed'])
1800 self.assertTrue(self.CONFIGS.write_all.called)
1801+ self.assertTrue(self.update_nrpe_config.called)
1802
1803 @patch('charmhelpers.core.hookenv.config')
1804 def test_nova_ceilometer_joined(self, mock_config):
1805@@ -68,6 +70,7 @@
1806 assert_called_with('ceilometer-common')
1807 self.assertFalse(self.do_openstack_upgrade.called)
1808 self.assertTrue(self.CONFIGS.write_all.called)
1809+ self.assertTrue(self.update_nrpe_config.called)
1810
1811 @patch('charmhelpers.core.hookenv.config')
1812 def test_config_changed_upgrade(self, mock_config):
1813@@ -77,3 +80,4 @@
1814 assert_called_with('ceilometer-common')
1815 self.assertTrue(self.do_openstack_upgrade.called)
1816 self.assertTrue(self.CONFIGS.write_all.called)
1817+ self.assertTrue(self.update_nrpe_config.called)

Subscribers

People subscribed via source and target branches