15
15
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
20
from collections import Iterable
19
from inspect import getargspec
20
from collections import Iterable, OrderedDict
22
22
from charmhelpers.core import host
23
23
from charmhelpers.core import hookenv
120
120
self._ready_file = os.path.join(hookenv.charm_dir(), 'READY-SERVICES.json')
121
121
self._ready = None
122
self.services = OrderedDict()
123
123
for service in services or []:
124
124
service_name = service['service']
125
125
self.services[service_name] = service
129
129
Handle the current hook by doing The Right Thing with the registered services.
131
hook_name = hookenv.hook_name()
132
if hook_name == 'stop':
136
self.reconfigure_services()
137
cfg = hookenv.config()
138
if cfg.implicit_save:
131
hookenv._run_atstart()
133
hook_name = hookenv.hook_name()
134
if hook_name == 'stop':
137
self.reconfigure_services()
139
except SystemExit as x:
140
if x.code is None or x.code == 0:
141
hookenv._run_atexit()
142
hookenv._run_atexit()
141
144
def provide_data(self):
145
148
A provider must have a `name` attribute, which indicates which relation
146
149
to set data on, and a `provide_data()` method, which returns a dict of
152
The `provide_data()` method can optionally accept two parameters:
154
* ``remote_service`` The name of the remote service that the data will
155
be provided to. The `provide_data()` method will be called once
156
for each connected service (not unit). This allows the method to
157
tailor its data to the given service.
158
* ``service_ready`` Whether or not the service definition had all of
159
its requirements met, and thus the ``data_ready`` callbacks run.
161
Note that the ``provided_data`` methods are now called **after** the
162
``data_ready`` callbacks are run. This gives the ``data_ready`` callbacks
163
a chance to generate any data necessary for the providing to the remote
149
hook_name = hookenv.hook_name()
150
for service in self.services.values():
166
for service_name, service in self.services.items():
167
service_ready = self.is_ready(service_name)
151
168
for provider in service.get('provided_data', []):
152
if re.match(r'{}-relation-(joined|changed)'.format(provider.name), hook_name):
153
data = provider.provide_data()
154
_ready = provider._is_ready(data) if hasattr(provider, '_is_ready') else data
156
hookenv.relation_set(None, data)
169
for relid in hookenv.relation_ids(provider.name):
170
units = hookenv.related_units(relid)
173
remote_service = units[0].split('/')[0]
174
argspec = getargspec(provider.provide_data)
175
if len(argspec.args) > 1:
176
data = provider.provide_data(remote_service, service_ready)
178
data = provider.provide_data()
180
hookenv.relation_set(relid, data)
158
182
def reconfigure_services(self, *service_names):