From 1dea26a747d0af4ce3431d67f1e5e339f811f720 Mon Sep 17 00:00:00 2001 From: Liam Young Date: Wed, 29 Jul 2015 11:51:24 +0100 Subject: [PATCH] [gnuoy,trivial] Pre-release charmhelper sync --- .../charmhelpers/contrib/openstack/context.py | 18 +++++--- .../contrib/openstack/templating.py | 4 +- .../contrib/storage/linux/utils.py | 2 +- hooks/charmhelpers/core/files.py | 45 +++++++++++++++++++ hooks/charmhelpers/core/hookenv.py | 3 +- 5 files changed, 63 insertions(+), 9 deletions(-) create mode 100644 hooks/charmhelpers/core/files.py diff --git a/hooks/charmhelpers/contrib/openstack/context.py b/hooks/charmhelpers/contrib/openstack/context.py index 8f3f1b15..bbf4722b 100644 --- a/hooks/charmhelpers/contrib/openstack/context.py +++ b/hooks/charmhelpers/contrib/openstack/context.py @@ -1053,11 +1053,17 @@ class SubordinateConfigContext(OSContextGenerator): """ self.service = service self.config_file = config_file - self.interface = interface + if isinstance(interface, list): + self.interfaces = interface + else: + self.interfaces = [interface] def __call__(self): ctxt = {'sections': {}} - for rid in relation_ids(self.interface): + rids = [] + for interface in self.interfaces: + rids.extend(relation_ids(interface)) + for rid in rids: for unit in related_units(rid): sub_config = relation_get('subordinate_configuration', rid=rid, unit=unit) @@ -1085,13 +1091,15 @@ class SubordinateConfigContext(OSContextGenerator): sub_config = sub_config[self.config_file] for k, v in six.iteritems(sub_config): if k == 'sections': - for section, config_dict in six.iteritems(v): + for section, config_list in six.iteritems(v): log("adding section '%s'" % (section), level=DEBUG) - ctxt[k][section] = config_dict + if ctxt[k].get(section): + ctxt[k][section].extend(config_list) + else: + ctxt[k][section] = config_list else: ctxt[k] = v - log("%d section(s) found" % (len(ctxt['sections'])), level=DEBUG) return ctxt diff --git a/hooks/charmhelpers/contrib/openstack/templating.py b/hooks/charmhelpers/contrib/openstack/templating.py index 24cb272b..021d8cf9 100644 --- a/hooks/charmhelpers/contrib/openstack/templating.py +++ b/hooks/charmhelpers/contrib/openstack/templating.py @@ -29,8 +29,8 @@ from charmhelpers.contrib.openstack.utils import OPENSTACK_CODENAMES try: from jinja2 import FileSystemLoader, ChoiceLoader, Environment, exceptions except ImportError: - # python-jinja2 may not be installed yet, or we're running unittests. - FileSystemLoader = ChoiceLoader = Environment = exceptions = None + apt_install('python-jinja2', fatal=True) + from jinja2 import FileSystemLoader, ChoiceLoader, Environment, exceptions class OSConfigException(Exception): diff --git a/hooks/charmhelpers/contrib/storage/linux/utils.py b/hooks/charmhelpers/contrib/storage/linux/utils.py index c8373b72..e2769e49 100644 --- a/hooks/charmhelpers/contrib/storage/linux/utils.py +++ b/hooks/charmhelpers/contrib/storage/linux/utils.py @@ -67,4 +67,4 @@ def is_device_mounted(device): out = check_output(['mount']).decode('UTF-8') if is_partition: return bool(re.search(device + r"\b", out)) - return bool(re.search(device + r"[0-9]+\b", out)) + return bool(re.search(device + r"[0-9]*\b", out)) diff --git a/hooks/charmhelpers/core/files.py b/hooks/charmhelpers/core/files.py new file mode 100644 index 00000000..0f12d321 --- /dev/null +++ b/hooks/charmhelpers/core/files.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright 2014-2015 Canonical Limited. +# +# This file is part of charm-helpers. +# +# charm-helpers is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 as +# published by the Free Software Foundation. +# +# charm-helpers is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with charm-helpers. If not, see . + +__author__ = 'Jorge Niedbalski ' + +import os +import subprocess + + +def sed(filename, before, after, flags='g'): + """ + Search and replaces the given pattern on filename. + + :param filename: relative or absolute file path. + :param before: expression to be replaced (see 'man sed') + :param after: expression to replace with (see 'man sed') + :param flags: sed-compatible regex flags in example, to make + the search and replace case insensitive, specify ``flags="i"``. + The ``g`` flag is always specified regardless, so you do not + need to remember to include it when overriding this parameter. + :returns: If the sed command exit code was zero then return, + otherwise raise CalledProcessError. + """ + expression = r's/{0}/{1}/{2}'.format(before, + after, flags) + + return subprocess.check_call(["sed", "-i", "-r", "-e", + expression, + os.path.expanduser(filename)]) diff --git a/hooks/charmhelpers/core/hookenv.py b/hooks/charmhelpers/core/hookenv.py index dd8def9a..15b09d11 100644 --- a/hooks/charmhelpers/core/hookenv.py +++ b/hooks/charmhelpers/core/hookenv.py @@ -21,6 +21,7 @@ # Charm Helpers Developers from __future__ import print_function +import copy from distutils.version import LooseVersion from functools import wraps import glob @@ -263,7 +264,7 @@ class Config(dict): self.path = path or self.path with open(self.path) as f: self._prev_dict = json.load(f) - for k, v in self._prev_dict.items(): + for k, v in copy.deepcopy(self._prev_dict).items(): if k not in self: self[k] = v