7
Charms define how services integrate and how their service units
8
react to events in the distributed environment, as orchestrated by
11
This specification describes how charms are defined, including their
12
metadata and hooks. It also describes the resources available to hooks
13
in working with the juju environment.
19
The `metadata.yaml` file, at the root of the charm directory,
20
describes the charm. The following fields are supported:
22
* **name:** - The charm name itself. Charm names are formed by
23
lowercase letters, digits, and dashes, and must necessarily
24
begin with a letter and have no digits alone in a dashed
27
* **summary:** - A one-line description of the charm.
29
* **description:** - Long explanation of the charm and its
32
* **provides:** - The deployed service unit must have the given
33
relations established with another service unit whose charm
34
requires them for the service to work properly. See below for how
37
* **requires:** - The deployed service unit must have the given
38
relations established with another service unit whose charm
39
provides them for the service to work properly. See below for how
42
* **peers:** - Relations that are established with P2P semantics
43
instead of a provides/requires (or client/server) style. When the
44
charm is deployed as a service unit, all the units from the
45
given service will automatically be made part of the relation.
46
See below for how to define a relation.
49
Relations available in `provides`, `requires`, and `peers` are defined
52
* **provides|requires|peers:**
54
* **<relation name>:** - This name is a user-provided value which
55
identifies the relation uniquely within the given charm.
56
Examples include "database", "cache", "proxy", and "appserver".
58
Each relation may have the following fields defined:
60
* **interface:** - This field defines the type of the
61
relation. The relation will only be established with service
62
units that define a compatible relation with the same
63
interface. Examples include "http", "mysql", and
66
* **limit:** - The maximum number of relations of this kind
67
which may be established to other service units. Defaults to
68
1 for `requires` relations, and to "none" (no limit) for
69
`provides` and `peers` relations. While you may define it,
70
this field is not yet enforced by juju.
72
* **optional:** - Whether this relation is required for the
73
service unit to function or not. Defaults to `false`, which
74
means the relation is required. While you may define it, this
75
field is not yet enforced by juju.
77
* **scope:** - Controls which units of related-to services can
78
be communicated with through this relationship. Juju supports
81
* **global:** `default` When a traditional relation is added
82
between two services, all the service units for the first service will
83
receive relation events about all service units for the second
86
* **container**: Communication is restricted to units deployed
87
in the same container. It is not possible to establish a
88
container scoped relation between principal services. See
89
:doc:`subordinate-services`.
91
As a shortcut, if these properties are not defined, and instead
92
a single string value is provided next to the relation name, the
93
string is taken as the interface value, as seen in this
99
Some sample charm definitions are provided at the end of this
106
juju uses hooks to notify a service unit about changes happening
107
in its lifecycle or the larger distributed environment. A hook running
108
for a service unit can query this environment, make any desired local
109
changes on its underlying machine, and change the relation
112
Each hook for a charm is implemented by placing an executable with
113
the desired hook name under the ``hooks/`` directory of the charm
114
directory. juju will execute the hook based on its file name when
115
the corresponding event occurs.
117
All hooks are optional. Not including a corresponding executable in
118
the charm is treated by juju as if the hook executed and then
119
exited with an exit code of 0.
121
All hooks are executed in the charm directory on the service unit.
123
The following hooks are with respect to the lifecycle of a service unit:
125
* **install** - Runs just once during the life time of a service
126
unit. Currently this hook is the right place to ensure any package
127
dependencies are met. However, in the future juju will use the
128
charm metadata to perform this role instead.
130
* **start** - Runs when the service unit is started. This happens
131
before any relation hooks are called. The purpose of this hook is
132
to get the service unit ready for relations to be established.
134
* **stop** - Runs when the service unit is stopped. If relations
135
exist, they will be broken and the respective hooks called before
138
The following hooks are called on each service unit as the membership
139
of an established relation changes:
141
* **<relation name>-relation-joined** - Runs upon each time a remote
142
service unit joins the relation.
144
* **<relation name>-relation-changed** - Runs upon each time the
145
following events occur:
147
1. A remote service unit joins the relation, right after the
148
**<relation name>-relation-joined** hook was called.
150
2. A remote service unit changes its relation settings.
152
This hook enables the charm to modify the service unit state
153
(configuration, running processes, or anything else) to adapt to
154
the relation settings of remote units.
156
An example usage is that HAProxy needs to be aware of web servers
157
as they become available, including details like its IP
158
address. Web server service units can publish their availability
159
by making the appropriate relation settings in the hook that makes
160
the most sense. Assume the HAProxy uses the relation name of
161
``server``. Then upon that happening, the HAProxy in its
162
``server-relation-changed hook`` can then change its own
163
configuration as to what is available to be proxied.
165
* **<relation name>-relation-departed** - Runs upon each time a
166
remote service unit leaves a relation. This could happen because
167
the service unit has been removed, its service has been destroyed,
168
or the relation between this service and the remote service has
171
An example usage is that HAProxy needs to be aware of web servers
172
when they are no longer available. It can remove each web server
173
its configuration as the corresponding service unit departs the
176
This relation hook is with respect to the relation itself:
178
* **<relation name>-relation-broken** - Runs when a relation which
179
had at least one other relation hook run for it (successfully or
180
not) is now unavailable. The service unit can then clean up any
183
An example might be cleaning up the configuration changes which
184
were performed when HAProxy was asked to load-balance for another
187
Note that the coupling between charms is defined by which settings
188
are required and made available to them through the relation hooks and
189
how these settings are used. Those conventions then define what the
190
relation interface really is, and the **interface** name in the
191
`metadata.yaml` file is simply a way to refer to them and avoid the
192
attempting of incompatible conversations. Keep that in mind when
193
designing your charms and relations, since it is a good idea to
194
allow the implementation of the charm to change and be replaced with
195
alternative versions without changing the relation conventions in a
196
backwards incompatible way.
202
Hooks can expect to be invoked with a standard environment and
203
context. The following environment variables are set:
205
* **$JUJU_UNIT_NAME** - The name of the local unit executing,
206
in the form ``<service name>/<unit sequence>``. E.g. ``myblog/3``.
208
Hooks called for relation changes will have the follow additional
209
environment variables set:
211
* **$JUJU_RELATION** - The relation name this hook is running
212
for. It's redundant with the hook name, but is necessary for
213
the command line tools to know the current context.
215
* **$JUJU_REMOTE_UNIT** - The unit name of the remote unit
216
which has triggered the hook execution.
219
Hook commands for working with relations
220
----------------------------------------
222
In implementing their functionality, hooks can leverage a set of
223
command tools provided by juju for working with relations. These
224
utilities enable the hook to collaborate on their relation settings,
225
and to inquire about the peers the service unit has relations with.
227
The following command line tools are made available:
229
* **relation-get** - Queries a setting from an established relation
230
with one or more service units. This command will read some
231
context information from environment variables (e.g.
232
$JUJU_RELATION_NAME).
236
Get the IP address from the remote unit which triggered the hook
241
Get all the settings from the remote unit which triggered the hook
246
Get the port information from the `wordpress/3` unit::
248
relation-get port wordpress/3
250
Get all the settings from the `wordpress/3` unit, in JSON format::
252
relation-get - wordpress/3
254
* **relation-set** - Changes a setting in an established relation.
258
Set this unit's port number for other peers to use::
260
relation-set port=8080
262
Change two settings at once::
264
relation-set dbname=wordpress dbpass="super secur3"
266
Change several settings at once, with a JSON file::
268
cat settings.json | relation-set
274
* **relation-list** - List all service units participating in the
275
established relation. This list excludes the local service unit
276
which is executing the command. For `provides` and `requires`
277
relations, this command will always return a single service unit.
281
MEMBERS=$(relation-list)
283
Changes to relation settings are only committed if the hook exited
284
with an exit code of 0. Such changes will then trigger further hook
285
execution in the remote unit(s), through the **<relation
286
name>-relation-changed** hook. This mechanism enables a general
287
communication mechanism for service units to coordinate.
290
Hook commands for opening and closing ports
291
-------------------------------------------
293
Service exposing determines which ports to expose by using the
294
``open-port`` and ``close-port`` commands in hooks. They may be
295
executed within any charm hook. The commands take the same
298
open-port port[/protocol]
300
close-port port[/protocol]
302
These commands are executed immediately; they do not depend on the
303
exit status of the hook.
305
As an example, consider the WordPress charm, which has been deployed
306
as ``my-wordpress``. After completing the setup and restart of Apache,
307
the ``wordpress`` charm can then publish the available port in its
308
``start`` hook for a given service unit::
312
External access to the service unit is only allowed when both
313
``open-port`` is executed within any hook and the administrator has
314
exposed its service. The order in which these happen is not
319
Being able to use any hook may be important for your charm.
320
Ideally, the service does not have ports that are vulnerable if
321
exposed prior to the service being fully ready. But if that's the
322
case, you can solve this problem by only opening the port in the
323
appropriate hook and when the desired conditions are met.
325
Alternatively, you may need to expose more than one port, or expose
326
ports that don't use the TCP protocol. To expose ports for
327
HTTP and HTTPS, your charm could instead make these settings::
332
Or if you are writing a charm for a DNS server that you would like
333
to expose, then specify the protocol to be UDP::
337
When the service unit is removed or stopped for any reason, the
338
firewall will again be changed to block traffic which was previously
339
allowed to reach the exposed service. Your charm can also do this to
344
To be precise, the firewall is only open for the exposed ports during
345
the time both these conditions hold:
347
* A service has been exposed.
348
* A corresponding ``open-port`` command has been run (without a
349
subsequent ``close-port``).
352
Sample metadata.yaml files
353
--------------------------
355
Below are presented some sample metadata files.
362
summary: "A pretty popular database"
372
summary: "A pretty popular blog engine"
386
summary: "Scalable K/V Store in Erlang with Clocks :-)"