~bcsaller/pyjuju/lxc-repairs

« back to all changes in this revision

Viewing changes to docs/source/charm.rst

  • Committer: Benjamin Saller
  • Date: 2012-07-20 17:28:30 UTC
  • mfrom: (542.1.17 fix-buildd-fail)
  • Revision ID: bcsaller@gmail.com-20120720172830-49xmmh12cne6r0ww
merge trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
Charms
2
 
======
3
 
 
4
 
Introduction
5
 
------------
6
 
 
7
 
Charms define how services integrate and how their service units
8
 
react to events in the distributed environment, as orchestrated by
9
 
juju.
10
 
 
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.
14
 
 
15
 
 
16
 
The metadata file
17
 
-----------------
18
 
 
19
 
The `metadata.yaml` file, at the root of the charm directory,
20
 
describes the charm. The following fields are supported:
21
 
 
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
25
 
    section.
26
 
 
27
 
  * **summary:** - A one-line description of the charm.
28
 
 
29
 
  * **description:** - Long explanation of the charm and its
30
 
    features.
31
 
 
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
35
 
    to define a relation.
36
 
 
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
40
 
    to define a relation.
41
 
 
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.
47
 
 
48
 
 
49
 
Relations available in `provides`, `requires`, and `peers` are defined
50
 
as follows:
51
 
 
52
 
  * **provides|requires|peers:**
53
 
 
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".
57
 
 
58
 
      Each relation may have the following fields defined:
59
 
 
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
64
 
        "backup-schedule".
65
 
 
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.
71
 
 
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.
76
 
 
77
 
      * **scope:** - Controls which units of related-to services can
78
 
        be communicated with through this relationship. Juju supports
79
 
        the following scopes:
80
 
 
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
84
 
          service.
