Exemple #1
0
 def _wrapped(*args, **kwargs):
     active_flags = get_flags()
     missing_flags = [flag for flag in desired_flags if flag not in active_flags]
     if missing_flags:
         hookenv.log('%s called before flag%s: %s' % (
             short_action_id,
             's' if len(missing_flags) > 1 else '',
             ', '.join(missing_flags)), hookenv.WARNING)
     return func(*args, **kwargs)
Exemple #2
0
    def render_configs(self, configs, adapters_instance=None):
        """Render the configuration files identified in the list passed as
        configs.

        Configs may not only be loaded via OpenStack loaders but also via
        string templates passed via config options or from relation data.
        This must be explicitly declared via string_templates dict of a given
        derived charm class by using a relation name that identifies a relation
        adapter or config option adapter and a property to be used from that
        adapter instance.

        :param configs: list of strings, the names of the configuration files.
        :param adapters_instance: [optional] the adapters_instance to use.
        """
        if adapters_instance is None:
            interfaces = []
            for f in flags.get_flags():
                ep_from_f = relations.endpoint_from_flag(f)
                if ep_from_f:
                    interfaces.append(ep_from_f)
            try:
                adapters_instance = self.adapters_class(interfaces,
                                                        charm_instance=self)
            except TypeError:
                adapters_instance = self.adapters_class(interfaces)

        with self.restart_on_change():
            for conf in configs:
                # check if we need to load a template from a string
                config_template = self._get_string_template(
                    conf, adapters_instance)
                if config_template is False:
                    # got a string template but it was not provided which
                    # means we need to skip this config to avoid rendering
                    return

                charmhelpers.core.templating.render(
                    source=os.path.basename(conf),
                    template_loader=os_templating.get_loader(
                        'templates/', self.release),
                    target=conf,
                    context=adapters_instance,
                    config_template=config_template,
                    group=self.group,
                    perms=0o640,
                )
Exemple #3
0
def _migrate_conversations():  # noqa
    """
    Due to issue #28 (https://github.com/juju-solutions/charms.reactive/issues/28),
    conversations needed to be updated to be namespaced per relation ID for SERVICE
    and UNIT scope.  To ensure backwards compatibility, this updates all convs in
    the old format to the new.

    TODO: Remove in 2.0.0
    """
    for key, data in unitdata.kv().getrange('reactive.conversations.').items():
        if 'local-data' in key:
            continue
        if 'namespace' in data:
            continue
        relation_name = data.pop('relation_name')
        if data['scope'] == scopes.GLOBAL:
            data['namespace'] = relation_name
            unitdata.kv().set(key, data)
        else:
            # split the conv based on the relation ID
            new_keys = []
            for rel_id in hookenv.relation_ids(relation_name):
                new_key = Conversation._key(rel_id, data['scope'])
                new_units = set(hookenv.related_units(rel_id)) & set(
                    data['units'])
                if new_units:
                    unitdata.kv().set(
                        new_key, {
                            'namespace': rel_id,
                            'scope': data['scope'],
                            'units': sorted(new_units),
                        })
                    new_keys.append(new_key)
            unitdata.kv().unset(key)
            # update the states pointing to the old conv key to point to the
            # (potentially multiple) new key(s)
            for flag in get_flags():
                value = _get_flag_value(flag)
                if not value:
                    continue
                if key not in value['conversations']:
                    continue
                value['conversations'].remove(key)
                value['conversations'].extend(new_keys)
                set_flag(flag, value)
Exemple #4
0
 def test_get_unset_flags(self):
     self.assertEqual(flags.get_flags(), [])
     flags.set_flag('foo')
     self.assertEqual(flags.get_flags(), ['foo'])
     self.assertEqual(flags.get_unset_flags('foo', 'bar'), ['bar'])
Exemple #5
0
def installed():
    '''Return the set of deb packages completed install'''
    return set(
        flag.split('.', 2)[2] for flag in flags.get_flags()
        if flag.startswith('apt.installed.'))