85
 
 
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`.
90
 
 
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
94
 
      example::
95
 
 
96
 
          requires:
97
 
            db: mysql
98
 
 
99
 
Some sample charm definitions are provided at the end of this
100
 
specification.
101
 
 
102
 
 
103
 
Hooks
104
 
-----
105
 
 
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
110
 
settings.
111
 
 
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.
116
 
 
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.
120
 
 
121
 
All hooks are executed in the charm directory on the service unit.
122
 
 
123
 
The following hooks are with respect to the lifecycle of a service unit:
124
 
 
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.
129
 
 
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.
133
 
 
134
 
  * **stop** - Runs when the service unit is stopped. If relations
135
 
    exist, they will be broken and the respective hooks called before
136
 
    this hook is called.
137
 
 
138
 
The following hooks are called on each service unit as the membership
139
 
of an established relation changes:
140
 
 
141
 
  * **<relation name>-relation-joined** - Runs upon each time a remote
142
 
    service unit joins the relation.
143
 
 
144
 
  * **<relation name>-relation-changed** - Runs upon each time the
145
 
    following events occur:
146
 
 
147
 
    1. A remote service unit joins the relation, right after the
148
 
       **<relation name>-relation-joined** hook was called.
149
 
 
150
 
    2. A remote service unit changes its relation settings.
151
 
 
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.
155
 
 
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.
164
 
 
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
169
 
    been removed.
170
 
 
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
174
 
    relation.
175
 
 
176
 
This relation hook is with respect to the relation itself:
177
 
 
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
181
 
    established state.
182
 
 
183
 
    An example might be cleaning up the configuration changes which
184
 
    were performed when HAProxy was asked to load-balance for another
185
 
    service unit.
186
 
 
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.
197
 
 
198
 
 
199
 
Hook environment
200
 
----------------
201
 
 
202
 
Hooks can expect to be invoked with a standard environment and
203
 
context. The following environment variables are set:
204
 
 
205
 
  * **$JUJU_UNIT_NAME** - The name of the local unit executing,
206
 
    in the form ``<service name>/<unit sequence>``. E.g. ``myblog/3``.
207
 
 
208
 
Hooks called for relation changes will have the follow additional
209
 
environment variables set:
210
 
 
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.
214
 
 
215
 
  * **$JUJU_REMOTE_UNIT** - The unit name of the remote unit
216
 
    which has triggered the hook execution.
217
 
 
218
 
 
219
 
Hook commands for working with relations
220
 
----------------------------------------
221
 
 
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.
226
 
 
227
 
The following command line tools are made available:
228
 
 
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).
233
 
 
234
 
    Examples:
235
 
 
236
 
    Get the IP address from the remote unit which triggered the hook
237
 
    execution::
238
 
 
239
 
        relation-get ip
240
 
 
241
 
    Get all the settings from the remote unit which triggered the hook
242
 
    execution::
243
 
 
244
 
        relation-get
245
 
 
246
 
    Get the port information from the `wordpress/3` unit::
247
 
 
248
 
        relation-get port wordpress/3
249
 
 
250
 
    Get all the settings from the `wordpress/3` unit, in JSON format::
251
 
 
252
 
        relation-get - wordpress/3
253
 
 
254
 
  * **relation-set** - Changes a setting in an established relation.
255
 
 
256
 
    Examples:
257
 
 
258
 
    Set this unit's port number for other peers to use::
259
 
 
260
 
        relation-set port=8080
261
 
 
262
 
    Change two settings at once::
263
 
 
264
 
        relation-set dbname=wordpress dbpass="super secur3"
265
 
 
266
 
    Change several settings at once, with a JSON file::
267
 
 
268
 
        cat settings.json | relation-set
269
 
 
270
 
    Delete a setting::
271
 
 
272
 
        relation-set name=
273
 
 
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.
278
 
 
279
 
    Example::
280
 
 
281
 
        MEMBERS=$(relation-list)
282
 
 
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.
288
 
 
289
 
 
290
 
Hook commands for opening and closing ports
291
 
-------------------------------------------
292
 
 
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
296
 
arguments::
297
 
 
298
 
    open-port port[/protocol]
299
 
 
300
 
    close-port port[/protocol]
301
 
 
302
 
These commands are executed immediately; they do not depend on the
303
 
exit status of the hook.
304
 
 
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::
309
 
 
310
 
    open-port 80
311
 
 
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
315
 
important, however.
316
 
 
317
 
.. note::
318
 
 
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.
324
 
 
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::
328
 
 
329
 
    open-port 80
330
 
    open-port 443
331
 
 
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::
334
 
 
335
 
    open-port 53/udp
336
 
 
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
340
 
close the port::
341
 
 
342
 
    close-port 80
343
 
 
344
 
To be precise, the firewall is only open for the exposed ports during
345
 
the time both these conditions hold:
346
 
 
347
 
    * A service has been exposed.
348
 
    * A corresponding ``open-port`` command has been run (without a
349
 
      subsequent ``close-port``).
350
 
 
351
 
 
352
 
Sample metadata.yaml files
353
 
--------------------------
354
 
 
355
 
Below are presented some sample metadata files.
356
 
 
357
 
 
358
 
MySQL::
359
 
 
360
 
  name: mysql
361
 
  revision: 1
362
 
  summary: "A pretty popular database"
363
 
 
364
 
  provides:
365
 
    db: mysql
366
 
 
367
 
 
368
 
Wordpress::
369
 
 
370
 
  name: wordpress
371
 
  revision: 3
372
 
  summary: "A pretty popular blog engine"
373
 
  provides:
374
 
    url:
375
 
      interface: http
376
 
 
377
 
  requires:
378
 
    db:
379
 
     interface: mysql
380
 
 
381
 
 
382
 
Riak::
383
 
 
384
 
  name: riak
385
 
  revision: 7
386
 
  summary: "Scalable K/V Store in Erlang with Clocks :-)"
387
 
  provides:
388
 
    endpoint:
389
 
      interface: http
390
 
 
391
 
  peers:
392
 
    ring:
393
 
      interface: riak