Merge lp:~fwereade/juju-core/docs-splurge into lp:juju-core/docs
- docs-splurge
- Merge into docs
Status: | Merged |
---|---|
Merged at revision: | 140 |
Proposed branch: | lp:~fwereade/juju-core/docs-splurge |
Merge into: | lp:juju-core/docs |
Diff against target: |
2839 lines (+2710/-6) (has conflicts) 14 files modified
htmldocs/authors-charm-config.html (+191/-0) htmldocs/authors-charm-contents.html (+207/-0) htmldocs/authors-charm-interfaces.html (+313/-0) htmldocs/authors-charm-metadata.html (+310/-0) htmldocs/authors-charm-policy.html (+1/-1) htmldocs/authors-charm-upgrades.html (+212/-0) htmldocs/authors-charm-writing.html (+1/-1) htmldocs/authors-hook-debug.html (+169/-0) htmldocs/authors-hook-environment.html (+539/-0) htmldocs/authors-hook-errors.html (+194/-0) htmldocs/authors-hook-kinds.html (+375/-0) htmldocs/authors-relations-in-depth.html (+159/-0) htmldocs/navigation.html (+21/-2) htmldocs/navigation.json (+18/-2) Contents conflict in htmldocs/authors-charm-anatomy.html Contents conflict in htmldocs/authors-charms-in-action.html Contents conflict in htmldocs/authors-hooks.html Contents conflict in htmldocs/authors-service-config.html Text conflict in htmldocs/navigation.html Text conflict in htmldocs/navigation.json |
To merge this branch: | bzr merge lp:~fwereade/juju-core/docs-splurge |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Nick Veitch | Pending | ||
Review via email: mp+184833@code.launchpad.net |
Commit message
Description of the change
Serious rearrangement and expansion of docs relevant to charm authors.
John A Meinel (jameinel) wrote : | # |
William Reade (fwereade) wrote : | # |
Gaah, ok. I didn't expect that depth of rework to the pre/postamble; I'll see what I can do.
Nick Veitch (evilnick) wrote : | # |
Just an update on this, since it has been here a while:
There is a vast amount of reorganising the author docs, and it makes sense including these changes in it, so that is the chief reason this has taken so long.
There were a number of gaps in this which I have filled and a few bits I took the liberty of rewriting.
I also found more than a few things that were out of date or a bit wrong - e.g. revision files are no longer used, charms can have more than one category ,etc. So I have checked a lot of the stuff against the current release.
Anyhow, I will *very soon* have a new version of the docs. We are going to set up a staging/test project for stuff like this so we can more easily work on big changes. I will post details of that here and the usual places when it is operational!
Thanks VERY much for this contribution, it was very well written, structured and informative!
Preview Diff
1 | === renamed file 'htmldocs/authors-charm-anatomy.html' => 'htmldocs/authors-charm-anatomy.html.THIS' |
2 | === added file 'htmldocs/authors-charm-config.html' |
3 | --- htmldocs/authors-charm-config.html 1970-01-01 00:00:00 +0000 |
4 | +++ htmldocs/authors-charm-config.html 2013-09-11 07:54:25 +0000 |
5 | @@ -0,0 +1,191 @@ |
6 | +<!DOCTYPE html> |
7 | +<html> |
8 | + <head> |
9 | + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> |
10 | + <title>Juju Documentation - Charm Configuration</title> |
11 | + <link href='https://fonts.googleapis.com/css?family=Ubuntu:400,300,300italic,400italic,700,700italic|Ubuntu+Mono' rel='stylesheet' type='text/css' /> |
12 | + <link rel="stylesheet" type="text/css" media="screen" href="//juju.ubuntu.com/wp-content/themes/juju-website/css/reset.css" /> |
13 | + <link rel="stylesheet" type="text/css" media="screen" href="//juju.ubuntu.com/wp-content/themes/juju-website/css/960.css" /> |
14 | + <link rel="stylesheet" type="text/css" media="screen" href="//juju.ubuntu.com/wp-content/themes/juju-website/css/base.css" /> |
15 | + <link rel="stylesheet" type="text/css" media="screen" href="//juju.ubuntu.com/wp-content/themes/juju-website/css/home-new.css" /> |
16 | + <link rel='stylesheet' id='stacktack-css' href='//juju.ubuntu.com/wp-content/plugins/stacktack/css/stacktack.min.css?ver=3.4.2' type='text/css' media='all' /> |
17 | + <link href="css/main.css?1375975745" rel="stylesheet" type="text/css"/> |
18 | + |
19 | + <!--[if lt IE 9]> |
20 | + <script type="text/javascript" src="//html5shim.googlecode.com/svn/trunk/html5.js"></script> |
21 | + <![endif]--> |
22 | +</head> |
23 | + <body class="resources"> |
24 | + <header class="global clearfix" role="banner"> |
25 | + <div class="header-navigation"> |
26 | + <div> |
27 | + <nav role="navigation"> |
28 | + <ul> |
29 | + <li class="page_item page-item-6"><a href="https://juju.ubuntu.com/">Home</a></li> |
30 | + <li class="page_item page-item-7"><a href="https://juju.ubuntu.com/get-started/">Get started</a></li> |
31 | + <li class="page_item page-item-9 current_page_item"><a href="https://juju.ubuntu.com/resources/">Resources</a></li> |
32 | + <li class="page_item page-item-13"><a href="https://juju.ubuntu.com/community/">Community</a></li> |
33 | + <li class="page_item page-item-3688"><a href="https://juju.ubuntu.com/charm-store/">Charm Store</a></li> |
34 | + <li class="page_item page-item-3691"><a href="https://juju.ubuntu.com/events/">Events</a></li> |
35 | + <li class="page_item page-item-4474"><a href="https://juju.ubuntu.com/charm-championship/">Charm Championship</a></li> |
36 | + <li class="page_item page-item-4249"><a href="https://juju.ubuntu.com/survey/">Survey</a></li> |
37 | + <li> |
38 | + <form id="form-search" method="get" action="https://juju.ubuntu.com/"> |
39 | + <fieldset> |
40 | + <input id="input-search" type="text" name="s" value="Search" /> |
41 | + </fieldset> |
42 | + </form> |
43 | + </li> |
44 | + </ul> |
45 | + </nav> |
46 | + </div> |
47 | + </div> |
48 | + <div class="header-content"> |
49 | + <div class="clearfix"> |
50 | + <img src="https://juju.ubuntu.com/wp-content/themes/juju-website/img/arrow-nav.png" width="9" height="5" style="left:455px; display: block;" class="arrow-nav"> |
51 | + <div class="header-navigation-secondary"></div> |
52 | + <div class="header-image"></div> |
53 | + <h1>Resources</h1> |
54 | + <h2>A collection of some of the most important online references for Juju users and developers.</h2> |
55 | + </div> |
56 | + </div> |
57 | +</header> |
58 | + |
59 | + <section id="content" class="container-12"> |
60 | + <div class="grid-12 doc-container"> |
61 | + <div id="navlinks" class="grid-3 doc-navigation">LINKS</div> |
62 | + <div class="grid-9 doc-content"> |
63 | + <article> |
64 | + |
65 | +<section id="charm-configuration"> |
66 | +<h1>Charm configuration</h1> |
67 | + |
68 | +<p>The optional <code>config.yaml</code> file defines how a service running the |
69 | +charm can be configured by its user.</p> |
70 | + |
71 | +<p>If it exists, it must contain a dictionary of <code>options</code>, in which |
72 | +each possible setting is named by the key and defined by the value. An option |
73 | +definition may contain any number of the following fields:</p> |
74 | +<ul> |
75 | + <li><code>type</code> can be <code>string</code>, <code>int</code>, <code>float</code>, |
76 | + or <code>boolean</code>. If not present, it defaults to <code>string</code>.</li> |
77 | + <li><code>description</code> should contain an explanation of what the user might |
78 | + achieve by altering the setting.</li> |
79 | + <li><code>default</code> should, if present, contain a value of the appropriate |
80 | + type. If not present it is treated as null (which is always a valid value in this |
81 | + context); an option with no default will not normally be reported by the |
82 | + config-get <a href="./authors-hook-environment.html">hook tool</a> unless it |
83 | + has been explicitly set.</li> |
84 | +</ul> |
85 | +</section> |
86 | + |
87 | +<section id="picking-options"> |
88 | +<h2>What to expose to users</h2> |
89 | + |
90 | +<p>The charm configuration is deliberately somewhat restrictive, in the hope of |
91 | +encouraging charmers to expose only features that are clear and comprehensible. |
92 | +The user doesn't want to configure the software: they want to configure the |
93 | +<em>service</em>, which exists at a higher level of abstraction. A charm with |
94 | +a single opinionated <code<tuning</code> option is, from this perspective, |
95 | +infinitely superior to one that exposes 6 arcane options that correspond |
96 | +directly to flags or config settings for the <em>software</em>.</p> |
97 | + |
98 | +<p>In short, the config is the user interface for the charm: keep that context in |
99 | +the forefront of your mind as you design it. If you're considering using base64 |
100 | +encoding to slip structured data through the deliberately restrictive configuration |
101 | +language, you're probably Doing It Wrong.</p> |
102 | +</section> |
103 | + |
104 | +<section id="default-options"> |
105 | +<h2>Default configuration</h2> |
106 | + |
107 | +<p>Your charm should operate correctly with no explicit configuration settings. |
108 | +The first time someone uses your charm, they're likely to run <code>juju deploy</code> |
109 | +and see what happens; if it doesn't work out of the box, your charm may face |
110 | +significant adoption issues.</p> |
111 | +</section> |
112 | + |
113 | +<section id="warning"> |
114 | +<h2>Warning</h2> |
115 | + |
116 | +<p>There's a <a href="https://bugs.launchpad.net/juju-core/+bug/1194945">bug</a> |
117 | +in the service configuration CLI at the moment; if a string-typed option has an |
118 | +explicit default that is <em>not</em> the empty string, it will become |
119 | +impossible to set the value to the empty string at runtime. If your option |
120 | +needs to accept an empty string value, it should make the empty string the |
121 | +explicit default value.</p> |
122 | +</section> |
123 | + |
124 | +<section id="examples"> |
125 | +<h2>Sample config.yaml files</h2> |
126 | + |
127 | +XXXXXXXXXXXXXXXXXXX |
128 | + |
129 | +</section> |
130 | + |
131 | + </article> |
132 | + </div> |
133 | + </div> |
134 | + </section> |
135 | + <div class="shadow"></div> |
136 | + <footer class="global clearfix" role="contentinfo"> |
137 | + <div class="row"> |
138 | + <div class="inner-wrapper"> |
139 | + <nav role="navigation" class="clearfix"> |
140 | + <ul class="footer-a"> |
141 | + <li class="grid-3 first-col"> |
142 | + <h4><a href="/get-started">Get started</a></h4> |
143 | + <ul> |
144 | + <li class="page_item page-item-20"><a href="https://juju.ubuntu.com/get-started/local/">Local</a></li> |
145 | + <li class="page_item page-item-22"><a href="https://juju.ubuntu.com/get-started/amazon/">Amazon Web Services</a></li> |
146 | + <li class="page_item page-item-18"><a href="https://juju.ubuntu.com/get-started/hp-cloud/">HP Cloud</a></li> |
147 | + <li class="page_item page-item-16"><a href="https://juju.ubuntu.com/get-started/rackspace/">Rackspace</a></li> |
148 | + <li class="page_item page-item-3596"><a href="https://juju.ubuntu.com/get-started/openstack/">Openstack</a></li> |
149 | + <li class="page_item page-item-3600"><a href="https://juju.ubuntu.com/get-started/maas/">MAAS</a></li> |
150 | + </ul> |
151 | + </li> |
152 | + <li class="grid-3"> |
153 | + <h4><a href="/resources">Resources</a></h4> |
154 | + <ul> |
155 | + <li><a href="http://juju.ubuntu.com/docs">Documentation</a></li> |
156 | + <li><a href="/resources/videos/">Videos</a></li> |
157 | + <li><a href="http://uistage.jujucharms.com:8080/">Juju GUI demo site</a></li> |
158 | + </ul> |
159 | + </li> |
160 | + <li class="grid-3"> |
161 | + <h4><a href="/community">Community</a></h4> |
162 | + <ul> |
163 | + <li class="page_item page-item-28"><a href="https://juju.ubuntu.com/community/juju-blog/">Juju Blog</a></li> |
164 | + <li class="page_item page-item-4262"><a href="https://juju.ubuntu.com/community/weekly-charm-meeting/">Weekly Charm Meeting</a></li> |
165 | + <li class="page_item page-item-4036"><a href="https://juju.ubuntu.com/community/charmers/">Charmers</a></li> |
166 | + <li><a href="https://lists.ubuntu.com/mailman/listinfo/juju">Mailing List</a></li> |
167 | + <li><a href="http://webchat.freenode.net/?channels=juju">Chat</a></li> |
168 | + <li><a href="http://askubuntu.com/questions/tagged/juju?sort=faq&pagesize=50">FAQ</a></li> |
169 | + </ul> |
170 | + </li> |
171 | + <li class="grid-3 last-col"> |
172 | + <h4><a href="https://launchpad.net/juju">Code</a></h4> |
173 | + <ul> |
174 | + <li><a href="https://launchpad.net/juju-core">Juju Core</a></li> |
175 | + <li><a href="https://launchpad.net/charms">Charms</a></li> |
176 | + </ul> |
177 | + </li> |
178 | + </ul> |
179 | + </nav> |
180 | + </div> |
181 | + </div> |
182 | + <div class="row no-border"> |
183 | + <div class="legal inner-wrapper"> |
184 | + <p>© 2013 Canonical Ltd. Ubuntu and Canonical are registered trademarks of Canonical Ltd.</p> |
185 | + <p><a href="https://bugs.launchpad.net/juju-website/+filebug">Report a bug on this site</a></p> |
186 | + </div> |
187 | + </div> |
188 | +</footer> |
189 | + |
190 | + <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script> |
191 | + <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jqueryui/1.8.14/jquery-ui.min.js"></script> |
192 | + <script src="//d38yea5fb4e2oh.cloudfront.net/jquery.stacktack.min.js"></script> |
193 | + <script type="text/javascript" src="js/main.js"></script> |
194 | + <script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.js"></script> |
195 | + </body> |
196 | +</html> |
197 | |
198 | === added file 'htmldocs/authors-charm-contents.html' |
199 | --- htmldocs/authors-charm-contents.html 1970-01-01 00:00:00 +0000 |
200 | +++ htmldocs/authors-charm-contents.html 2013-09-11 07:54:25 +0000 |
201 | @@ -0,0 +1,207 @@ |
202 | +<!DOCTYPE html> |
203 | +<html> |
204 | + <head> |
205 | + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> |
206 | + <title>Juju Documentation - Charm contents</title> |
207 | + <link href='https://fonts.googleapis.com/css?family=Ubuntu:400,300,300italic,400italic,700,700italic|Ubuntu+Mono' rel='stylesheet' type='text/css' /> |
208 | + <link rel="stylesheet" type="text/css" media="screen" href="//juju.ubuntu.com/wp-content/themes/juju-website/css/reset.css" /> |
209 | + <link rel="stylesheet" type="text/css" media="screen" href="//juju.ubuntu.com/wp-content/themes/juju-website/css/960.css" /> |
210 | + <link rel="stylesheet" type="text/css" media="screen" href="//juju.ubuntu.com/wp-content/themes/juju-website/css/base.css" /> |
211 | + <link rel="stylesheet" type="text/css" media="screen" href="//juju.ubuntu.com/wp-content/themes/juju-website/css/home-new.css" /> |
212 | + <link rel='stylesheet' id='stacktack-css' href='//juju.ubuntu.com/wp-content/plugins/stacktack/css/stacktack.min.css?ver=3.4.2' type='text/css' media='all' /> |
213 | + <link href="css/main.css?1375975745" rel="stylesheet" type="text/css"/> |
214 | + |
215 | + <!--[if lt IE 9]> |
216 | + <script type="text/javascript" src="//html5shim.googlecode.com/svn/trunk/html5.js"></script> |
217 | + <![endif]--> |
218 | +</head> |
219 | + <body class="resources"> |
220 | + <header class="global clearfix" role="banner"> |
221 | + <div class="header-navigation"> |
222 | + <div> |
223 | + <nav role="navigation"> |
224 | + <ul> |
225 | + <li class="page_item page-item-6"><a href="https://juju.ubuntu.com/">Home</a></li> |
226 | + <li class="page_item page-item-7"><a href="https://juju.ubuntu.com/get-started/">Get started</a></li> |
227 | + <li class="page_item page-item-9 current_page_item"><a href="https://juju.ubuntu.com/resources/">Resources</a></li> |
228 | + <li class="page_item page-item-13"><a href="https://juju.ubuntu.com/community/">Community</a></li> |
229 | + <li class="page_item page-item-3688"><a href="https://juju.ubuntu.com/charm-store/">Charm Store</a></li> |
230 | + <li class="page_item page-item-3691"><a href="https://juju.ubuntu.com/events/">Events</a></li> |
231 | + <li class="page_item page-item-4474"><a href="https://juju.ubuntu.com/charm-championship/">Charm Championship</a></li> |
232 | + <li class="page_item page-item-4249"><a href="https://juju.ubuntu.com/survey/">Survey</a></li> |
233 | + <li> |
234 | + <form id="form-search" method="get" action="https://juju.ubuntu.com/"> |
235 | + <fieldset> |
236 | + <input id="input-search" type="text" name="s" value="Search" /> |
237 | + </fieldset> |
238 | + </form> |
239 | + </li> |
240 | + </ul> |
241 | + </nav> |
242 | + </div> |
243 | + </div> |
244 | + <div class="header-content"> |
245 | + <div class="clearfix"> |
246 | + <img src="https://juju.ubuntu.com/wp-content/themes/juju-website/img/arrow-nav.png" width="9" height="5" style="left:455px; display: block;" class="arrow-nav"> |
247 | + <div class="header-navigation-secondary"></div> |
248 | + <div class="header-image"></div> |
249 | + <h1>Resources</h1> |
250 | + <h2>A collection of some of the most important online references for Juju users and developers.</h2> |
251 | + </div> |
252 | + </div> |
253 | +</header> |
254 | + |
255 | + <section id="content" class="container-12"> |
256 | + <div class="grid-12 doc-container"> |
257 | + <div id="navlinks" class="grid-3 doc-navigation">LINKS</div> |
258 | + <div class="grid-9 doc-content"> |
259 | + <article> |
260 | + |
261 | +<section id="charm-contents"> |
262 | +<h1>Charm contents</h1> |
263 | +<p>Conceptually, charms are composed of metadata, configuration, and hooks. Other |
264 | +files may be present in a charm directory for a variety of reasons.</p> |
265 | +</section> |
266 | + |
267 | +<section id="required-files"> |
268 | +<h2>Required files</h2> |
269 | +<p>A charm requires only a single file in order to be considered valid by juju: |
270 | +<ul> |
271 | +<li><code>metadata.yaml</code> <a href="./authors-charm-metadata.html">describes the |
272 | + charm</a> and the relations it can participate in.</li> |
273 | +</ul> |
274 | +</section> |
275 | + |
276 | +<section id="special-files"> |
277 | +<h2>Special files</h2> |
278 | +<p>The following files will be treated specially, if present:</p> |
279 | +<ul> |
280 | + <li><code>hooks</code> must be a directory holding <a href="./authors-hook-kinds.html"> |
281 | + executables with specific names</a>, that will be invoked by juju at specific times. |
282 | + A charm needs to implement at least one hook in order to do anything at all.</li> |
283 | + <li><code>config.yaml</code> defines <a href="./authors-charm-config.html"> |
284 | + service configuration options</a>.</li> |
285 | + <li><code>icon.svg</code> is used to <a href="./authors-charm-icon.html">identify |
286 | + your charm</a> in the GUI and in the charm store.</li> |
287 | + <li><code>README</code> is made available in the charm store. It should be |
288 | + comprehensible to a reasonably ignorant user.</li> |
289 | + <li><code>revision</code> should not be used other than by juju; ignore it |
290 | + in your VCS.</li> |
291 | + <li> files matching <code>.juju*</code> should not be used.</li> |
292 | +</ul> |
293 | +</section> |
294 | + |
295 | +<section id="other-files"> |
296 | +<h2>Other files</h2> |
297 | + |
298 | +<p>Any other files you know you'll need can be placed in the charm for convenience. |
299 | +We recommend reserving the hooks directory for hooks alone, and putting library |
300 | +code elsewhere in the charm, but we do not enforce the contents of the hooks |
301 | +directory today.</p> |
302 | + |
303 | +<p>When hooks are actually running, they can read and write to the charm directory |
304 | +freely, but should carefully observe the caveats in the next section.</p> |
305 | +</section> |
306 | + |
307 | +<section id="runtime-files"> |
308 | +<h2>Charm files at runtime</h2> |
309 | + |
310 | +<p>However, the files you use in your charm should <em>not</em> be used directly by the |
311 | +software installed by your charm. If the files are really needed by the software |
312 | +at runtime, copy them on the system alongside the software and reference those |
313 | +instead.</p> |
314 | + |
315 | +<p>This is because the software does <em>not</em> have control over the charm directory; |
316 | +<em>juju</em> has control over the charm directory, which it temporarily cedes to the |
317 | +charm only when running a hook. Juju will occasionally do things to the contents |
318 | +of that directory that assume it is neither read nor written outside a hook, and |
319 | +the results of such interactions can only be undefined.</p> |
320 | + |
321 | +<p>The only files you should be writing into the charm directory should be written |
322 | +by hooks, and accessed only by hooks. If everything in your charm directory |
323 | +went away, that should be considered a <em>management</em> failure only; the software |
324 | +installed should continue to run, using its last known good configuration, and |
325 | +should do this by virtue of never having had the opportunity to observe the |
326 | +change.</p> |
327 | + |
328 | +<p>Finally, any file written at runtime constrains all future implementations of |
329 | +the charm. When <a href="./authors-charm-upgrades.html">upgrading a charm</a>, any |
330 | +change that would cause runtime state to be overwritten will cause juju to abort |
331 | +the operation and hand over to the user for resolution. This is inconvenient for |
332 | +the users and makes everyone look bad.</p> |
333 | + |
334 | +<p>You need to be especially aware of these guidelines when writing python code. |
335 | +Python packages run without bytecode suppression will write <code>.pyc</code> files into |
336 | +the package, and subsequent attempts to move or remove the package will fail: |
337 | +the .pyc files are treated as important hook-relevant runtime state, to be |
338 | +recorded and tracked, and the loss of their directory will put the unit into |
339 | +an upgrade error state as referenced above.</p> |
340 | +</section> |
341 | + |
342 | + </article> |
343 | + </div> |
344 | + </div> |
345 | + </section> |
346 | + <div class="shadow"></div> |
347 | + <footer class="global clearfix" role="contentinfo"> |
348 | + <div class="row"> |
349 | + <div class="inner-wrapper"> |
350 | + <nav role="navigation" class="clearfix"> |
351 | + <ul class="footer-a"> |
352 | + <li class="grid-3 first-col"> |
353 | + <h4><a href="/get-started">Get started</a></h4> |
354 | + <ul> |
355 | + <li class="page_item page-item-20"><a href="https://juju.ubuntu.com/get-started/local/">Local</a></li> |
356 | + <li class="page_item page-item-22"><a href="https://juju.ubuntu.com/get-started/amazon/">Amazon Web Services</a></li> |
357 | + <li class="page_item page-item-18"><a href="https://juju.ubuntu.com/get-started/hp-cloud/">HP Cloud</a></li> |
358 | + <li class="page_item page-item-16"><a href="https://juju.ubuntu.com/get-started/rackspace/">Rackspace</a></li> |
359 | + <li class="page_item page-item-3596"><a href="https://juju.ubuntu.com/get-started/openstack/">Openstack</a></li> |
360 | + <li class="page_item page-item-3600"><a href="https://juju.ubuntu.com/get-started/maas/">MAAS</a></li> |
361 | + </ul> |
362 | + </li> |
363 | + <li class="grid-3"> |
364 | + <h4><a href="/resources">Resources</a></h4> |
365 | + <ul> |
366 | + <li><a href="http://juju.ubuntu.com/docs">Documentation</a></li> |
367 | + <li><a href="/resources/videos/">Videos</a></li> |
368 | + <li><a href="http://uistage.jujucharms.com:8080/">Juju GUI demo site</a></li> |
369 | + </ul> |
370 | + </li> |
371 | + <li class="grid-3"> |
372 | + <h4><a href="/community">Community</a></h4> |
373 | + <ul> |
374 | + <li class="page_item page-item-28"><a href="https://juju.ubuntu.com/community/juju-blog/">Juju Blog</a></li> |
375 | + <li class="page_item page-item-4262"><a href="https://juju.ubuntu.com/community/weekly-charm-meeting/">Weekly Charm Meeting</a></li> |
376 | + <li class="page_item page-item-4036"><a href="https://juju.ubuntu.com/community/charmers/">Charmers</a></li> |
377 | + <li><a href="https://lists.ubuntu.com/mailman/listinfo/juju">Mailing List</a></li> |
378 | + <li><a href="http://webchat.freenode.net/?channels=juju">Chat</a></li> |
379 | + <li><a href="http://askubuntu.com/questions/tagged/juju?sort=faq&pagesize=50">FAQ</a></li> |
380 | + </ul> |
381 | + </li> |
382 | + <li class="grid-3 last-col"> |
383 | + <h4><a href="https://launchpad.net/juju">Code</a></h4> |
384 | + <ul> |
385 | + <li><a href="https://launchpad.net/juju-core">Juju Core</a></li> |
386 | + <li><a href="https://launchpad.net/charms">Charms</a></li> |
387 | + </ul> |
388 | + </li> |
389 | + </ul> |
390 | + </nav> |
391 | + </div> |
392 | + </div> |
393 | + <div class="row no-border"> |
394 | + <div class="legal inner-wrapper"> |
395 | + <p>© 2013 Canonical Ltd. Ubuntu and Canonical are registered trademarks of Canonical Ltd.</p> |
396 | + <p><a href="https://bugs.launchpad.net/juju-website/+filebug">Report a bug on this site</a></p> |
397 | + </div> |
398 | + </div> |
399 | +</footer> |
400 | + |
401 | + <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script> |
402 | + <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jqueryui/1.8.14/jquery-ui.min.js"></script> |
403 | + <script src="//d38yea5fb4e2oh.cloudfront.net/jquery.stacktack.min.js"></script> |
404 | + <script type="text/javascript" src="js/main.js"></script> |
405 | + <script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.js"></script> |
406 | + </body> |
407 | +</html> |
408 | + |
409 | |
410 | === added file 'htmldocs/authors-charm-interfaces.html' |
411 | --- htmldocs/authors-charm-interfaces.html 1970-01-01 00:00:00 +0000 |
412 | +++ htmldocs/authors-charm-interfaces.html 2013-09-11 07:54:25 +0000 |
413 | @@ -0,0 +1,313 @@ |
414 | +<!DOCTYPE html> |
415 | +<html> |
416 | + <head> |
417 | + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> |
418 | + <title>Juju Documentation - Charm relation interfaces</title> |
419 | + <link href='https://fonts.googleapis.com/css?family=Ubuntu:400,300,300italic,400italic,700,700italic|Ubuntu+Mono' rel='stylesheet' type='text/css' /> |
420 | + <link rel="stylesheet" type="text/css" media="screen" href="//juju.ubuntu.com/wp-content/themes/juju-website/css/reset.css" /> |
421 | + <link rel="stylesheet" type="text/css" media="screen" href="//juju.ubuntu.com/wp-content/themes/juju-website/css/960.css" /> |
422 | + <link rel="stylesheet" type="text/css" media="screen" href="//juju.ubuntu.com/wp-content/themes/juju-website/css/base.css" /> |
423 | + <link rel="stylesheet" type="text/css" media="screen" href="//juju.ubuntu.com/wp-content/themes/juju-website/css/home-new.css" /> |
424 | + <link rel='stylesheet' id='stacktack-css' href='//juju.ubuntu.com/wp-content/plugins/stacktack/css/stacktack.min.css?ver=3.4.2' type='text/css' media='all' /> |
425 | + <link href="css/main.css?1375975745" rel="stylesheet" type="text/css"/> |
426 | + |
427 | + <!--[if lt IE 9]> |
428 | + <script type="text/javascript" src="//html5shim.googlecode.com/svn/trunk/html5.js"></script> |
429 | + <![endif]--> |
430 | +</head> |
431 | + <body class="resources"> |
432 | + <header class="global clearfix" role="banner"> |
433 | + <div class="header-navigation"> |
434 | + <div> |
435 | + <nav role="navigation"> |
436 | + <ul> |
437 | + <li class="page_item page-item-6"><a href="https://juju.ubuntu.com/">Home</a></li> |
438 | + <li class="page_item page-item-7"><a href="https://juju.ubuntu.com/get-started/">Get started</a></li> |
439 | + <li class="page_item page-item-9 current_page_item"><a href="https://juju.ubuntu.com/resources/">Resources</a></li> |
440 | + <li class="page_item page-item-13"><a href="https://juju.ubuntu.com/community/">Community</a></li> |
441 | + <li class="page_item page-item-3688"><a href="https://juju.ubuntu.com/charm-store/">Charm Store</a></li> |
442 | + <li class="page_item page-item-3691"><a href="https://juju.ubuntu.com/events/">Events</a></li> |
443 | + <li class="page_item page-item-4474"><a href="https://juju.ubuntu.com/charm-championship/">Charm Championship</a></li> |
444 | + <li class="page_item page-item-4249"><a href="https://juju.ubuntu.com/survey/">Survey</a></li> |
445 | + <li> |
446 | + <form id="form-search" method="get" action="https://juju.ubuntu.com/"> |
447 | + <fieldset> |
448 | + <input id="input-search" type="text" name="s" value="Search" /> |
449 | + </fieldset> |
450 | + </form> |
451 | + </li> |
452 | + </ul> |
453 | + </nav> |
454 | + </div> |
455 | + </div> |
456 | + <div class="header-content"> |
457 | + <div class="clearfix"> |
458 | + <img src="https://juju.ubuntu.com/wp-content/themes/juju-website/img/arrow-nav.png" width="9" height="5" style="left:455px; display: block;" class="arrow-nav"> |
459 | + <div class="header-navigation-secondary"></div> |
460 | + <div class="header-image"></div> |
461 | + <h1>Resources</h1> |
462 | + <h2>A collection of some of the most important online references for Juju users and developers.</h2> |
463 | + </div> |
464 | + </div> |
465 | +</header> |
466 | + |
467 | + <section id="content" class="container-12"> |
468 | + <div class="grid-12 doc-container"> |
469 | + <div id="navlinks" class="grid-3 doc-navigation">LINKS</div> |
470 | + <div class="grid-9 doc-content"> |
471 | + <article> |
472 | + |
473 | +<section id="relation-interfaces"> |
474 | +<h1>Charm relation interfaces</h1> |
475 | + |
476 | +<p>As described <a href="./authors-charm-metadata.html">elsewhere</a>, picking an |
477 | +interface is a strong statement; whether you're providing or requiring a given |
478 | +interface, you need to be compatible with all providers and requirers of that |
479 | +interface.</p> |
480 | + |
481 | +<p>In short, this means that you need to set the same settings as do all the |
482 | +other charms with the same role for the interface; and you should only expect |
483 | +to be able to read those settings set by the other charms with the counterpart |
484 | +role.</p> |
485 | +</section> |
486 | + |
487 | +<section id="determining-interfaces"> |
488 | +<h2>Determining charm relation interfaces</h2> |
489 | + |
490 | +<p>This is in some respects an uncomfortable situation to be in. If two charms |
491 | +declare compatibility, but fail when run together due to disagreement about |
492 | +the actual definition of that interface; it's not immediately clear which is |
493 | +at fault, because the "standard" is defined only by consensus among the |
494 | +existing charms that provide or require that interface.</p> |
495 | + |
496 | +<p>On the upside, this means that reading any charm that already implements the |
497 | +interface is <em>theoretically</em> good enough to figure it out; in practice, it's |
498 | +sometimes hard to understand the code in isolation. The incontrovertible way |
499 | +to determine the protocol defined by an interface is to deploy a pair of charms |
500 | +that already use that interface, and <a href="./authors-hook-debug.html">intercept</a> |
501 | +the communications between them.</p> |
502 | + |
503 | +<pre class="runnable"><code> |
504 | +$ juju deploy mongodb |
505 | +$ juju deploy node-app |
506 | +</code></pre> |
507 | + |
508 | +<p>In a separate window, once node-app/0 reports <code>started</code> status:</p> |
509 | + |
510 | +<pre class="runnable"><code> |
511 | +$ juju debug-hooks node-app/0 * |
512 | +</code></pre> |
513 | + |
514 | +<p>This opens a tmux session; when the unit wants to run a hook, it'll create a |
515 | +new window in which you can interactively inspect the environment. In a relation |
516 | +hook, you'll want to run the following commands:</p> |
517 | + |
518 | +<pre class="runnable"><code> |
519 | +# discover what's been set by the unit on the other end of the relation: |
520 | +$ relation-get $JUJU_REMOTE_UNIT |
521 | +address: example.com:37070 |
522 | +username: bob |
523 | +password: seekrit |
524 | + |
525 | +# get the local unit's relation settings, for comparison afterwards: |
526 | +$ relation-get $JUJU_UNIT_NAME |
527 | +# (no results) |
528 | + |
529 | +# run the actual hook: |
530 | +$ ./hooks/$JUJU_HOOK_NAME |
531 | + |
532 | +# get the local settings again, to see if any changes were made by the hook: |
533 | +$ relation-get $JUJU_UNIT_NAME |
534 | +# (no results) |
535 | +</code></pre> |
536 | + |
537 | +<p>...and then close that tmux window and wait to see if another one opens for the |
538 | +next hook. Assuming you started debugging before creating the relation, you'll |
539 | +see exactly one -joined hook, and at least one -changed hook, and you're only |
540 | +done when new -changed hooks stop popping up.</p> |
541 | + |
542 | +<p>The relation-get <a href="./authors-hook-environment.html">tool</a> accepts a |
543 | +<code>--format</code> parameter that accepts <code>json</code> and <code>yaml</code> |
544 | +values, in case you want to consume them programmatically.</p> |
545 | + |
546 | +<p>In practice, what you'll most likely find is that one side sets a couple of keys, |
547 | +the other side gets them, and that's that... in no more than two changed hooks. |
548 | +Be aware, though, that it is possible in principle for an interface to imply |
549 | +a more demanding interface, involving multiple rounds of setting and getting.</p> |
550 | +</section> |
551 | + |
552 | +<section id="documenting-interfaces"> |
553 | +<h2>Documenting charm relation interfaces</h2> |
554 | + |
555 | +<p>In light of the above, there is a clear need for some means of documenting the |
556 | +above. The optional <code>gets</code> and <code>sets</code> fields in a charm's |
557 | +relation <a href="./authors-charm-metadata.html">metadata</a> should be used for |
558 | +this purpose.</p> |
559 | + |
560 | +<p>Please be especially careful to note that this format is <em>not</em> checked |
561 | +by juju today. But it does encode the information that's most helpful to your fellow |
562 | +charmers, and by doing so in a consistent and machine-readable format we maximise |
563 | +our chances of one day making use of this information automatically.</p> |
564 | + |
565 | +<p>The simple form, which will be the most common form, looks like this:</p> |
566 | + |
567 | +<pre class="runnable"><code> |
568 | +name: python-django |
569 | +... |
570 | +provides: |
571 | + website: |
572 | + interface: http |
573 | + sets: [host, post] |
574 | +</code></pre> |
575 | + |
576 | +<p>...and this:</p> |
577 | + |
578 | +<pre class="runnable"><code> |
579 | +name: haproxy |
580 | +... |
581 | +requires: |
582 | + reverseproxy: |
583 | + interface: http |
584 | + gets: [host, port] |
585 | +</code></pre> |
586 | + |
587 | +<p>...indicating that a relation can surely be made between python-django and haproxy, |
588 | +because the <code>website</code> relation unconditionally sets the keys that the |
589 | +<code>reverseproxy</code> relation requires in order to function.</p> |
590 | + |
591 | +<p>The more complex form, which is only required for complex protocols, is defined |
592 | +as follows:</p> |
593 | +<ul> |
594 | + <li><code>gets</code> holds a list of settings keys that must all be set by |
595 | + each unit on the remote end of a relation in order for the local unit to |
596 | + function.</li> |
597 | + <li><code>sets</code> holds a list of settings that will be set by each unit |
598 | + of the local charm. These settings can either be a plain string, indicating that |
599 | + no remote settings need exist for this key to be written; or a single-element |
600 | + map, with the setting to be written mapped to the remote settings that must |
601 | + exist for this to be done.</li> |
602 | +</ul> |
603 | +<p>For example, consider charms <code>a</code> and <code>b</code>, which do the |
604 | +following handshake dance before they can complete their configuration:</p> |
605 | +<ul> |
606 | + <li><code>b/0</code> starts running -joined, which takes a while.</li> |
607 | + <li><code>a/0</code> runs -joined and -changed before <code>b/0</code> has |
608 | + finished -joined. In the -changed hook, it fails to find the remote settings |
609 | + it expected, and exits without error.</li> |
610 | + <li><code>b/0</code> finishes -joined, setting <code>X</code> and <code>Y</code>, |
611 | + thus triggering -changed on <code>a/0</code>.</li> |
612 | + <li><code>a/0</code> sets <code>P</code> and <code>Q</code> in response, causing |
613 | + a -changed on <code>b/0</code>.</li> |
614 | + <li><code>b/0</code> completes local configuration using <code>P</code> and |
615 | + <code>Q</code>, and sets <code>Z</code>, triggering a final -changed on |
616 | + <code>a/0</code>.</li> |
617 | + <li><code>a/0</code> completes local configuration using <code>X</code>, |
618 | + <code>Y</code>, and <code>Z</code>, and sets nothing.</li> |
619 | +</ul> |
620 | +<p>For example, in the hypothetical complex protocol described in the previous |
621 | +section, the metadata for charm <code>a</code> above would contain:</p> |
622 | + |
623 | +<pre class="runnable"><code> |
624 | +requires: |
625 | + ab: |
626 | + interface: ab |
627 | + sets: |
628 | + - P: [X, Y] |
629 | + - Q: [X, Y] |
630 | + gets: [X, Y, Z] |
631 | +</code></pre> |
632 | + |
633 | +<p>...indicating that <code>P</code> and <code>Q</code> will only be written when |
634 | +<code>X</code> and <code>Y</code> have; and that configuration will not complete |
635 | +without <code>X</code>, <code>Y</code> and <code>Z</code>. Meanwhile charm |
636 | +<code>b</code> would contain:</p> |
637 | + |
638 | +<pre class="runnable"><code> |
639 | +provides: |
640 | + ab: |
641 | + interface: ab |
642 | + sets: |
643 | + - X |
644 | + - Y |
645 | + - Z: [P, Q] |
646 | + gets: [P, Q] |
647 | +</code></pre> |
648 | + |
649 | +<p>...indicating that it will always write <code>X</code> and <code>Y</code>, and |
650 | +that <code>Z</code> will be written when <code>P</code> and <code>Q</code> have; and |
651 | +that configuration will not be complete without <code>P</code> and <code>Q</code>.</p> |
652 | + |
653 | +<p>Peer relations are a different matter, in that peer relations are the mechanism |
654 | +by which service units share information internally. It's not unusual for peer |
655 | +service units to maintain convenient caches of distributed information in their |
656 | +own peer settings, and this inevitably involves generating settings keys at |
657 | +runtime.</p> |
658 | +</section> |
659 | + |
660 | + </article> |
661 | + </div> |
662 | + </div> |
663 | + </section> |
664 | + <div class="shadow"></div> |
665 | + <footer class="global clearfix" role="contentinfo"> |
666 | + <div class="row"> |
667 | + <div class="inner-wrapper"> |
668 | + <nav role="navigation" class="clearfix"> |
669 | + <ul class="footer-a"> |
670 | + <li class="grid-3 first-col"> |
671 | + <h4><a href="/get-started">Get started</a></h4> |
672 | + <ul> |
673 | + <li class="page_item page-item-20"><a href="https://juju.ubuntu.com/get-started/local/">Local</a></li> |
674 | + <li class="page_item page-item-22"><a href="https://juju.ubuntu.com/get-started/amazon/">Amazon Web Services</a></li> |
675 | + <li class="page_item page-item-18"><a href="https://juju.ubuntu.com/get-started/hp-cloud/">HP Cloud</a></li> |
676 | + <li class="page_item page-item-16"><a href="https://juju.ubuntu.com/get-started/rackspace/">Rackspace</a></li> |
677 | + <li class="page_item page-item-3596"><a href="https://juju.ubuntu.com/get-started/openstack/">Openstack</a></li> |
678 | + <li class="page_item page-item-3600"><a href="https://juju.ubuntu.com/get-started/maas/">MAAS</a></li> |
679 | + </ul> |
680 | + </li> |
681 | + <li class="grid-3"> |
682 | + <h4><a href="/resources">Resources</a></h4> |
683 | + <ul> |
684 | + <li><a href="http://juju.ubuntu.com/docs">Documentation</a></li> |
685 | + <li><a href="/resources/videos/">Videos</a></li> |
686 | + <li><a href="http://uistage.jujucharms.com:8080/">Juju GUI demo site</a></li> |
687 | + </ul> |
688 | + </li> |
689 | + <li class="grid-3"> |
690 | + <h4><a href="/community">Community</a></h4> |
691 | + <ul> |
692 | + <li class="page_item page-item-28"><a href="https://juju.ubuntu.com/community/juju-blog/">Juju Blog</a></li> |
693 | + <li class="page_item page-item-4262"><a href="https://juju.ubuntu.com/community/weekly-charm-meeting/">Weekly Charm Meeting</a></li> |
694 | + <li class="page_item page-item-4036"><a href="https://juju.ubuntu.com/community/charmers/">Charmers</a></li> |
695 | + <li><a href="https://lists.ubuntu.com/mailman/listinfo/juju">Mailing List</a></li> |
696 | + <li><a href="http://webchat.freenode.net/?channels=juju">Chat</a></li> |
697 | + <li><a href="http://askubuntu.com/questions/tagged/juju?sort=faq&pagesize=50">FAQ</a></li> |
698 | + </ul> |
699 | + </li> |
700 | + <li class="grid-3 last-col"> |
701 | + <h4><a href="https://launchpad.net/juju">Code</a></h4> |
702 | + <ul> |
703 | + <li><a href="https://launchpad.net/juju-core">Juju Core</a></li> |
704 | + <li><a href="https://launchpad.net/charms">Charms</a></li> |
705 | + </ul> |
706 | + </li> |
707 | + </ul> |
708 | + </nav> |
709 | + </div> |
710 | + </div> |
711 | + <div class="row no-border"> |
712 | + <div class="legal inner-wrapper"> |
713 | + <p>© 2013 Canonical Ltd. Ubuntu and Canonical are registered trademarks of Canonical Ltd.</p> |
714 | + <p><a href="https://bugs.launchpad.net/juju-website/+filebug">Report a bug on this site</a></p> |
715 | + </div> |
716 | + </div> |
717 | +</footer> |
718 | + |
719 | + <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script> |
720 | + <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jqueryui/1.8.14/jquery-ui.min.js"></script> |
721 | + <script src="//d38yea5fb4e2oh.cloudfront.net/jquery.stacktack.min.js"></script> |
722 | + <script type="text/javascript" src="js/main.js"></script> |
723 | + <script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.js"></script> |
724 | + </body> |
725 | +</html> |
726 | + |
727 | |
728 | === added file 'htmldocs/authors-charm-metadata.html' |
729 | --- htmldocs/authors-charm-metadata.html 1970-01-01 00:00:00 +0000 |
730 | +++ htmldocs/authors-charm-metadata.html 2013-09-11 07:54:25 +0000 |
731 | @@ -0,0 +1,310 @@ |
732 | +<!DOCTYPE html> |
733 | +<html> |
734 | + <head> |
735 | + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> |
736 | + <title>Juju Documentation - Charm Metadata</title> |
737 | + <link href='https://fonts.googleapis.com/css?family=Ubuntu:400,300,300italic,400italic,700,700italic|Ubuntu+Mono' rel='stylesheet' type='text/css' /> |
738 | + <link rel="stylesheet" type="text/css" media="screen" href="//juju.ubuntu.com/wp-content/themes/juju-website/css/reset.css" /> |
739 | + <link rel="stylesheet" type="text/css" media="screen" href="//juju.ubuntu.com/wp-content/themes/juju-website/css/960.css" /> |
740 | + <link rel="stylesheet" type="text/css" media="screen" href="//juju.ubuntu.com/wp-content/themes/juju-website/css/base.css" /> |
741 | + <link rel="stylesheet" type="text/css" media="screen" href="//juju.ubuntu.com/wp-content/themes/juju-website/css/home-new.css" /> |
742 | + <link rel='stylesheet' id='stacktack-css' href='//juju.ubuntu.com/wp-content/plugins/stacktack/css/stacktack.min.css?ver=3.4.2' type='text/css' media='all' /> |
743 | + <link href="css/main.css?1375975745" rel="stylesheet" type="text/css"/> |
744 | + |
745 | + <!--[if lt IE 9]> |
746 | + <script type="text/javascript" src="//html5shim.googlecode.com/svn/trunk/html5.js"></script> |
747 | + <![endif]--> |
748 | +</head> |
749 | + <body class="resources"> |
750 | + <header class="global clearfix" role="banner"> |
751 | + <div class="header-navigation"> |
752 | + <div> |
753 | + <nav role="navigation"> |
754 | + <ul> |
755 | + <li class="page_item page-item-6"><a href="https://juju.ubuntu.com/">Home</a></li> |
756 | + <li class="page_item page-item-7"><a href="https://juju.ubuntu.com/get-started/">Get started</a></li> |
757 | + <li class="page_item page-item-9 current_page_item"><a href="https://juju.ubuntu.com/resources/">Resources</a></li> |
758 | + <li class="page_item page-item-13"><a href="https://juju.ubuntu.com/community/">Community</a></li> |
759 | + <li class="page_item page-item-3688"><a href="https://juju.ubuntu.com/charm-store/">Charm Store</a></li> |
760 | + <li class="page_item page-item-3691"><a href="https://juju.ubuntu.com/events/">Events</a></li> |
761 | + <li class="page_item page-item-4474"><a href="https://juju.ubuntu.com/charm-championship/">Charm Championship</a></li> |
762 | + <li class="page_item page-item-4249"><a href="https://juju.ubuntu.com/survey/">Survey</a></li> |
763 | + <li> |
764 | + <form id="form-search" method="get" action="https://juju.ubuntu.com/"> |
765 | + <fieldset> |
766 | + <input id="input-search" type="text" name="s" value="Search" /> |
767 | + </fieldset> |
768 | + </form> |
769 | + </li> |
770 | + </ul> |
771 | + </nav> |
772 | + </div> |
773 | + </div> |
774 | + <div class="header-content"> |
775 | + <div class="clearfix"> |
776 | + <img src="https://juju.ubuntu.com/wp-content/themes/juju-website/img/arrow-nav.png" width="9" height="5" style="left:455px; display: block;" class="arrow-nav"> |
777 | + <div class="header-navigation-secondary"></div> |
778 | + <div class="header-image"></div> |
779 | + <h1>Resources</h1> |
780 | + <h2>A collection of some of the most important online references for Juju users and developers.</h2> |
781 | + </div> |
782 | + </div> |
783 | +</header> |
784 | + |
785 | + <section id="content" class="container-12"> |
786 | + <div class="grid-12 doc-container"> |
787 | + <div id="navlinks" class="grid-3 doc-navigation">LINKS</div> |
788 | + <div class="grid-9 doc-content"> |
789 | + <article> |
790 | + |
791 | +<section id="charm-metadata"> |
792 | +<h1>Charm metadata</h1> |
793 | + |
794 | +<p>The only file that must be present in a charm is <code>metadata.yaml</code>, in |
795 | +the root directory. A metadata file must be a valid yaml dictionary, containing at |
796 | +least the following fields:</p> |
797 | +<ul> |
798 | + <li><code>name</code> is the charm name, which is used to form the charm URL. |
799 | + It must contain only <code>a-z</code>, <code>0-9</code>, and <code>-</code>; |
800 | + must start with <code>a-z</code>; must not end with a <code>-</code>; and may |
801 | + only end with digits if the digits are <em>not</em> directly preceded by a |
802 | + space. Stick with names like <code>foo</code> and <code>foo-bar-baz</code> |
803 | + and you needn't pay further attention to the restrictions.</li> |
804 | + <li><code>summary</code> is a one-line description of the charm.</li> |
805 | + <li><code>description</code> is a long-form description of the charm and its |
806 | + features. It will also appear in the juju GUI.</li> |
807 | +</ul> |
808 | + |
809 | +<p>Here's a valid metadata file:</p> |
810 | +<pre class="runnable"><code> |
811 | +name: minecraft |
812 | +summary: Minecraft Server |
813 | +description: | |
814 | + Will deploy OpenJDK 6 JRE and the latest Minecraft server |
815 | +</code></pre> |
816 | + |
817 | +<p>...and so, by extension, a valid charm, if suitably named and placed on its |
818 | +own in a directory.</p> |
819 | + |
820 | +<p>With only those fields, a metadata file is valid, but not very useful. Charms |
821 | +for use in the charm store should always set the following fields as well, |
822 | +for categorization and display in the GUI:</p> |
823 | +<ul> |
824 | + <li><code>maintainer</code> is the name and email address for the main point |
825 | + of contact for the development and maintenance of the charm. Or, at least, it |
826 | + should be: in frequent practice, it's just a name. Please update your charms |
827 | + as you get the opportunity.</li> |
828 | + <li><code>categories</code> is a list containing just one of the following: |
829 | + <ul> |
830 | + <li>applications</li> |
831 | + <li>app-servers</li> |
832 | + <li>cache-proxy</li> |
833 | + <li>databases</li> |
834 | + <li>file-servers</li> |
835 | + <li>miscellaneous</li> |
836 | + </ul> |
837 | + It's used to help keep the charm store organised.</li> |
838 | +</ul> |
839 | + |
840 | +<p>Finally, a metadata file defines the charm's relations, and whether it's |
841 | +designed for deployment as a <a href="./authors-subordinate-services.html">subordinate</a>.</p> |
842 | +<ul> |
843 | + <li><code>subordinate</code> should be set to true if the charm is a |
844 | + subordinate. If omitted, the charm will be presumed not to be subordinate.</li> |
845 | + <li><code>provides</code>, <code>requires</code>, and <code>peers</code> define |
846 | + the various relations the charm will participate in.</li> |
847 | + <li>if the charm is subordinate, it must contain at least one <code>requires</code> |
848 | + relation with container scope.</li> |
849 | +</ul> |
850 | + |
851 | +<p>Other field names should be considered to be reserved; please don't use any |
852 | +not listed above, lest they be used incompatibly by a future version of juju.</p> |
853 | +</section> |
854 | + |
855 | +<section id="simple-relations"> |
856 | +<h2>Simple relations</h2> |
857 | + |
858 | +<p>The <code>provides</code> and <code>requires</code> keys are used to define |
859 | +pairings of charms that are likely to be fruitful. Consider a simple mongodb |
860 | +charm's metadata:</p> |
861 | + |
862 | +<pre class="runnable"><code> |
863 | +name: my-mongodb |
864 | +... |
865 | +provides: |
866 | + server: mongodb |
867 | +</code></pre> |
868 | + |
869 | +<p>...and that of a simple node.js application charm:</p> |
870 | + |
871 | +<pre class="runnable"><code> |
872 | +name: my-node-app |
873 | +... |
874 | +requires: |
875 | + database: mongodb |
876 | +provides: |
877 | + website: http |
878 | +</code></pre> |
879 | + |
880 | +<p>Put together, these files indicate that a relation can be made between services |
881 | +running the respective charms. The my-mongodb charm <code>provides</code> a relation named |
882 | +<code>server</code> with the <code>mongodb</code> interface, and the my-node-app charm |
883 | +<code>requires</code> a relation named <code>database</code> with the <code>mongodb</code> |
884 | +interface.</p> |
885 | + |
886 | +<p>The my-node-app charm also <code>provides</code> a relation named <code>website</code> |
887 | +with the <code>http</code> interface, but that's irrelevant to the mongodb charm. (But an |
888 | +haproxy charm might well define, say, <code>reverseproxy</code>, that <code>requires</code> |
889 | +the <code>http</code> interface provided by my-node-app.)</p> |
890 | +</section> |
891 | + |
892 | +<section id="relation-interfaces"> |
893 | +<h2>Relation interfaces</h2> |
894 | + |
895 | +<p>An interface is a string that must only contain <code>a-z</code> and <code>-</code>, |
896 | +and neither start nor end with <code>-</code>. It's the single determiner of |
897 | +compatibility between charms; and it carries with it nothing more than a mutual |
898 | +promise that the provider and requirer somehow know the communication protocol |
899 | +implied by the name.</p> |
900 | + |
901 | +<p>So, the relation namespace is essentially unrestricted (with one enforced |
902 | +exception: you may not <em>provide</em> a relation named <code>juju</code>, or |
903 | +starting with <code>juju-</code>). This allows for rapid development in some |
904 | +situations; but, in the example above, there is a potential problem: we've picked |
905 | +<em>two</em> interface names that already have meanings in the charm ecosystem, |
906 | +and that means we have to be <a href="./authors-charm-interfaces.html">compatible</a>; |
907 | +but that's a concern for a bit later, when we're actually writing the relation hooks.</p> |
908 | +</section> |
909 | + |
910 | +<section id="peer-relations"> |
911 | +<h2>Peer relations</h2> |
912 | + |
913 | +<p>Alongside <code>provides</code> and <code>requires</code>, charms can declare |
914 | +relations under <code>peers</code>. Where <code>provides</code> relations integrate |
915 | +with <code>requires</code> ones, such that providers respond to requirers and vice |
916 | +versa, the <code>peers</code> relation causes each unit of a single service to |
917 | +respond to the other units in the same service. A peer relation is otherwise defined |
918 | +in exactly the same way as any other relation.</p> |
919 | +</section> |
920 | + |
921 | +<section id="relation-config"> |
922 | +<h2>Configuring relations</h2> |
923 | + |
924 | +<p>There's an alternative syntax for specifying relations, which allows you to |
925 | +set additional fields by replacing the interface name with a dictionary. In this case, the <code>interface</code> key must be specified explicitly, and a number of other possibilities become available:</p> |
926 | +<ul> |
927 | + <li><code>scope</code> defaults to <code>global</code>, but may be set to |
928 | + <code>container</code>. The scope controls the set of remote units that are |
929 | + reported to the unit as members of the relation: container-scoped relations |
930 | + are restricted to reporting details of a single principal unit to a single |
931 | + subordinate, and vice versa, while global relations consider all possible |
932 | + remote units.<br /> |
933 | + <a href="authors-charm-subordinates.html">Subordinate</a> charms are only |
934 | + valid if they have at least one <code>requires</code> relation with |
935 | + <code>container</code> scope.</li> |
936 | + <li><code>limit</code> is ignored by juju, but if present should be a positive |
937 | + integer N indicating that the charm is not designed to use this interface in more |
938 | + than N relations at once.<br /> |
939 | + For example, if you're writing a really simple exploratory charm for your |
940 | + particular data store, you could just create a single shared store and |
941 | + write the same access credentials for every relation. A limit of 1 is |
942 | + thus useful in that it does <em>document</em> the restriction, even though |
943 | + it's not automatically enforced today.</li> |
944 | + <li><code>optional</code> is ignored by juju, but if present should only be |
945 | + set to true, on <code>requires</code> relations, to indicate that the charm |
946 | + can still function effectively without having those relations added.<br /> |
947 | + For example, the my-node-app charm might also define:<br /> |
948 | +<pre class="runnable"><code> |
949 | +requires: |
950 | + database: mongodb |
951 | + memcache: |
952 | + interface: memcached |
953 | + optional: true |
954 | +</code></pre><br /> |
955 | + ...to indicate that it can integrate with memcached if it's available, but |
956 | + that it can't be expected to do anything useful without a mongodb service |
957 | + available.</li> |
958 | + <li><code>gets</code> and <code>sets</code> are ignored by juju at present, |
959 | + but are valuable <a href="./authors-charm-interfaces.html">documentation</a>.</li> |
960 | +</ul> |
961 | + |
962 | +</section> |
963 | + |
964 | +<section id="examples"> |
965 | +<h2>Sample metadata.yaml files</h2> |
966 | + |
967 | + |
968 | + |
969 | +XXXXXXXXXXXXXXXXXXXXXXXXX |
970 | + |
971 | + |
972 | +</section> |
973 | + |
974 | + |
975 | + </article> |
976 | + </div> |
977 | + </div> |
978 | + </section> |
979 | + <div class="shadow"></div> |
980 | + <footer class="global clearfix" role="contentinfo"> |
981 | + <div class="row"> |
982 | + <div class="inner-wrapper"> |
983 | + <nav role="navigation" class="clearfix"> |
984 | + <ul class="footer-a"> |
985 | + <li class="grid-3 first-col"> |
986 | + <h4><a href="/get-started">Get started</a></h4> |
987 | + <ul> |
988 | + <li class="page_item page-item-20"><a href="https://juju.ubuntu.com/get-started/local/">Local</a></li> |
989 | + <li class="page_item page-item-22"><a href="https://juju.ubuntu.com/get-started/amazon/">Amazon Web Services</a></li> |
990 | + <li class="page_item page-item-18"><a href="https://juju.ubuntu.com/get-started/hp-cloud/">HP Cloud</a></li> |
991 | + <li class="page_item page-item-16"><a href="https://juju.ubuntu.com/get-started/rackspace/">Rackspace</a></li> |
992 | + <li class="page_item page-item-3596"><a href="https://juju.ubuntu.com/get-started/openstack/">Openstack</a></li> |
993 | + <li class="page_item page-item-3600"><a href="https://juju.ubuntu.com/get-started/maas/">MAAS</a></li> |
994 | + </ul> |
995 | + </li> |
996 | + <li class="grid-3"> |
997 | + <h4><a href="/resources">Resources</a></h4> |
998 | + <ul> |
999 | + <li><a href="http://juju.ubuntu.com/docs">Documentation</a></li> |
1000 | + <li><a href="/resources/videos/">Videos</a></li> |
1001 | + <li><a href="http://uistage.jujucharms.com:8080/">Juju GUI demo site</a></li> |
1002 | + </ul> |
1003 | + </li> |
1004 | + <li class="grid-3"> |
1005 | + <h4><a href="/community">Community</a></h4> |
1006 | + <ul> |
1007 | + <li class="page_item page-item-28"><a href="https://juju.ubuntu.com/community/juju-blog/">Juju Blog</a></li> |
1008 | + <li class="page_item page-item-4262"><a href="https://juju.ubuntu.com/community/weekly-charm-meeting/">Weekly Charm Meeting</a></li> |
1009 | + <li class="page_item page-item-4036"><a href="https://juju.ubuntu.com/community/charmers/">Charmers</a></li> |
1010 | + <li><a href="https://lists.ubuntu.com/mailman/listinfo/juju">Mailing List</a></li> |
1011 | + <li><a href="http://webchat.freenode.net/?channels=juju">Chat</a></li> |
1012 | + <li><a href="http://askubuntu.com/questions/tagged/juju?sort=faq&pagesize=50">FAQ</a></li> |
1013 | + </ul> |
1014 | + </li> |
1015 | + <li class="grid-3 last-col"> |
1016 | + <h4><a href="https://launchpad.net/juju">Code</a></h4> |
1017 | + <ul> |
1018 | + <li><a href="https://launchpad.net/juju-core">Juju Core</a></li> |
1019 | + <li><a href="https://launchpad.net/charms">Charms</a></li> |
1020 | + </ul> |
1021 | + </li> |
1022 | + </ul> |
1023 | + </nav> |
1024 | + </div> |
1025 | + </div> |
1026 | + <div class="row no-border"> |
1027 | + <div class="legal inner-wrapper"> |
1028 | + <p>© 2013 Canonical Ltd. Ubuntu and Canonical are registered trademarks of Canonical Ltd.</p> |
1029 | + <p><a href="https://bugs.launchpad.net/juju-website/+filebug">Report a bug on this site</a></p> |
1030 | + </div> |
1031 | + </div> |
1032 | +</footer> |
1033 | + |
1034 | + <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script> |
1035 | + <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jqueryui/1.8.14/jquery-ui.min.js"></script> |
1036 | + <script src="//d38yea5fb4e2oh.cloudfront.net/jquery.stacktack.min.js"></script> |
1037 | + <script type="text/javascript" src="js/main.js"></script> |
1038 | + <script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.js"></script> |
1039 | + </body> |
1040 | +</html> |
1041 | + |
1042 | |
1043 | === modified file 'htmldocs/authors-charm-policy.html' |
1044 | --- htmldocs/authors-charm-policy.html 2013-09-10 11:11:16 +0000 |
1045 | +++ htmldocs/authors-charm-policy.html 2013-09-11 07:54:25 +0000 |
1046 | @@ -91,7 +91,7 @@ |
1047 | |
1048 | <h2>metadata.yaml</h2> |
1049 | |
1050 | - <p>This file is an important component of a charm, see <a href="authors-charm-anatomy.html">Anatomy of a Charm</a> for the structure.</p> |
1051 | + <p>This file is an <a href="authors-charm-contents.html">important component</a> of a charm.</p> |
1052 | <p>Check out the <a href="https://bazaar.launchpad.net/~charmers/charms/precise/mysql/trunk/view/head:/metadata.yaml">MySQL metadata.yaml</a> as an example.</p> |
1053 | |
1054 | |
1055 | |
1056 | === added file 'htmldocs/authors-charm-upgrades.html' |
1057 | --- htmldocs/authors-charm-upgrades.html 1970-01-01 00:00:00 +0000 |
1058 | +++ htmldocs/authors-charm-upgrades.html 2013-09-11 07:54:25 +0000 |
1059 | @@ -0,0 +1,212 @@ |
1060 | +<!DOCTYPE html> |
1061 | +<html> |
1062 | + <head> |
1063 | + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> |
1064 | + <title>Juju Documentation - Charm Upgrades</title> |
1065 | + <link href='https://fonts.googleapis.com/css?family=Ubuntu:400,300,300italic,400italic,700,700italic|Ubuntu+Mono' rel='stylesheet' type='text/css' /> |
1066 | + <link rel="stylesheet" type="text/css" media="screen" href="//juju.ubuntu.com/wp-content/themes/juju-website/css/reset.css" /> |
1067 | + <link rel="stylesheet" type="text/css" media="screen" href="//juju.ubuntu.com/wp-content/themes/juju-website/css/960.css" /> |
1068 | + <link rel="stylesheet" type="text/css" media="screen" href="//juju.ubuntu.com/wp-content/themes/juju-website/css/base.css" /> |
1069 | + <link rel="stylesheet" type="text/css" media="screen" href="//juju.ubuntu.com/wp-content/themes/juju-website/css/home-new.css" /> |
1070 | + <link rel='stylesheet' id='stacktack-css' href='//juju.ubuntu.com/wp-content/plugins/stacktack/css/stacktack.min.css?ver=3.4.2' type='text/css' media='all' /> |
1071 | + <link href="css/main.css?1375975745" rel="stylesheet" type="text/css"/> |
1072 | + |
1073 | + <!--[if lt IE 9]> |
1074 | + <script type="text/javascript" src="//html5shim.googlecode.com/svn/trunk/html5.js"></script> |
1075 | + <![endif]--> |
1076 | +</head> |
1077 | + <body class="resources"> |
1078 | + <header class="global clearfix" role="banner"> |
1079 | + <div class="header-navigation"> |
1080 | + <div> |
1081 | + <nav role="navigation"> |
1082 | + <ul> |
1083 | + <li class="page_item page-item-6"><a href="https://juju.ubuntu.com/">Home</a></li> |
1084 | + <li class="page_item page-item-7"><a href="https://juju.ubuntu.com/get-started/">Get started</a></li> |
1085 | + <li class="page_item page-item-9 current_page_item"><a href="https://juju.ubuntu.com/resources/">Resources</a></li> |
1086 | + <li class="page_item page-item-13"><a href="https://juju.ubuntu.com/community/">Community</a></li> |
1087 | + <li class="page_item page-item-3688"><a href="https://juju.ubuntu.com/charm-store/">Charm Store</a></li> |
1088 | + <li class="page_item page-item-3691"><a href="https://juju.ubuntu.com/events/">Events</a></li> |
1089 | + <li class="page_item page-item-4474"><a href="https://juju.ubuntu.com/charm-championship/">Charm Championship</a></li> |
1090 | + <li class="page_item page-item-4249"><a href="https://juju.ubuntu.com/survey/">Survey</a></li> |
1091 | + <li> |
1092 | + <form id="form-search" method="get" action="https://juju.ubuntu.com/"> |
1093 | + <fieldset> |
1094 | + <input id="input-search" type="text" name="s" value="Search" /> |
1095 | + </fieldset> |
1096 | + </form> |
1097 | + </li> |
1098 | + </ul> |
1099 | + </nav> |
1100 | + </div> |
1101 | + </div> |
1102 | + <div class="header-content"> |
1103 | + <div class="clearfix"> |
1104 | + <img src="https://juju.ubuntu.com/wp-content/themes/juju-website/img/arrow-nav.png" width="9" height="5" style="left:455px; display: block;" class="arrow-nav"> |
1105 | + <div class="header-navigation-secondary"></div> |
1106 | + <div class="header-image"></div> |
1107 | + <h1>Resources</h1> |
1108 | + <h2>A collection of some of the most important online references for Juju users and developers.</h2> |
1109 | + </div> |
1110 | + </div> |
1111 | +</header> |
1112 | + |
1113 | + <section id="content" class="container-12"> |
1114 | + <div class="grid-12 doc-container"> |
1115 | + <div id="navlinks" class="grid-3 doc-navigation">LINKS</div> |
1116 | + <div class="grid-9 doc-content"> |
1117 | + <article> |
1118 | + |
1119 | + |
1120 | +<!--Actual docs start here--> |
1121 | + |
1122 | +<section id="charm-upgrades"> |
1123 | +<h1>Charm upgrades</h1> |
1124 | + |
1125 | +<p>A service's charm can be changed at runtime with the <code>upgrade-charm</code> |
1126 | +command. By default, it changes to the latest available version of the same charm; if |
1127 | +<code>--revision</code> is specified, it changes to that revision of the same charm; and |
1128 | +if <code>--switch</code> is specified it changes to any arbitrary charm, inferred from the |
1129 | +argument in the same way as in <code>juju deploy</code>.</p> |
1130 | + |
1131 | +<p>For a charm to replace another, though, there is a minimum standard of |
1132 | +compatibility, which applies regardless of the particular change. That is:</p> |
1133 | +<ul> |
1134 | + <li>a subordinate charm must be replaced by a subordinate charm, and a |
1135 | + principal charm must be replaced by a principal charm.</li> |
1136 | + <li>every runtime relation used by the service must exist in both charms.</li> |
1137 | + <li class=" sub">charm relations that are defined, but not in use at runtime, |
1138 | + may be removed freely.</li> |
1139 | + <li class=" sub">in particular, it's not possible to remove a peer relation by |
1140 | + upgrading, because peer relations are always in use.</li> |
1141 | +</ul> |
1142 | +<p>No other factor is used in determining compatibility: configuration settings |
1143 | +in particular are converted completely naively, such that any settings from |
1144 | +the original charm that share a name and type are preserved; any incompatible |
1145 | +settings are removed; and any new settings take defaults as though freshly |
1146 | +deployed.</p> |
1147 | + |
1148 | +<p>When a service has been upgraded but a particular unit has not, the unit will |
1149 | +continue to see the configuration settings from before conversion; these settings |
1150 | +will not be affected by subsequent changes to the service's settings.</p> |
1151 | +</section> |
1152 | + |
1153 | +<section id="forced-upgrades"> |
1154 | +<h2>Forced charm upgrades</h2> |
1155 | + |
1156 | +<p>Juju defines the upgrade-charm <a href="./authors-hook-kinds.html">hook</a> for |
1157 | +resolving differences between versions of the same charm. No notice is given of |
1158 | +charm upgrades; a charm upgrade may run at any time the unit is started, and the |
1159 | +only opportunity for resolution that exists occurs *after* the change has taken |
1160 | +place.</p> |
1161 | + |
1162 | +<p>This is quite a tight restriction, but nonetheless valuable, so long as you can |
1163 | +guarantee it'll run. However, it's important to understand that the upgrade-charm |
1164 | +accepts a <code>--force</code> flag: a forced charm upgrade will upgrade even units |
1165 | +that are currently in an <a href="./authors-hook-errors.html">error</a> state, at |
1166 | +the cost of skipping the <code>upgrade-charm</code> hook for those units.</p> |
1167 | + |
1168 | +<p>This is useful for charm authors who want to push a new version of a failed hook |
1169 | +(they can <code>upgrade-charm --force</code> and then <code>resolved --retry</code> |
1170 | +to run it immediately without otherwise disturbing the system); but it's potentially |
1171 | +dangerous if abused. We recommend that use of the feature be restricted to charm |
1172 | +authors while developing their own charms, and that it's not sensible to devote |
1173 | +serious effort to recovering from inappropriately forced upgrades.</p> |
1174 | +</section> |
1175 | + |
1176 | +<section id="upgrade-errors"> |
1177 | +<h2>Charm upgrade errors</h2> |
1178 | + |
1179 | +<p>These will only occur as a result of conflicts between the contents of the |
1180 | +charm directory written at runtime, and should never be seen by a user; users |
1181 | +certainly cannot be expected to understand the structure of your charm well |
1182 | +enough to solve the conflicts sanely.</p> |
1183 | + |
1184 | +<p>When you're writing a new version of a charm, you should always test upgrading |
1185 | +it from (at least) the previous version, to ensure these errors don't slip out |
1186 | +into the wild.</p> |
1187 | + |
1188 | +<p>You can completely avoid these errors by <em>never</em> writing to the charm |
1189 | +directory; and you can also avoid them by rigorously delineating the parts of |
1190 | +your charm directory that you write to at runtime, and ensuring you never add a |
1191 | +file to the raw charm that could conflict with the runtime state.</p> |
1192 | + |
1193 | +<p>If you're writing your hooks in python, you should be doubly aware of this: if |
1194 | +you don't configure python to suppress bytecode caching, it will write <code>.pyc</code> |
1195 | +files next to your python files at runtime, and effectively prevent you from |
1196 | +rearranging those directories in future. This is not an unreasonable burden to |
1197 | +bear, but it's important to know you're taking it on.</p> |
1198 | + |
1199 | +<p>If you encounter a charm upgrade error, you can run <code>git status</code> in |
1200 | +the charm directory to see what the problem is, and use the knowledge thus gleaned to |
1201 | +fix the charm and try to upgrade again.</p> |
1202 | +</section> |
1203 | + |
1204 | + |
1205 | + </article> |
1206 | + </div> |
1207 | + </div> |
1208 | + </section> |
1209 | + <div class="shadow"></div> |
1210 | + <footer class="global clearfix" role="contentinfo"> |
1211 | + <div class="row"> |
1212 | + <div class="inner-wrapper"> |
1213 | + <nav role="navigation" class="clearfix"> |
1214 | + <ul class="footer-a"> |
1215 | + <li class="grid-3 first-col"> |
1216 | + <h4><a href="/get-started">Get started</a></h4> |
1217 | + <ul> |
1218 | + <li class="page_item page-item-20"><a href="https://juju.ubuntu.com/get-started/local/">Local</a></li> |
1219 | + <li class="page_item page-item-22"><a href="https://juju.ubuntu.com/get-started/amazon/">Amazon Web Services</a></li> |
1220 | + <li class="page_item page-item-18"><a href="https://juju.ubuntu.com/get-started/hp-cloud/">HP Cloud</a></li> |
1221 | + <li class="page_item page-item-16"><a href="https://juju.ubuntu.com/get-started/rackspace/">Rackspace</a></li> |
1222 | + <li class="page_item page-item-3596"><a href="https://juju.ubuntu.com/get-started/openstack/">Openstack</a></li> |
1223 | + <li class="page_item page-item-3600"><a href="https://juju.ubuntu.com/get-started/maas/">MAAS</a></li> |
1224 | + </ul> |
1225 | + </li> |
1226 | + <li class="grid-3"> |
1227 | + <h4><a href="/resources">Resources</a></h4> |
1228 | + <ul> |
1229 | + <li><a href="http://juju.ubuntu.com/docs">Documentation</a></li> |
1230 | + <li><a href="/resources/videos/">Videos</a></li> |
1231 | + <li><a href="http://uistage.jujucharms.com:8080/">Juju GUI demo site</a></li> |
1232 | + </ul> |
1233 | + </li> |
1234 | + <li class="grid-3"> |
1235 | + <h4><a href="/community">Community</a></h4> |
1236 | + <ul> |
1237 | + <li class="page_item page-item-28"><a href="https://juju.ubuntu.com/community/juju-blog/">Juju Blog</a></li> |
1238 | + <li class="page_item page-item-4262"><a href="https://juju.ubuntu.com/community/weekly-charm-meeting/">Weekly Charm Meeting</a></li> |
1239 | + <li class="page_item page-item-4036"><a href="https://juju.ubuntu.com/community/charmers/">Charmers</a></li> |
1240 | + <li><a href="https://lists.ubuntu.com/mailman/listinfo/juju">Mailing List</a></li> |
1241 | + <li><a href="http://webchat.freenode.net/?channels=juju">Chat</a></li> |
1242 | + <li><a href="http://askubuntu.com/questions/tagged/juju?sort=faq&pagesize=50">FAQ</a></li> |
1243 | + </ul> |
1244 | + </li> |
1245 | + <li class="grid-3 last-col"> |
1246 | + <h4><a href="https://launchpad.net/juju">Code</a></h4> |
1247 | + <ul> |
1248 | + <li><a href="https://launchpad.net/juju-core">Juju Core</a></li> |
1249 | + <li><a href="https://launchpad.net/charms">Charms</a></li> |
1250 | + </ul> |
1251 | + </li> |
1252 | + </ul> |
1253 | + </nav> |
1254 | + </div> |
1255 | + </div> |
1256 | + <div class="row no-border"> |
1257 | + <div class="legal inner-wrapper"> |
1258 | + <p>© 2013 Canonical Ltd. Ubuntu and Canonical are registered trademarks of Canonical Ltd.</p> |
1259 | + <p><a href="https://bugs.launchpad.net/juju-website/+filebug">Report a bug on this site</a></p> |
1260 | + </div> |
1261 | + </div> |
1262 | +</footer> |
1263 | + |
1264 | + <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script> |
1265 | + <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jqueryui/1.8.14/jquery-ui.min.js"></script> |
1266 | + <script src="//d38yea5fb4e2oh.cloudfront.net/jquery.stacktack.min.js"></script> |
1267 | + <script type="text/javascript" src="js/main.js"></script> |
1268 | + <script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.js"></script> |
1269 | + </body> |
1270 | +</html> |
1271 | + |
1272 | |
1273 | === modified file 'htmldocs/authors-charm-writing.html' |
1274 | --- htmldocs/authors-charm-writing.html 2013-09-10 11:11:16 +0000 |
1275 | +++ htmldocs/authors-charm-writing.html 2013-09-11 07:54:25 +0000 |
1276 | @@ -163,7 +163,7 @@ |
1277 | <span class="number" > 4 </span> |
1278 | <div class="step" id="step04"> |
1279 | <h2>Writing hooks</h2> |
1280 | - <p>As you will know from your through reading of <a href="./authors-charm-anatomy.html"> the anatomy of a charm</a> The hooks are the important scripts that actually do things. You can write hooks in whatever language you can reasonably expect to execute on an Ubuntu server</p> |
1281 | + <p>As you will know from your thorough reading of the <a href="./authors-charm-contents.html">charm contents</a>, the hooks are the important scripts that actually do things. You can write hooks in whatever language you can reasonably expect to execute on an Ubuntu server.</p> |
1282 | <p>For our charm, the hooks we will need to create are:</p> |
1283 | <ul> |
1284 | <li>start - for when the service needs to be started.</li> |
1285 | |
1286 | === renamed file 'htmldocs/authors-charms-in-action.html' => 'htmldocs/authors-charms-in-action.html.THIS' |
1287 | === added file 'htmldocs/authors-hook-debug.html' |
1288 | --- htmldocs/authors-hook-debug.html 1970-01-01 00:00:00 +0000 |
1289 | +++ htmldocs/authors-hook-debug.html 2013-09-11 07:54:25 +0000 |
1290 | @@ -0,0 +1,169 @@ |
1291 | +<!DOCTYPE html> |
1292 | +<html> |
1293 | + <head> |
1294 | + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> |
1295 | + <title>Juju Documentation - Hook Debugging</title> |
1296 | + <link href='https://fonts.googleapis.com/css?family=Ubuntu:400,300,300italic,400italic,700,700italic|Ubuntu+Mono' rel='stylesheet' type='text/css' /> |
1297 | + <link rel="stylesheet" type="text/css" media="screen" href="//juju.ubuntu.com/wp-content/themes/juju-website/css/reset.css" /> |
1298 | + <link rel="stylesheet" type="text/css" media="screen" href="//juju.ubuntu.com/wp-content/themes/juju-website/css/960.css" /> |
1299 | + <link rel="stylesheet" type="text/css" media="screen" href="//juju.ubuntu.com/wp-content/themes/juju-website/css/base.css" /> |
1300 | + <link rel="stylesheet" type="text/css" media="screen" href="//juju.ubuntu.com/wp-content/themes/juju-website/css/home-new.css" /> |
1301 | + <link rel='stylesheet' id='stacktack-css' href='//juju.ubuntu.com/wp-content/plugins/stacktack/css/stacktack.min.css?ver=3.4.2' type='text/css' media='all' /> |
1302 | + <link href="css/main.css?1375975745" rel="stylesheet" type="text/css"/> |
1303 | + |
1304 | + <!--[if lt IE 9]> |
1305 | + <script type="text/javascript" src="//html5shim.googlecode.com/svn/trunk/html5.js"></script> |
1306 | + <![endif]--> |
1307 | +</head> |
1308 | + <body class="resources"> |
1309 | + <header class="global clearfix" role="banner"> |
1310 | + <div class="header-navigation"> |
1311 | + <div> |
1312 | + <nav role="navigation"> |
1313 | + <ul> |
1314 | + <li class="page_item page-item-6"><a href="https://juju.ubuntu.com/">Home</a></li> |
1315 | + <li class="page_item page-item-7"><a href="https://juju.ubuntu.com/get-started/">Get started</a></li> |
1316 | + <li class="page_item page-item-9 current_page_item"><a href="https://juju.ubuntu.com/resources/">Resources</a></li> |
1317 | + <li class="page_item page-item-13"><a href="https://juju.ubuntu.com/community/">Community</a></li> |
1318 | + <li class="page_item page-item-3688"><a href="https://juju.ubuntu.com/charm-store/">Charm Store</a></li> |
1319 | + <li class="page_item page-item-3691"><a href="https://juju.ubuntu.com/events/">Events</a></li> |
1320 | + <li class="page_item page-item-4474"><a href="https://juju.ubuntu.com/charm-championship/">Charm Championship</a></li> |
1321 | + <li class="page_item page-item-4249"><a href="https://juju.ubuntu.com/survey/">Survey</a></li> |
1322 | + <li> |
1323 | + <form id="form-search" method="get" action="https://juju.ubuntu.com/"> |
1324 | + <fieldset> |
1325 | + <input id="input-search" type="text" name="s" value="Search" /> |
1326 | + </fieldset> |
1327 | + </form> |
1328 | + </li> |
1329 | + </ul> |
1330 | + </nav> |
1331 | + </div> |
1332 | + </div> |
1333 | + <div class="header-content"> |
1334 | + <div class="clearfix"> |
1335 | + <img src="https://juju.ubuntu.com/wp-content/themes/juju-website/img/arrow-nav.png" width="9" height="5" style="left:455px; display: block;" class="arrow-nav"> |
1336 | + <div class="header-navigation-secondary"></div> |
1337 | + <div class="header-image"></div> |
1338 | + <h1>Resources</h1> |
1339 | + <h2>A collection of some of the most important online references for Juju users and developers.</h2> |
1340 | + </div> |
1341 | + </div> |
1342 | +</header> |
1343 | + |
1344 | + <section id="content" class="container-12"> |
1345 | + <div class="grid-12 doc-container"> |
1346 | + <div id="navlinks" class="grid-3 doc-navigation">LINKS</div> |
1347 | + <div class="grid-9 doc-content"> |
1348 | + <article> |
1349 | + |
1350 | + |
1351 | +<section id="debugging-hooks"> |
1352 | +<h1>Debugging hooks</h1> |
1353 | + |
1354 | +<p>The <code>juju debug-hooks</code> command accepts a unit and an optional list |
1355 | +of hooks to debug, which must each be named individually -- or all omitted, causing all |
1356 | +hooks to be debugged.</p> |
1357 | + |
1358 | +<p>When you start a debug-hooks session, juju creates a tmux session on the |
1359 | +machine running the requested unit; while that session persists, all hook |
1360 | +executions will be replaced with new windows in that session, which run an |
1361 | +<a href="./authors-hook-environment.html">environment</a> matching that of the |
1362 | +appropriate hook (with one addition: <code>$JUJU_HOOK_NAME</code>) and which are |
1363 | +marked as succeeded or failed depending on the exit code of the window.</p> |
1364 | + |
1365 | +<p>You can stop debugging by closing all windows in the tmux session.</p> |
1366 | +</section> |
1367 | + |
1368 | +<section id="intercept-install"> |
1369 | +<h2>Debugging early hooks</h2> |
1370 | + |
1371 | +<p>The <code>install</code>, <code>config-changed</code>, and <code>start</code> |
1372 | +hooks often execute quite soon after the unit comes up, making it difficult to start |
1373 | +a debug-hooks session in time to intercept them. If you're having difficulties, you |
1374 | +can temporarily return an error code from your <code>install</code> hook, and start |
1375 | +your session only when the unit reports an <a href="./authors-hook-errors.html">error |
1376 | +status</a>; then run <code>juju resolved --retry</code> for the affected unit, and go |
1377 | +back to the debug-hooks session to interact.</p> |
1378 | +</section> |
1379 | + |
1380 | +<section id="notes"> |
1381 | +<h2>Special considerations</h2> |
1382 | + |
1383 | +<p>While you're debugging hooks for one unit on a machine, you're blocking |
1384 | +execution of all hooks on that machine. This is generally helpful, because |
1385 | +you don't want to have to contend with concurrent changes to the machine's |
1386 | +software, but you should be aware that multiple debug-hooks sessions for |
1387 | +units assigned to the same machine will block one another, and that you |
1388 | +can't control relative execution order directly (other than by erroring out |
1389 | +of hooks you don't want to run yet, and retrying them later).</p> |
1390 | +</section> |
1391 | + |
1392 | + |
1393 | + </article> |
1394 | + </div> |
1395 | + </div> |
1396 | + </section> |
1397 | + <div class="shadow"></div> |
1398 | + <footer class="global clearfix" role="contentinfo"> |
1399 | + <div class="row"> |
1400 | + <div class="inner-wrapper"> |
1401 | + <nav role="navigation" class="clearfix"> |
1402 | + <ul class="footer-a"> |
1403 | + <li class="grid-3 first-col"> |
1404 | + <h4><a href="/get-started">Get started</a></h4> |
1405 | + <ul> |
1406 | + <li class="page_item page-item-20"><a href="https://juju.ubuntu.com/get-started/local/">Local</a></li> |
1407 | + <li class="page_item page-item-22"><a href="https://juju.ubuntu.com/get-started/amazon/">Amazon Web Services</a></li> |
1408 | + <li class="page_item page-item-18"><a href="https://juju.ubuntu.com/get-started/hp-cloud/">HP Cloud</a></li> |
1409 | + <li class="page_item page-item-16"><a href="https://juju.ubuntu.com/get-started/rackspace/">Rackspace</a></li> |
1410 | + <li class="page_item page-item-3596"><a href="https://juju.ubuntu.com/get-started/openstack/">Openstack</a></li> |
1411 | + <li class="page_item page-item-3600"><a href="https://juju.ubuntu.com/get-started/maas/">MAAS</a></li> |
1412 | + </ul> |
1413 | + </li> |
1414 | + <li class="grid-3"> |
1415 | + <h4><a href="/resources">Resources</a></h4> |
1416 | + <ul> |
1417 | + <li><a href="http://juju.ubuntu.com/docs">Documentation</a></li> |
1418 | + <li><a href="/resources/videos/">Videos</a></li> |
1419 | + <li><a href="http://uistage.jujucharms.com:8080/">Juju GUI demo site</a></li> |
1420 | + </ul> |
1421 | + </li> |
1422 | + <li class="grid-3"> |
1423 | + <h4><a href="/community">Community</a></h4> |
1424 | + <ul> |
1425 | + <li class="page_item page-item-28"><a href="https://juju.ubuntu.com/community/juju-blog/">Juju Blog</a></li> |
1426 | + <li class="page_item page-item-4262"><a href="https://juju.ubuntu.com/community/weekly-charm-meeting/">Weekly Charm Meeting</a></li> |
1427 | + <li class="page_item page-item-4036"><a href="https://juju.ubuntu.com/community/charmers/">Charmers</a></li> |
1428 | + <li><a href="https://lists.ubuntu.com/mailman/listinfo/juju">Mailing List</a></li> |
1429 | + <li><a href="http://webchat.freenode.net/?channels=juju">Chat</a></li> |
1430 | + <li><a href="http://askubuntu.com/questions/tagged/juju?sort=faq&pagesize=50">FAQ</a></li> |
1431 | + </ul> |
1432 | + </li> |
1433 | + <li class="grid-3 last-col"> |
1434 | + <h4><a href="https://launchpad.net/juju">Code</a></h4> |
1435 | + <ul> |
1436 | + <li><a href="https://launchpad.net/juju-core">Juju Core</a></li> |
1437 | + <li><a href="https://launchpad.net/charms">Charms</a></li> |
1438 | + </ul> |
1439 | + </li> |
1440 | + </ul> |
1441 | + </nav> |
1442 | + </div> |
1443 | + </div> |
1444 | + <div class="row no-border"> |
1445 | + <div class="legal inner-wrapper"> |
1446 | + <p>© 2013 Canonical Ltd. Ubuntu and Canonical are registered trademarks of Canonical Ltd.</p> |
1447 | + <p><a href="https://bugs.launchpad.net/juju-website/+filebug">Report a bug on this site</a></p> |
1448 | + </div> |
1449 | + </div> |
1450 | +</footer> |
1451 | + |
1452 | + <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script> |
1453 | + <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jqueryui/1.8.14/jquery-ui.min.js"></script> |
1454 | + <script src="//d38yea5fb4e2oh.cloudfront.net/jquery.stacktack.min.js"></script> |
1455 | + <script type="text/javascript" src="js/main.js"></script> |
1456 | + <script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.js"></script> |
1457 | + </body> |
1458 | +</html> |
1459 | + |
1460 | |
1461 | === added file 'htmldocs/authors-hook-environment.html' |
1462 | --- htmldocs/authors-hook-environment.html 1970-01-01 00:00:00 +0000 |
1463 | +++ htmldocs/authors-hook-environment.html 2013-09-11 07:54:25 +0000 |
1464 | @@ -0,0 +1,539 @@ |
1465 | +<!DOCTYPE html> |
1466 | +<html> |
1467 | + <head> |
1468 | + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> |
1469 | + <title>Juju Documentation - Hook Environment and Tools</title> |
1470 | + <link href='https://fonts.googleapis.com/css?family=Ubuntu:400,300,300italic,400italic,700,700italic|Ubuntu+Mono' rel='stylesheet' type='text/css' /> |
1471 | + <link rel="stylesheet" type="text/css" media="screen" href="//juju.ubuntu.com/wp-content/themes/juju-website/css/reset.css" /> |
1472 | + <link rel="stylesheet" type="text/css" media="screen" href="//juju.ubuntu.com/wp-content/themes/juju-website/css/960.css" /> |
1473 | + <link rel="stylesheet" type="text/css" media="screen" href="//juju.ubuntu.com/wp-content/themes/juju-website/css/base.css" /> |
1474 | + <link rel="stylesheet" type="text/css" media="screen" href="//juju.ubuntu.com/wp-content/themes/juju-website/css/home-new.css" /> |
1475 | + <link rel='stylesheet' id='stacktack-css' href='//juju.ubuntu.com/wp-content/plugins/stacktack/css/stacktack.min.css?ver=3.4.2' type='text/css' media='all' /> |
1476 | + <link href="css/main.css?1375975745" rel="stylesheet" type="text/css"/> |
1477 | + |
1478 | + <!--[if lt IE 9]> |
1479 | + <script type="text/javascript" src="//html5shim.googlecode.com/svn/trunk/html5.js"></script> |
1480 | + <![endif]--> |
1481 | +</head> |
1482 | + <body class="resources"> |
1483 | + <header class="global clearfix" role="banner"> |
1484 | + <div class="header-navigation"> |
1485 | + <div> |
1486 | + <nav role="navigation"> |
1487 | + <ul> |
1488 | + <li class="page_item page-item-6"><a href="https://juju.ubuntu.com/">Home</a></li> |
1489 | + <li class="page_item page-item-7"><a href="https://juju.ubuntu.com/get-started/">Get started</a></li> |
1490 | + <li class="page_item page-item-9 current_page_item"><a href="https://juju.ubuntu.com/resources/">Resources</a></li> |
1491 | + <li class="page_item page-item-13"><a href="https://juju.ubuntu.com/community/">Community</a></li> |
1492 | + <li class="page_item page-item-3688"><a href="https://juju.ubuntu.com/charm-store/">Charm Store</a></li> |
1493 | + <li class="page_item page-item-3691"><a href="https://juju.ubuntu.com/events/">Events</a></li> |
1494 | + <li class="page_item page-item-4474"><a href="https://juju.ubuntu.com/charm-championship/">Charm Championship</a></li> |
1495 | + <li class="page_item page-item-4249"><a href="https://juju.ubuntu.com/survey/">Survey</a></li> |
1496 | + <li> |
1497 | + <form id="form-search" method="get" action="https://juju.ubuntu.com/"> |
1498 | + <fieldset> |
1499 | + <input id="input-search" type="text" name="s" value="Search" /> |
1500 | + </fieldset> |
1501 | + </form> |
1502 | + </li> |
1503 | + </ul> |
1504 | + </nav> |
1505 | + </div> |
1506 | + </div> |
1507 | + <div class="header-content"> |
1508 | + <div class="clearfix"> |
1509 | + <img src="https://juju.ubuntu.com/wp-content/themes/juju-website/img/arrow-nav.png" width="9" height="5" style="left:455px; display: block;" class="arrow-nav"> |
1510 | + <div class="header-navigation-secondary"></div> |
1511 | + <div class="header-image"></div> |
1512 | + <h1>Resources</h1> |
1513 | + <h2>A collection of some of the most important online references for Juju users and developers.</h2> |
1514 | + </div> |
1515 | + </div> |
1516 | +</header> |
1517 | + |
1518 | + <section id="content" class="container-12"> |
1519 | + <div class="grid-12 doc-container"> |
1520 | + <div id="navlinks" class="grid-3 doc-navigation">LINKS</div> |
1521 | + <div class="grid-9 doc-content"> |
1522 | + <article> |
1523 | + |
1524 | + |
1525 | +<section id="hook-execution-environment"> |
1526 | +<h1>Hook execution environment</h1> |
1527 | + |
1528 | +<p>When a charm is deployed onto a unit, the raw charm is extracted into a |
1529 | +directory; this directory is known as the charm directory. It's owned and |
1530 | +operated by juju, and juju sometimes temporarily cedes control of it to |
1531 | +user code, by running a hook inside it.</p> |
1532 | + |
1533 | +<p>When a hook's running, it should be considered to have sole access to the |
1534 | +charm directory; at all other times, you should consider that juju may be |
1535 | +making arbitrarily scary changes to the directory, and that it is not safe |
1536 | +to read or write to anything in there at all.</p> |
1537 | + |
1538 | +<p>This is to say that the software you install must, once it's running, be |
1539 | +entirely independent of the charm that created it. It's fine (and encouraged, |
1540 | +with some caveats) to store <em>charm</em> state in the charm directory, but the |
1541 | +state of your <em>software</em> must remain unperturbed by direct changes to the |
1542 | +charm.</p> |
1543 | + |
1544 | +<p>So, every hook runs with easy access to the charm files. Every hook also runs |
1545 | +as root, with a number of useful variables set, and has access to hook-specific |
1546 | +tools that let you interrogate and affect the juju environment.</p> |
1547 | + |
1548 | +<p>No more than one hook will execute on a given system at a given time. A unit in |
1549 | +a container is considered to be on a different system to any unit on the |
1550 | +container's host machine.</p> |
1551 | +</section> |
1552 | + |
1553 | +<section id="environment-variables"> |
1554 | +<h2>Environment variables</h2> |
1555 | + |
1556 | +<p>The following variables are always available.</p> |
1557 | +<ul> |
1558 | + <li>The <code>$CHARM_DIR</code> variable is the path to the charm directory.</li> |
1559 | + <li>The <code>$PATH</code> variable is prefixed with the path to the hook tools |
1560 | + directory.</li> |
1561 | + <li>The <code>$JUJU_UNIT_NAME</code> variable holds the name of the unit.</li> |
1562 | + <li>The <code>$JUJU_API_ADDRESSES</code> variable holds a space-separated list of API |
1563 | + server addresses.</li> |
1564 | +</ul> |
1565 | +<p>In addition, every relation hook makes available relation-specific variables.</p> |
1566 | +<ul> |
1567 | + <li>The <code>$JUJU_RELATION</code> variable holds the relation name. This |
1568 | + information is of limited value, because it's always the same as the part of |
1569 | + the hook name just before "-relation-".</li> |
1570 | + <li>The <code>$JUJU_RELATION_ID</code> variable holds an opaque relation |
1571 | + identifier, used to distinguish between multiple relations with the same name. |
1572 | + It is vitally important, because it's the only reasonable way of telling the |
1573 | + difference between (say) a database service's many independent clients.</li> |
1574 | +</ul> |
1575 | +<p>...and, if that relation hook is not a -broken hook:</p> |
1576 | +<ul> |
1577 | + <li>The <code>$JUJU_REMOTE_UNIT</code> variable holds the name of the unit which |
1578 | + is being reported to have -joined, -changed, or -departed.</li> |
1579 | +</ul> |
1580 | +<p>Juju does <em>not</em> pay any attention to the values of the above variables when |
1581 | +running hook tools: they're a one-way communication channel from juju to |
1582 | +the charm only. Finally, in all cases:</p> |
1583 | +<ul> |
1584 | + <li>The <code>$JUJU_AGENT_SOCKET</code> and <code>$JUJU_CONTEXT_ID</code> variables |
1585 | + allow the hook tools to work: juju <em>does</em> pay attention to them, but you |
1586 | + should treat them as opaque and avoid messing with them.</li> |
1587 | +</ul> |
1588 | +<p>Finally, if you're <a href="./authors-hook-debug.html">debugging</a>, you'll also |
1589 | +have access to:</p> |
1590 | +<ul> |
1591 | + <li>The <code>$JUJU_HOOK_NAME</code> variable, which will be set to the current |
1592 | + hook name.</li> |
1593 | +</ul> |
1594 | +</section> |
1595 | + |
1596 | +<section id="hook-tools"> |
1597 | +<h2>Hook tools</h2> |
1598 | + |
1599 | +<p>All hook tools are available in all hooks. Many of the tools produce output, |
1600 | +and those that do accept a <code>--format</code> flag whose value can be set to |
1601 | +<code>json</code> or <code>yaml</code> as desired. If it's not specified, the format |
1602 | +defaults to <code>smart</code>, which transforms the basic output as follows:</p> |
1603 | +<ul> |
1604 | + <li>strings are left untouched</li> |
1605 | + <li>boolean values are converted to the strings <code>True</code> and |
1606 | + <code>False</code></li> |
1607 | + <li>ints and floats are converted directly to strings</li> |
1608 | + <li>lists of strings are converted to a single newline-separated string</li> |
1609 | + <li>all other types (in general, dictionaries) are formatted as YAML</li> |
1610 | +</ul> |
1611 | +<p>Tools which do not produce output also accept the <code>--format</code> flag, |
1612 | +but ignore it, for compatibility reasons.</p> |
1613 | + |
1614 | +<p>The various "relation-" tools infer context from the hook where |
1615 | +possible. If they're running in a relation hook, the current relation id is set |
1616 | +as the default; and if they're running in a -joined, -changed, or -broken hook, |
1617 | +the current remote unit is set as the default.</p> |
1618 | + |
1619 | +<p>Best use of relation hooks will be made by those who understand the |
1620 | +<a href="./authors-relations-in-depth">relation model</a>.</p> |
1621 | +</section> |
1622 | + |
1623 | +<section id="juju-log"> |
1624 | +<h3>juju-log</h3> |
1625 | + |
1626 | +<p><code>juju-log</code> writes its arguments directly to the unit's log file. |
1627 | +All hook output is currently logged anyway, so it's theoretically redundant with |
1628 | +<code>echo</code>, but this is an implementation detail and should not be depended |
1629 | +upon. If it's important, please <code>juju-log</code> it.</p> |
1630 | + |
1631 | +<pre class="runnable"><code> |
1632 | +$ juju-log some important text |
1633 | +</code></pre> |
1634 | + |
1635 | +<p>It accepts a <code>--debug</code> flag which causes the message to be logged |
1636 | +at <code>DEBUG</code> level; in all other cases it's logged at <code>INFO</code> |
1637 | +level. The <code>-l</code>/<code>--level</code> argument is ignored, and is present |
1638 | +only to prevent legacy charms from entirely failing to run; the inability to specify |
1639 | +logging levels and targets in more detail is a known |
1640 | +<a href="https://bugs.launchpad.net/juju-core/+bug/1223325">bug</a>.</p> |
1641 | +</section> |
1642 | + |
1643 | +<section id="unit-get"> |
1644 | +<h3>unit-get</h3> |
1645 | + |
1646 | +<p><code>unit-get</code> returns information about the local unit. It accepts a |
1647 | +single argument, which must be <code>private-address</code> or |
1648 | +<code>public-address</code>. It is not affected by context.</p> |
1649 | + |
1650 | +<pre class="runnable"><code> |
1651 | +$ unit-get private-address |
1652 | +10.0.1.101 |
1653 | +</code></pre> |
1654 | + |
1655 | +<pre class="runnable"><code> |
1656 | +$ unit-get public-address |
1657 | +foo.example.com |
1658 | +</code></pre> |
1659 | + |
1660 | +</section> |
1661 | + |
1662 | +<section id="config-get"> |
1663 | +<h3>config-get</h3> |
1664 | + |
1665 | +<p><code>config-get</code> returns information about the service configuration (as |
1666 | +defined by the charm). If called without arguments, it returns a dictionary |
1667 | +containing all config settings that are either explicitly set, or which |
1668 | +have a non-nil default value. If the <code>--all</code> flag is passed, it returns |
1669 | +a dictionary containing all definied config settings including nil values |
1670 | +(for those without defaults). If called with a single argument, it returns |
1671 | +the value of that config key. Missing config keys are reported as having a |
1672 | +value of nil, and do not return an error.</p> |
1673 | + |
1674 | +<pre class="runnable"><code> |
1675 | +# Get the interesting bits of the config. |
1676 | +$ config-get |
1677 | +key: some-value |
1678 | +another-key: default-value |
1679 | +</code></pre> |
1680 | + |
1681 | +<pre class="runnable"><code> |
1682 | +# Get the whole config including nulls. |
1683 | +$ config-get --all |
1684 | +key: some-value |
1685 | +another-key: default-value |
1686 | +no-default: null |
1687 | +</code></pre> |
1688 | + |
1689 | +<pre class="runnable"><code> |
1690 | +# Get a single config setting. |
1691 | +$ config-get another-key |
1692 | +default-value |
1693 | +</code></pre> |
1694 | + |
1695 | +<pre class="runnable"><code> |
1696 | +# Get a config setting with no value. |
1697 | +$ config-get no-default |
1698 | +</code></pre> |
1699 | + |
1700 | +<pre class="runnable"><code> |
1701 | +# Get a config setting that doesn't exist. |
1702 | +$ config-get missing-key |
1703 | +</code></pre> |
1704 | + |
1705 | +</section> |
1706 | + |
1707 | +<section id="open-port"> |
1708 | +<h3>open-port</h3> |
1709 | + |
1710 | +<p><code>open-port</code> marks a port on the local system as appropriate to |
1711 | +open, if and when the service is exposed to the outside world. It accepts a single |
1712 | +port with an optional protocol, which may be <code>udp</code> or <code>tcp</code>, |
1713 | +where <code>tcp</code> is the default.</p> |
1714 | + |
1715 | +<pre class="runnable"><code> |
1716 | +# Open 80/tcp if and when the service is exposed. |
1717 | +$ open-port 80 |
1718 | +</code></pre> |
1719 | + |
1720 | +<pre class="runnable"><code> |
1721 | +# Open 1234/udp if and when the service is exposed. |
1722 | +$ open-port 1234/udp |
1723 | +</code></pre> |
1724 | + |
1725 | +<p><code>open-port</code> will not have any effect if the service is not exposed, |
1726 | +and may have a somewhat delayed effect even if it is. It accepts and ignores |
1727 | +<code>--format</code>, because it doesn't produce any output.</p> |
1728 | + |
1729 | +</section> |
1730 | + |
1731 | +<section id="close-port"> |
1732 | +<h3>close-port</h3> |
1733 | + |
1734 | +<p><code>close-port</code> unmarks a local system port. If the service is not |
1735 | +exposed, it has no effect; otherwise the port is marked for imminent closure. It |
1736 | +accepts the same flags and arguments as <code>open-port</code>.</p> |
1737 | + |
1738 | +<pre class="runnable"><code> |
1739 | +# Close 1234/udp if it was open. |
1740 | +$ close-port 1234/udp |
1741 | +</code></pre> |
1742 | + |
1743 | +<pre class="runnable"><code> |
1744 | +# Close 80/tcp if it was open. |
1745 | +$ close-port 80 |
1746 | +</code></pre> |
1747 | + |
1748 | +</section> |
1749 | + |
1750 | +<section id="relation-set"> |
1751 | +<h3>relation-set</h3> |
1752 | + |
1753 | +<p><code>relation-set</code> writes the local unit's settings for some relation. It |
1754 | +accepts any number of <code>key=value</code> strings, and an optional <code>-r</code> |
1755 | +argument, which defaults to the current relation id. If it's not running in a relation |
1756 | +hook, <code>-r</code> needs to be specified. The <code>value</code> part of an argument |
1757 | +is not inspected, and is stored directly as a string. Setting an empty string causes |
1758 | +the setting to be removed.</p> |
1759 | + |
1760 | +<pre class="runnable"><code> |
1761 | +# Set a pair of values for the local unit in the default relation. |
1762 | +$ echo $JUJU_RELATION_ID |
1763 | +server:3 |
1764 | +$ relation-set username=bob password=2db673e81ffa264c |
1765 | +</code></pre> |
1766 | + |
1767 | +<pre class="runnable"><code> |
1768 | +# Set a pair of values for the local unit in a specific relation. |
1769 | +$ echo $JUJU_RELATION_ID |
1770 | + |
1771 | +$ relation-set -r server:3 username=jim password=12345 |
1772 | +</code></pre> |
1773 | + |
1774 | +<pre class="runnable"><code> |
1775 | +# Clear a value for the local unit in the default relation. |
1776 | +$ echo $JUJU_RELATION_ID |
1777 | +server:3 |
1778 | +$ relation-set deprecated-or-unused= |
1779 | +</code></pre> |
1780 | + |
1781 | +<p><code>relation-set</code> is the single tool at your disposal for communicating |
1782 | +your own configuration to units of related services. At least by convention, the |
1783 | +charm that <code>provides</code> an interface is likely to set values, and a charm |
1784 | +that <code>requires</code> that interface will read them; but there's nothing |
1785 | +forcing this. Whatever information you need to propagate for the remote charm to |
1786 | +work must be propagated via relation-set, with the single exception of the |
1787 | +<code>private-address</code> key, which is always set before the unit joins.</p> |
1788 | + |
1789 | +<p>You may wish to overwrite the <code>private-address</code> setting, for example |
1790 | +if you're writing a charm that serves as a proxy for some external service; but |
1791 | +you should in general avoid <em>removing</em> that key, because most charms expect |
1792 | +that value to exist unconditionally.</p> |
1793 | + |
1794 | +<p>All values set are stored locally until the hook completes; at that point, |
1795 | +if the hook exit code is 0, all changed values will be communicated to the |
1796 | +rest of the system, causing -changed hooks to run in all related units.</p> |
1797 | + |
1798 | +<p>There is no way to write settings for any unit other than the local unit; but |
1799 | +any hook on the local unit can write settings for any relation the local unit is |
1800 | +participating in.</p> |
1801 | + |
1802 | +</section> |
1803 | + |
1804 | +<section id="relation-get"> |
1805 | +<h3>relation-get</h3> |
1806 | + |
1807 | +<p><code>relation-get</code> reads the settings of the local unit, or of any |
1808 | +remote unit, in a given relation (set with <code>-r</code>, defaulting to the |
1809 | +current relation, as in <code>relation-set</code>). The first argument specifies |
1810 | +the settings key, and the second the remote unit, which may be omitted if a |
1811 | +default is available (that is, when running a relation hook other than -broken).</p> |
1812 | + |
1813 | +<p>If the first argument is omitted, a dictionary of all current keys and values |
1814 | +will be printed; all values are always plain strings without any interpretation. |
1815 | +If you need to specify a remote unit but want to see all settings, use <code>-</code> |
1816 | +for the first argument.</p> |
1817 | + |
1818 | +<pre class="runnable"><code> |
1819 | +# Get all settings from the default remote unit in the default relation. |
1820 | +$ echo $JUJU_RELATION_ID |
1821 | +db:1 |
1822 | +$ echo $JUJU_REMOTE_UNIT |
1823 | +mongodb/2 |
1824 | +$ relation-get |
1825 | +username: jim |
1826 | +password: "12345" |
1827 | +</code></pre> |
1828 | + |
1829 | +<pre class="runnable"><code> |
1830 | +# Get one setting from the default remote unit in the default relation. |
1831 | +$ echo $JUJU_RELATION_ID |
1832 | +db:1 |
1833 | +$ echo $JUJU_REMOTE_UNIT |
1834 | +mongodb/2 |
1835 | +$ relation-get username |
1836 | +jim |
1837 | +</code></pre> |
1838 | + |
1839 | +<pre class="runnable"><code> |
1840 | +# Get all settings from a particular remote unit in a particular relation. |
1841 | +$ echo $JUJU_RELATION_ID |
1842 | + |
1843 | +$ relation-get -r database:7 - mongodb/5 |
1844 | +username: bob |
1845 | +password: 2db673e81ffa264c |
1846 | +</code></pre> |
1847 | + |
1848 | +<p>Note that <code>relation-get</code> produces results that are <em>consistent</em> |
1849 | +but not necessarily <em>accurate</em>, in that you will always see settings that:</p> |
1850 | +<ul> |
1851 | + <li>were accurate at some point in the reasonably recent past |
1852 | + <li>are always the same within a single hook run... |
1853 | + <li class=" sub"><em>except</em> when inspecting the unit's own relation settings, |
1854 | + in which case local changes from <code>relation-set</code> will be seen correctly.</li> |
1855 | +</ul> |
1856 | +<p>You should never depend upon the presence of any given key in <code>relation-get</code> |
1857 | +output. Processing that depends on specific values (other than |
1858 | +<code>private-addres</code>) should be restricted to -changed hooks for the relevant |
1859 | +unit, and the absence of a remote unit's value should never be treated as an |
1860 | +<a href="./authors-hook-errors.html">error</a> in the local unit.</p> |
1861 | + |
1862 | +<p>In practice, it is common and encouraged for -relation-changed hooks to exit |
1863 | +early, without error, after inspecting <code>relation-get</code> output and |
1864 | +determining it to be inadequate; and for <a href="./authors-hook-kinds.html">all |
1865 | +other hooks</a> to be resilient in the face of missing keys, such that |
1866 | +-relation-changed hooks will be sufficient to complete all configuration that |
1867 | +depends on remote unit settings.</p> |
1868 | + |
1869 | +<p>Settings for remote units already known to have departed remain accessible |
1870 | +for the lifetime of the relation.</p> |
1871 | + |
1872 | +<p><code>relation-get</code> currently has a |
1873 | +<a href="https://bugs.launchpad.net/juju-core/+bug/1223339">bug</a> that allows units |
1874 | +of the same service to see each other's settings outside of a peer relation. Depending |
1875 | +on this behaviour is foolish in the extreme: if you need to share settings between |
1876 | +units of the same service, always use a peer relation to do so, or you may be |
1877 | +seriously inconvenienced when the hole is closed without notice.</p> |
1878 | + |
1879 | +</section> |
1880 | + |
1881 | +<section id="relation-list"> |
1882 | +<h3>relation-list</h3> |
1883 | + |
1884 | +<p><code>relation-list</code> accepts the <code>-r</code> flag as above, and |
1885 | +outputs the names of every remote unit currently known to be in the relation.</p> |
1886 | + |
1887 | +<pre class="runnable"><code> |
1888 | +# Show all remote units in the current relation. |
1889 | +$ echo $JUJU_RELATION_ID |
1890 | +db:1 |
1891 | +$ relation-list |
1892 | +mongodb/0 |
1893 | +mongodb/2 |
1894 | +mongodb/3 |
1895 | +</code></pre> |
1896 | + |
1897 | +<pre class="runnable"><code> |
1898 | +# Show all remote units in a specific relation. |
1899 | +$ echo $JUJU_RELATION_ID |
1900 | + |
1901 | +$ relation-list -r website:2 |
1902 | +haproxy/0 |
1903 | +</code></pre> |
1904 | + |
1905 | +</section> |
1906 | + |
1907 | +<section id="relation-ids"> |
1908 | +<h3>relation-ids</h3> |
1909 | + |
1910 | +<p><code>relation-ids</code> accepts a single argument which, in a relation |
1911 | +hook, defaults to the name of the current relation.</p> |
1912 | + |
1913 | +<pre class="runnable"><code> |
1914 | +# Show all relations like the current one. |
1915 | +$ echo $JUJU_RELATION |
1916 | +server |
1917 | +$ relation-ids |
1918 | +server:1 |
1919 | +server:7 |
1920 | +server:9 |
1921 | +</code></pre> |
1922 | + |
1923 | +<pre class="runnable"><code> |
1924 | +# Show all relations with the given name. |
1925 | +$ echo $JUJU_RELATION_ID |
1926 | + |
1927 | +$ relation-ids reverseproxy |
1928 | +reverseproxy:3 |
1929 | +</code></pre> |
1930 | + |
1931 | +<p>Note again that all commands that produce output accept <code>--format json</code> |
1932 | +and <code>--format yaml</code>, and you may consider it smarter to use those for |
1933 | +clarity's sake than to depend on the default <code>smart</code> format. |
1934 | +</section> |
1935 | + |
1936 | + |
1937 | + </article> |
1938 | + </div> |
1939 | + </div> |
1940 | + </section> |
1941 | + <div class="shadow"></div> |
1942 | + <footer class="global clearfix" role="contentinfo"> |
1943 | + <div class="row"> |
1944 | + <div class="inner-wrapper"> |
1945 | + <nav role="navigation" class="clearfix"> |
1946 | + <ul class="footer-a"> |
1947 | + <li class="grid-3 first-col"> |
1948 | + <h4><a href="/get-started">Get started</a></h4> |
1949 | + <ul> |
1950 | + <li class="page_item page-item-20"><a href="https://juju.ubuntu.com/get-started/local/">Local</a></li> |
1951 | + <li class="page_item page-item-22"><a href="https://juju.ubuntu.com/get-started/amazon/">Amazon Web Services</a></li> |
1952 | + <li class="page_item page-item-18"><a href="https://juju.ubuntu.com/get-started/hp-cloud/">HP Cloud</a></li> |
1953 | + <li class="page_item page-item-16"><a href="https://juju.ubuntu.com/get-started/rackspace/">Rackspace</a></li> |
1954 | + <li class="page_item page-item-3596"><a href="https://juju.ubuntu.com/get-started/openstack/">Openstack</a></li> |
1955 | + <li class="page_item page-item-3600"><a href="https://juju.ubuntu.com/get-started/maas/">MAAS</a></li> |
1956 | + </ul> |
1957 | + </li> |
1958 | + <li class="grid-3"> |
1959 | + <h4><a href="/resources">Resources</a></h4> |
1960 | + <ul> |
1961 | + <li><a href="http://juju.ubuntu.com/docs">Documentation</a></li> |
1962 | + <li><a href="/resources/videos/">Videos</a></li> |
1963 | + <li><a href="http://uistage.jujucharms.com:8080/">Juju GUI demo site</a></li> |
1964 | + </ul> |
1965 | + </li> |
1966 | + <li class="grid-3"> |
1967 | + <h4><a href="/community">Community</a></h4> |
1968 | + <ul> |
1969 | + <li class="page_item page-item-28"><a href="https://juju.ubuntu.com/community/juju-blog/">Juju Blog</a></li> |
1970 | + <li class="page_item page-item-4262"><a href="https://juju.ubuntu.com/community/weekly-charm-meeting/">Weekly Charm Meeting</a></li> |
1971 | + <li class="page_item page-item-4036"><a href="https://juju.ubuntu.com/community/charmers/">Charmers</a></li> |
1972 | + <li><a href="https://lists.ubuntu.com/mailman/listinfo/juju">Mailing List</a></li> |
1973 | + <li><a href="http://webchat.freenode.net/?channels=juju">Chat</a></li> |
1974 | + <li><a href="http://askubuntu.com/questions/tagged/juju?sort=faq&pagesize=50">FAQ</a></li> |
1975 | + </ul> |
1976 | + </li> |
1977 | + <li class="grid-3 last-col"> |
1978 | + <h4><a href="https://launchpad.net/juju">Code</a></h4> |
1979 | + <ul> |
1980 | + <li><a href="https://launchpad.net/juju-core">Juju Core</a></li> |
1981 | + <li><a href="https://launchpad.net/charms">Charms</a></li> |
1982 | + </ul> |
1983 | + </li> |
1984 | + </ul> |
1985 | + </nav> |
1986 | + </div> |
1987 | + </div> |
1988 | + <div class="row no-border"> |
1989 | + <div class="legal inner-wrapper"> |
1990 | + <p>© 2013 Canonical Ltd. Ubuntu and Canonical are registered trademarks of Canonical Ltd.</p> |
1991 | + <p><a href="https://bugs.launchpad.net/juju-website/+filebug">Report a bug on this site</a></p> |
1992 | + </div> |
1993 | + </div> |
1994 | +</footer> |
1995 | + |
1996 | + <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script> |
1997 | + <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jqueryui/1.8.14/jquery-ui.min.js"></script> |
1998 | + <script src="//d38yea5fb4e2oh.cloudfront.net/jquery.stacktack.min.js"></script> |
1999 | + <script type="text/javascript" src="js/main.js"></script> |
2000 | + <script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.js"></script> |
2001 | + </body> |
2002 | +</html> |
2003 | + |
2004 | |
2005 | === added file 'htmldocs/authors-hook-errors.html' |
2006 | --- htmldocs/authors-hook-errors.html 1970-01-01 00:00:00 +0000 |
2007 | +++ htmldocs/authors-hook-errors.html 2013-09-11 07:54:25 +0000 |
2008 | @@ -0,0 +1,194 @@ |
2009 | +<!DOCTYPE html> |
2010 | +<html> |
2011 | + <head> |
2012 | + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> |
2013 | + <title>Juju Documentation - Hook Errors</title> |
2014 | + <link href='https://fonts.googleapis.com/css?family=Ubuntu:400,300,300italic,400italic,700,700italic|Ubuntu+Mono' rel='stylesheet' type='text/css' /> |
2015 | + <link rel="stylesheet" type="text/css" media="screen" href="//juju.ubuntu.com/wp-content/themes/juju-website/css/reset.css" /> |
2016 | + <link rel="stylesheet" type="text/css" media="screen" href="//juju.ubuntu.com/wp-content/themes/juju-website/css/960.css" /> |
2017 | + <link rel="stylesheet" type="text/css" media="screen" href="//juju.ubuntu.com/wp-content/themes/juju-website/css/base.css" /> |
2018 | + <link rel="stylesheet" type="text/css" media="screen" href="//juju.ubuntu.com/wp-content/themes/juju-website/css/home-new.css" /> |
2019 | + <link rel='stylesheet' id='stacktack-css' href='//juju.ubuntu.com/wp-content/plugins/stacktack/css/stacktack.min.css?ver=3.4.2' type='text/css' media='all' /> |
2020 | + <link href="css/main.css?1375975745" rel="stylesheet" type="text/css"/> |
2021 | + |
2022 | + <!--[if lt IE 9]> |
2023 | + <script type="text/javascript" src="//html5shim.googlecode.com/svn/trunk/html5.js"></script> |
2024 | + <![endif]--> |
2025 | +</head> |
2026 | + <body class="resources"> |
2027 | + <header class="global clearfix" role="banner"> |
2028 | + <div class="header-navigation"> |
2029 | + <div> |
2030 | + <nav role="navigation"> |
2031 | + <ul> |
2032 | + <li class="page_item page-item-6"><a href="https://juju.ubuntu.com/">Home</a></li> |
2033 | + <li class="page_item page-item-7"><a href="https://juju.ubuntu.com/get-started/">Get started</a></li> |
2034 | + <li class="page_item page-item-9 current_page_item"><a href="https://juju.ubuntu.com/resources/">Resources</a></li> |
2035 | + <li class="page_item page-item-13"><a href="https://juju.ubuntu.com/community/">Community</a></li> |
2036 | + <li class="page_item page-item-3688"><a href="https://juju.ubuntu.com/charm-store/">Charm Store</a></li> |
2037 | + <li class="page_item page-item-3691"><a href="https://juju.ubuntu.com/events/">Events</a></li> |
2038 | + <li class="page_item page-item-4474"><a href="https://juju.ubuntu.com/charm-championship/">Charm Championship</a></li> |
2039 | + <li class="page_item page-item-4249"><a href="https://juju.ubuntu.com/survey/">Survey</a></li> |
2040 | + <li> |
2041 | + <form id="form-search" method="get" action="https://juju.ubuntu.com/"> |
2042 | + <fieldset> |
2043 | + <input id="input-search" type="text" name="s" value="Search" /> |
2044 | + </fieldset> |
2045 | + </form> |
2046 | + </li> |
2047 | + </ul> |
2048 | + </nav> |
2049 | + </div> |
2050 | + </div> |
2051 | + <div class="header-content"> |
2052 | + <div class="clearfix"> |
2053 | + <img src="https://juju.ubuntu.com/wp-content/themes/juju-website/img/arrow-nav.png" width="9" height="5" style="left:455px; display: block;" class="arrow-nav"> |
2054 | + <div class="header-navigation-secondary"></div> |
2055 | + <div class="header-image"></div> |
2056 | + <h1>Resources</h1> |
2057 | + <h2>A collection of some of the most important online references for Juju users and developers.</h2> |
2058 | + </div> |
2059 | + </div> |
2060 | +</header> |
2061 | + |
2062 | + <section id="content" class="container-12"> |
2063 | + <div class="grid-12 doc-container"> |
2064 | + <div id="navlinks" class="grid-3 doc-navigation">LINKS</div> |
2065 | + <div class="grid-9 doc-content"> |
2066 | + <article> |
2067 | + |
2068 | + |
2069 | +<section id="hook-errors"> |
2070 | +<h1>Hook errors</h1> |
2071 | + |
2072 | +<p>If any of your hooks returns a non-zero exit code, juju will stop managing the |
2073 | +unit directly and will wait for user intervention. This is a Bad Thing, and you |
2074 | +should make every effort to avoid it, because the average user may not be in a |
2075 | +position to diagnose the fault with any great degree of sophistication.</p> |
2076 | + |
2077 | +<p>So, in general, you should write your hooks as robustly as possible: if an |
2078 | +operation suffers a possibly-transient failure, it's wise to wait a moment and |
2079 | +retry a couple of times, to avoid needlessly bothering the user with a decision |
2080 | +or call to action that they're not necessarily equipped to make.</p> |
2081 | + |
2082 | +<p>However, you will no doubt encounter errors on occasion -- in particular, if |
2083 | +the unit agent is aborted while it's running a hook, it'll set an error status |
2084 | +for that hook when it comes back up. You will in that case have to deal with |
2085 | +users' potentially underinformed responses to those errors.</p> |
2086 | +</section> |
2087 | + |
2088 | +<section id="error-status"> |
2089 | +<h2>Error status</h2> |
2090 | + |
2091 | +<p>When a unit agent sets an error status, it stops running hooks and relinquishes |
2092 | +control over the charm directory. This means that it's generally safe to |
2093 | +<code>juju ssh</code> into the unit and use it as though you were the sole |
2094 | +administrator; juju will only take back control of the directory when explicitly |
2095 | +requested, in response to either <code>juju resolved</code> or |
2096 | +<code>juju upgrade-charm --force</code>. |
2097 | +<ul> |
2098 | + <li><code>juju resolved</code> causes the unit to unblock itself and continue |
2099 | + as though the hook had completed successfuly. The ideal charm will be aware of |
2100 | + this possibility and will therefore trust information from its |
2101 | + <a href="./authors-hook-environment.html">environment</a> to be more recent and |
2102 | + correct than anything it may have previously have recorded in the local |
2103 | + <a href="./authors-charm-contents.html">charm directory</a>.</li> |
2104 | + |
2105 | + <li><code>juju resolved --retry</code> reverts the charm directory's contents |
2106 | + to whatever they were at the start of the failed hook, and runs the hook again |
2107 | + exactly as before. This, in combination with the |
2108 | + <a href="./authors-hook-debug.html">debug-hooks</a> command, is your main entry |
2109 | + point for investigating an error in detail. If the hook fails again when retried, |
2110 | + it will set an error as before and wait again for user resolution.</li> |
2111 | + |
2112 | + <li><code>juju upgrade-charm --force</code> merges into the charm directory the |
2113 | + contents of the newer charm version, and continues blocking in the original hook |
2114 | + error state. Each time a new upgrade is forced, the charm directory is rolled |
2115 | + back to the state from which it was originally upgraded before proceeding; this |
2116 | + means that a forced upgrade back to the original charm will always be a no-op, |
2117 | + regardless of what other upgrade attempts have been made in the interim.</li> |
2118 | +</ul> |
2119 | +<p>Once you have issued one of the above commands, the charm directory should |
2120 | +once again be treated as inaccessible.</p> |
2121 | +</section> |
2122 | + |
2123 | +<section id="upgrade-errors"> |
2124 | +<h2>Charm upgrade errors</h2> |
2125 | + |
2126 | +<p>Finally, there's another reason a unit might set an error status: a |
2127 | +<a href="./authors-charm-upgrades.html">charm upgrade</a> conflict, which |
2128 | +should never happen except during development.</p> |
2129 | + |
2130 | +<p>They can be resolved either by forcing an upgrade to a different charm version, |
2131 | +or by manually resolving the git conflicts in the charm directory and running |
2132 | +<code>juju resolved</code> to cause the unit agent to continue.</p> |
2133 | +</section> |
2134 | + |
2135 | + |
2136 | + </article> |
2137 | + </div> |
2138 | + </div> |
2139 | + </section> |
2140 | + <div class="shadow"></div> |
2141 | + <footer class="global clearfix" role="contentinfo"> |
2142 | + <div class="row"> |
2143 | + <div class="inner-wrapper"> |
2144 | + <nav role="navigation" class="clearfix"> |
2145 | + <ul class="footer-a"> |
2146 | + <li class="grid-3 first-col"> |
2147 | + <h4><a href="/get-started">Get started</a></h4> |
2148 | + <ul> |
2149 | + <li class="page_item page-item-20"><a href="https://juju.ubuntu.com/get-started/local/">Local</a></li> |
2150 | + <li class="page_item page-item-22"><a href="https://juju.ubuntu.com/get-started/amazon/">Amazon Web Services</a></li> |
2151 | + <li class="page_item page-item-18"><a href="https://juju.ubuntu.com/get-started/hp-cloud/">HP Cloud</a></li> |
2152 | + <li class="page_item page-item-16"><a href="https://juju.ubuntu.com/get-started/rackspace/">Rackspace</a></li> |
2153 | + <li class="page_item page-item-3596"><a href="https://juju.ubuntu.com/get-started/openstack/">Openstack</a></li> |
2154 | + <li class="page_item page-item-3600"><a href="https://juju.ubuntu.com/get-started/maas/">MAAS</a></li> |
2155 | + </ul> |
2156 | + </li> |
2157 | + <li class="grid-3"> |
2158 | + <h4><a href="/resources">Resources</a></h4> |
2159 | + <ul> |
2160 | + <li><a href="http://juju.ubuntu.com/docs">Documentation</a></li> |
2161 | + <li><a href="/resources/videos/">Videos</a></li> |
2162 | + <li><a href="http://uistage.jujucharms.com:8080/">Juju GUI demo site</a></li> |
2163 | + </ul> |
2164 | + </li> |
2165 | + <li class="grid-3"> |
2166 | + <h4><a href="/community">Community</a></h4> |
2167 | + <ul> |
2168 | + <li class="page_item page-item-28"><a href="https://juju.ubuntu.com/community/juju-blog/">Juju Blog</a></li> |
2169 | + <li class="page_item page-item-4262"><a href="https://juju.ubuntu.com/community/weekly-charm-meeting/">Weekly Charm Meeting</a></li> |
2170 | + <li class="page_item page-item-4036"><a href="https://juju.ubuntu.com/community/charmers/">Charmers</a></li> |
2171 | + <li><a href="https://lists.ubuntu.com/mailman/listinfo/juju">Mailing List</a></li> |
2172 | + <li><a href="http://webchat.freenode.net/?channels=juju">Chat</a></li> |
2173 | + <li><a href="http://askubuntu.com/questions/tagged/juju?sort=faq&pagesize=50">FAQ</a></li> |
2174 | + </ul> |
2175 | + </li> |
2176 | + <li class="grid-3 last-col"> |
2177 | + <h4><a href="https://launchpad.net/juju">Code</a></h4> |
2178 | + <ul> |
2179 | + <li><a href="https://launchpad.net/juju-core">Juju Core</a></li> |
2180 | + <li><a href="https://launchpad.net/charms">Charms</a></li> |
2181 | + </ul> |
2182 | + </li> |
2183 | + </ul> |
2184 | + </nav> |
2185 | + </div> |
2186 | + </div> |
2187 | + <div class="row no-border"> |
2188 | + <div class="legal inner-wrapper"> |
2189 | + <p>© 2013 Canonical Ltd. Ubuntu and Canonical are registered trademarks of Canonical Ltd.</p> |
2190 | + <p><a href="https://bugs.launchpad.net/juju-website/+filebug">Report a bug on this site</a></p> |
2191 | + </div> |
2192 | + </div> |
2193 | +</footer> |
2194 | + |
2195 | + <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script> |
2196 | + <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jqueryui/1.8.14/jquery-ui.min.js"></script> |
2197 | + <script src="//d38yea5fb4e2oh.cloudfront.net/jquery.stacktack.min.js"></script> |
2198 | + <script type="text/javascript" src="js/main.js"></script> |
2199 | + <script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.js"></script> |
2200 | + </body> |
2201 | +</html> |
2202 | + |
2203 | |
2204 | === added file 'htmldocs/authors-hook-kinds.html' |
2205 | --- htmldocs/authors-hook-kinds.html 1970-01-01 00:00:00 +0000 |
2206 | +++ htmldocs/authors-hook-kinds.html 2013-09-11 07:54:25 +0000 |
2207 | @@ -0,0 +1,375 @@ |
2208 | + |
2209 | +<!DOCTYPE html> |
2210 | +<html> |
2211 | + <head> |
2212 | + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> |
2213 | + <title>Juju Documentation - Hook Kinds</title> |
2214 | + <link href='https://fonts.googleapis.com/css?family=Ubuntu:400,300,300italic,400italic,700,700italic|Ubuntu+Mono' rel='stylesheet' type='text/css' /> |
2215 | + <link rel="stylesheet" type="text/css" media="screen" href="//juju.ubuntu.com/wp-content/themes/juju-website/css/reset.css" /> |
2216 | + <link rel="stylesheet" type="text/css" media="screen" href="//juju.ubuntu.com/wp-content/themes/juju-website/css/960.css" /> |
2217 | + <link rel="stylesheet" type="text/css" media="screen" href="//juju.ubuntu.com/wp-content/themes/juju-website/css/base.css" /> |
2218 | + <link rel="stylesheet" type="text/css" media="screen" href="//juju.ubuntu.com/wp-content/themes/juju-website/css/home-new.css" /> |
2219 | + <link rel='stylesheet' id='stacktack-css' href='//juju.ubuntu.com/wp-content/plugins/stacktack/css/stacktack.min.css?ver=3.4.2' type='text/css' media='all' /> |
2220 | + <link href="css/main.css?1375975745" rel="stylesheet" type="text/css"/> |
2221 | + |
2222 | + <!--[if lt IE 9]> |
2223 | + <script type="text/javascript" src="//html5shim.googlecode.com/svn/trunk/html5.js"></script> |
2224 | + <![endif]--> |
2225 | +</head> |
2226 | + <body class="resources"> |
2227 | + <header class="global clearfix" role="banner"> |
2228 | + <div class="header-navigation"> |
2229 | + <div> |
2230 | + <nav role="navigation"> |
2231 | + <ul> |
2232 | + <li class="page_item page-item-6"><a href="https://juju.ubuntu.com/">Home</a></li> |
2233 | + <li class="page_item page-item-7"><a href="https://juju.ubuntu.com/get-started/">Get started</a></li> |
2234 | + <li class="page_item page-item-9 current_page_item"><a href="https://juju.ubuntu.com/resources/">Resources</a></li> |
2235 | + <li class="page_item page-item-13"><a href="https://juju.ubuntu.com/community/">Community</a></li> |
2236 | + <li class="page_item page-item-3688"><a href="https://juju.ubuntu.com/charm-store/">Charm Store</a></li> |
2237 | + <li class="page_item page-item-3691"><a href="https://juju.ubuntu.com/events/">Events</a></li> |
2238 | + <li class="page_item page-item-4474"><a href="https://juju.ubuntu.com/charm-championship/">Charm Championship</a></li> |
2239 | + <li class="page_item page-item-4249"><a href="https://juju.ubuntu.com/survey/">Survey</a></li> |
2240 | + <li> |
2241 | + <form id="form-search" method="get" action="https://juju.ubuntu.com/"> |
2242 | + <fieldset> |
2243 | + <input id="input-search" type="text" name="s" value="Search" /> |
2244 | + </fieldset> |
2245 | + </form> |
2246 | + </li> |
2247 | + </ul> |
2248 | + </nav> |
2249 | + </div> |
2250 | + </div> |
2251 | + <div class="header-content"> |
2252 | + <div class="clearfix"> |
2253 | + <img src="https://juju.ubuntu.com/wp-content/themes/juju-website/img/arrow-nav.png" width="9" height="5" style="left:455px; display: block;" class="arrow-nav"> |
2254 | + <div class="header-navigation-secondary"></div> |
2255 | + <div class="header-image"></div> |
2256 | + <h1>Resources</h1> |
2257 | + <h2>A collection of some of the most important online references for Juju users and developers.</h2> |
2258 | + </div> |
2259 | + </div> |
2260 | +</header> |
2261 | + |
2262 | + <section id="content" class="container-12"> |
2263 | + <div class="grid-12 doc-container"> |
2264 | + <div id="navlinks" class="grid-3 doc-navigation">LINKS</div> |
2265 | + <div class="grid-9 doc-content"> |
2266 | + <article> |
2267 | + |
2268 | + |
2269 | +<section id="charm-hooks"> |
2270 | +<h1>Charm hooks</h1> |
2271 | + |
2272 | +<p>A service unit's direct action is entirely defined by its charm's hooks. Hooks |
2273 | +are executable files in a charm's <code>hooks</code> directory; hooks with particular |
2274 | +names will be invoked by the juju unit agent at particular times, and thereby cause |
2275 | +changes to the world.</p> |
2276 | + |
2277 | +<p>Whenever a hook-worthy event takes place, the unit agent first checks whether |
2278 | +that hook is being <a href="./authors-hook-debug.html">debugged</a>, and if so |
2279 | +hands over control to the user. Otherwise, it tries to find a hook with precisely |
2280 | +the right name. If the hook doesn't exist, the agent continues without complaint; |
2281 | +if it does, it is invoked without arguments in a specific |
2282 | +<a href="./authors-hook-environment.html">environment</a>, and its output is written |
2283 | +to the unit agent's log. If it returns a non-zero exit code, the agent enters an |
2284 | +<a href="./authors-hook-errors.html">error state</a> and awaits user intervention; |
2285 | +otherwise the unit agent continues to run further hooks as they become appropriate.</p> |
2286 | + |
2287 | +<p>The agent will also enter an error state if the unit agent process is aborted |
2288 | +during hook execution.</p> |
2289 | +</section> |
2290 | + |
2291 | +<section id="hook-kinds"> |
2292 | +<h2>Hook kinds</h2> |
2293 | + |
2294 | +<p>There are 5 "unit hooks" with predefined names that can be implemented |
2295 | +by any charm:</p> |
2296 | +<ul> |
2297 | + <li>install</li> |
2298 | + <li>config-changed</li> |
2299 | + <li>start</li> |
2300 | + <li>upgrade-charm</li> |
2301 | + <li>stop</li> |
2302 | +</ul> |
2303 | + |
2304 | +<p>For every relation defined by a charm, an additional 4 "relation hooks" |
2305 | +can be implemented, named after the charm relation:</p> |
2306 | +<ul> |
2307 | + <li><name>-relation-joined</li> |
2308 | + <li><name>-relation-changed</li> |
2309 | + <li><name>-relation-departed</li> |
2310 | + <li><name>-relation-broken</li> |
2311 | +</ul> |
2312 | +<p>None of the unit or relation hooks are required; if you don't implement a hook, |
2313 | +it just doesn't get run, except when debugging.</p> |
2314 | +</section> |
2315 | + |
2316 | +<section id="unit-hooks"> |
2317 | +<h2>Unit hooks</h2> |
2318 | + |
2319 | +<p>The unit hooks are run under the following circumstances.</p> |
2320 | +</section> |
2321 | + |
2322 | +<section id="hook-install"> |
2323 | +<h3>install</h3> |
2324 | + |
2325 | +<p><code>install</code> runs just once, before any other hook. It should be used to |
2326 | +perform one-time setup operations only.</p> |
2327 | +</section> |
2328 | + |
2329 | +<section id="hook-config-changed"> |
2330 | +<h3>config-changed</h3> |
2331 | + |
2332 | +<p><code>config-changed</code> runs in several different situations.</p> |
2333 | +<ul> |
2334 | + <li>immediately after "install"</li> |
2335 | + <li>immediately after "upgrade-charm"</li> |
2336 | + <li>at least once when the unit agent is restarted (but, if the unit is in |
2337 | + an <a href="./authors-hook-errors.html">error state</a>, it won't be run |
2338 | + until after the error state is cleared).</li> |
2339 | +</ul> |
2340 | +<p>It cannot assume that the software has already been started; it should not |
2341 | +start stopped software, but should (if appropriate) restart running software |
2342 | +to take configuration changes into account.</p> |
2343 | +</section> |
2344 | + |
2345 | +<section id="hook-start"> |
2346 | +<h3>start</h3> |
2347 | +<p><code>start</code> runs immediately after the first <code>config-changed</code> |
2348 | +hook. It should be used to ensure the charm's software is running. Note that the |
2349 | +charm's software should be configured so as to persist through reboots without further |
2350 | +intervention on juju's part. |
2351 | +</section> |
2352 | + |
2353 | +<section id="hook-upgrade-charm"> |
2354 | +<h3>upgrade-charm</h3> |
2355 | + |
2356 | +<p><code>upgrade-charm</code> runs immediately after any |
2357 | +<a href="./authors-charm-upgrades.html">upgrade</a> operation that does <em>not</em> |
2358 | +itself interrupt an existing <a href="./authors-hook-errors.html">error state.</a>. It |
2359 | +should be used to reconcile local state written by some other version of the charm into |
2360 | +whatever form it needs to take to be manipulated by the current version.</p> |
2361 | + |
2362 | +<p>While the forced upgrade functionality is intended as a developer tool, and is |
2363 | +not generally suitable for end users, it's somewhat optimistic to depend on the |
2364 | +functionality never being abused. In light of this, if you need to run an |
2365 | +<code>upgrade-charm</code> hook before your other hooks will work correctly, |
2366 | +it may be wise to preface all your other hooks with a quick call to your |
2367 | +(idempotent)<code>upgrade-charm</code>.</p> |
2368 | +</section> |
2369 | + |
2370 | +<section id="hook-stop"> |
2371 | +<h3>stop</h3> |
2372 | + |
2373 | +<p><code>stop</code> runs immediately before the end of the unit's destruction |
2374 | +sequence. It should be used to ensure that the charm's software is not running, and |
2375 | +will not start again on reboot.</p> |
2376 | +</section> |
2377 | + |
2378 | +<section id="relation-hooks"> |
2379 | +<h2>Relation hooks</h2> |
2380 | + |
2381 | +<p>Units will only participate in relations after they're been started, and before |
2382 | +they've been stopped. Within that time window, the unit may participate in several |
2383 | +different relations at a time, <em>including</em> multiple relations with the |
2384 | +same name.</p> |
2385 | + |
2386 | +<p>To illustrate, consider a database service that will be used by multiple client |
2387 | +services. Units of a single client service will surely want to connect to, and |
2388 | +use, the same database; but if units of another client service were to use that |
2389 | +same database, the consequences could be catastrophic for all concerned.</p> |
2390 | + |
2391 | +<p>If juju respected the <code>limit</code> field in relation |
2392 | +<a href="./authors-charm-metadata.html">metadata</a>, it would be possible |
2393 | +to work around this, but it's not a high-priority |
2394 | +<a href="https://bugs.launchpad.net/bugs/1089297">bug</a>: most provider services |
2395 | +<em>should</em> be able to handle multiple requirers anyway; and most requirers will |
2396 | +only be connected to one provider anyway.</p> |
2397 | + |
2398 | +<p>When a unit running a given charm participates in a given relation, it runs at |
2399 | +least three hooks for every remote unit it becomes aware of in that relation.</p> |
2400 | +</section> |
2401 | + |
2402 | +<section id="hook-relation-joined"> |
2403 | +<h3><name>-relation-joined</h3> |
2404 | + |
2405 | +<p><code><name>-relation-joined</code> is run once only, when that remote |
2406 | +unit is first observed by the unit. It should be used to <code>relation-set</code> any |
2407 | +local unit settings that can be determined using no more than the name of the joining |
2408 | +unit and the remote <code>private-address</code> setting, which is always available |
2409 | +when the relation is created and is by convention not deleted.</p> |
2410 | + |
2411 | +<p>You should not depend upon any other relation settings in the -joined hook |
2412 | +because they're not guaranteed to be present; if you need more information |
2413 | +you should wait for a -changed hook that presents the right information.</p> |
2414 | +</section> |
2415 | + |
2416 | +<section id="hook-relation-changed"> |
2417 | +<h3><name>-relation-changed</h3> |
2418 | + |
2419 | +<p><code><name>-relation-changed</code> is always run once, after -joined, and |
2420 | +will subsequently be run whenever that remote unit changes its settings for the |
2421 | +relation. It should be the <em>only</em> hook that <em>relies</em> upon remote relation |
2422 | +settings from <code>relation-get</code>, and it should <em>not</em> error if the |
2423 | +settings are incomplete: you can guarantee that when the remote unit changes its |
2424 | +settings, the hook will be run again.</p> |
2425 | + |
2426 | +<p>The settings that you can get, and that you should set, are determined by |
2427 | +the relation's <a href="./authors-charm-interfaces.html">interface</a>.</p> |
2428 | +</section> |
2429 | + |
2430 | +<section id="hook-relation-departed"> |
2431 | +<h3><name>-relation-departed</h3> |
2432 | + |
2433 | +<p><code><name>-relation-departed</code> is run once only, when the remote unit |
2434 | +is known to be leaving the relation; it will only run once at least one -changed has |
2435 | +been run, and after -departed has run, no further -changeds will be run. This should |
2436 | +be used to remove all references to the remote unit, because there's no guarantee that |
2437 | +it's still part of the system; it's perfectly probable (although not guaranteed) that |
2438 | +the system running that unit has already shut down.</p> |
2439 | + |
2440 | +<p>When a unit's own participation in a relation is known to be ending, the unit |
2441 | +agent continues to uphold the ordering guarantees above; but within those |
2442 | +constraints, it will run the fewest possible hooks to notify the charm of the |
2443 | +departure of each individual remote unit.</p> |
2444 | + |
2445 | +<p>Once all necessary -departed hooks have been run for such a relation, the unit |
2446 | +agent will run the final relation hook:</p> |
2447 | +</section> |
2448 | + |
2449 | +<section id="hook-relation-broken"> |
2450 | +<h3><name>-relation-broken</h3> |
2451 | + |
2452 | +<p><code><name>-relation-broken</code> indicates that the current relation is |
2453 | +no longer valid, and that the charm's software must be configured as though the |
2454 | +relation had never existed. It will only be called after every necessary -departed |
2455 | +hook has been run; if it's being executed, you can be sure that no remote units are |
2456 | +currently known locally.</p> |
2457 | + |
2458 | +<p>It is important to note that the -broken hook might run even if no other units |
2459 | +have ever joined the relation. This is not a bug: even if no remote units have ever |
2460 | +joined, the fact of the unit's participation can be detected in other hooks via the |
2461 | +<code>relation-ids</code> tool, and the -broken hook needs to execute to give the |
2462 | +charm an opportunity to clean up any optimistically-generated configuration.</p> |
2463 | + |
2464 | +<p>And, again, it's important to internalise the fact that there may be multiple |
2465 | +runtime relations in play with the same name, and that they're independent: |
2466 | +one -broken hook does not mean that <em>every</em> such relation is broken.</p> |
2467 | +</section> |
2468 | + |
2469 | +<section id="writing-hooks"> |
2470 | +<h2>Writing hooks</h2> |
2471 | + |
2472 | +<p>If you follow the <a href="./authors-charm-writing.html">tutorial</a>, you'll |
2473 | +get a good sense of the basics. To fill out your knowledge, you'll want to study |
2474 | +the hook <a href="./authors-hook-environment.html">environment and tools</a>, and |
2475 | +to experiment with <a href="./authors-hook-debug.html">debug-hooks</a>.</p> |
2476 | + |
2477 | +<p>Independent of the nuts and bolts, though, good hooks display a number of |
2478 | +useful high-level properties:</p> |
2479 | +<ul> |
2480 | + <li>They are <em>idempotent</em>: that is to say that there should be no |
2481 | + observable difference between running a hook once, and running it N times |
2482 | + in a row. If this property does not hold, you are likely to be making your |
2483 | + own life unnecesarily difficult: apart from anything else, the average user's |
2484 | + most likely first response to a failed hook will be to try to run it again |
2485 | + (if they don't just skip it).</li> |
2486 | + |
2487 | + <li>They are <em>easy to read</em> and understand. It's tempting to write a |
2488 | + single file that does everything, and which just calls different functions |
2489 | + internally depending on the value of <code>argv[0]</code>, and to symlink that |
2490 | + one file for every hook; but such structures quickly become unwieldy.<br /> |
2491 | + The time taken to write a library, separate from the hooks, is very likely |
2492 | + to be well spent: it lets you write single hooks that are clear and focused, |
2493 | + and insulates the maintainer from irrelevant details.</li> |
2494 | + |
2495 | + <li>Where possible, they reuse |
2496 | + <a href="https://launchpad.net/charm-tools">common code</a> already written to |
2497 | + ease or solve common use cases.</li> |
2498 | + |
2499 | + <li>They do not return <a href="./authors-hook-errors.html">errors</a> unless |
2500 | + there is a good reason to believe that they cannot be resolved without user |
2501 | + intervention. Doing so is an admission of defeat: a user who sees your charm |
2502 | + returning an error state is unlikely to have the specific expertise necessary |
2503 | + to resolve it. If you have to return an error, please be sure to at least write |
2504 | + any context you can to the log before you do so.</li> |
2505 | + |
2506 | + <li>They write only <em>very</em> sparingly to the |
2507 | + <a href="./authors-charm-contents.html">charm directory</a>.</li> |
2508 | +</ul> |
2509 | + |
2510 | +<p>We recommend you also familiarize yourself with the |
2511 | +<a href="./authors-charm-best-practice.html">best practices</a> and, if you |
2512 | +plan to distribute your charm, the |
2513 | +<a href="./authors-charm-policy.html">charm store policy</a>.</p> |
2514 | +</section> |
2515 | + |
2516 | + |
2517 | + </article> |
2518 | + </div> |
2519 | + </div> |
2520 | + </section> |
2521 | + <div class="shadow"></div> |
2522 | + <footer class="global clearfix" role="contentinfo"> |
2523 | + <div class="row"> |
2524 | + <div class="inner-wrapper"> |
2525 | + <nav role="navigation" class="clearfix"> |
2526 | + <ul class="footer-a"> |
2527 | + <li class="grid-3 first-col"> |
2528 | + <h4><a href="/get-started">Get started</a></h4> |
2529 | + <ul> |
2530 | + <li class="page_item page-item-20"><a href="https://juju.ubuntu.com/get-started/local/">Local</a></li> |
2531 | + <li class="page_item page-item-22"><a href="https://juju.ubuntu.com/get-started/amazon/">Amazon Web Services</a></li> |
2532 | + <li class="page_item page-item-18"><a href="https://juju.ubuntu.com/get-started/hp-cloud/">HP Cloud</a></li> |
2533 | + <li class="page_item page-item-16"><a href="https://juju.ubuntu.com/get-started/rackspace/">Rackspace</a></li> |
2534 | + <li class="page_item page-item-3596"><a href="https://juju.ubuntu.com/get-started/openstack/">Openstack</a></li> |
2535 | + <li class="page_item page-item-3600"><a href="https://juju.ubuntu.com/get-started/maas/">MAAS</a></li> |
2536 | + </ul> |
2537 | + </li> |
2538 | + <li class="grid-3"> |
2539 | + <h4><a href="/resources">Resources</a></h4> |
2540 | + <ul> |
2541 | + <li><a href="http://juju.ubuntu.com/docs">Documentation</a></li> |
2542 | + <li><a href="/resources/videos/">Videos</a></li> |
2543 | + <li><a href="http://uistage.jujucharms.com:8080/">Juju GUI demo site</a></li> |
2544 | + </ul> |
2545 | + </li> |
2546 | + <li class="grid-3"> |
2547 | + <h4><a href="/community">Community</a></h4> |
2548 | + <ul> |
2549 | + <li class="page_item page-item-28"><a href="https://juju.ubuntu.com/community/juju-blog/">Juju Blog</a></li> |
2550 | + <li class="page_item page-item-4262"><a href="https://juju.ubuntu.com/community/weekly-charm-meeting/">Weekly Charm Meeting</a></li> |
2551 | + <li class="page_item page-item-4036"><a href="https://juju.ubuntu.com/community/charmers/">Charmers</a></li> |
2552 | + <li><a href="https://lists.ubuntu.com/mailman/listinfo/juju">Mailing List</a></li> |
2553 | + <li><a href="http://webchat.freenode.net/?channels=juju">Chat</a></li> |
2554 | + <li><a href="http://askubuntu.com/questions/tagged/juju?sort=faq&pagesize=50">FAQ</a></li> |
2555 | + </ul> |
2556 | + </li> |
2557 | + <li class="grid-3 last-col"> |
2558 | + <h4><a href="https://launchpad.net/juju">Code</a></h4> |
2559 | + <ul> |
2560 | + <li><a href="https://launchpad.net/juju-core">Juju Core</a></li> |
2561 | + <li><a href="https://launchpad.net/charms">Charms</a></li> |
2562 | + </ul> |
2563 | + </li> |
2564 | + </ul> |
2565 | + </nav> |
2566 | + </div> |
2567 | + </div> |
2568 | + <div class="row no-border"> |
2569 | + <div class="legal inner-wrapper"> |
2570 | + <p>© 2013 Canonical Ltd. Ubuntu and Canonical are registered trademarks of Canonical Ltd.</p> |
2571 | + <p><a href="https://bugs.launchpad.net/juju-website/+filebug">Report a bug on this site</a></p> |
2572 | + </div> |
2573 | + </div> |
2574 | +</footer> |
2575 | + |
2576 | + <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script> |
2577 | + <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jqueryui/1.8.14/jquery-ui.min.js"></script> |
2578 | + <script src="//d38yea5fb4e2oh.cloudfront.net/jquery.stacktack.min.js"></script> |
2579 | + <script type="text/javascript" src="js/main.js"></script> |
2580 | + <script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.js"></script> |
2581 | + </body> |
2582 | +</html> |
2583 | |
2584 | === renamed file 'htmldocs/authors-hooks.html' => 'htmldocs/authors-hooks.html.THIS' |
2585 | === added file 'htmldocs/authors-relations-in-depth.html' |
2586 | --- htmldocs/authors-relations-in-depth.html 1970-01-01 00:00:00 +0000 |
2587 | +++ htmldocs/authors-relations-in-depth.html 2013-09-11 07:54:25 +0000 |
2588 | @@ -0,0 +1,159 @@ |
2589 | + |
2590 | +<!DOCTYPE html> |
2591 | +<html> |
2592 | + <head> |
2593 | + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> |
2594 | + <title>Juju Documentation - Relations in Depth</title> |
2595 | + <link href='https://fonts.googleapis.com/css?family=Ubuntu:400,300,300italic,400italic,700,700italic|Ubuntu+Mono' rel='stylesheet' type='text/css' /> |
2596 | + <link rel="stylesheet" type="text/css" media="screen" href="//juju.ubuntu.com/wp-content/themes/juju-website/css/reset.css" /> |
2597 | + <link rel="stylesheet" type="text/css" media="screen" href="//juju.ubuntu.com/wp-content/themes/juju-website/css/960.css" /> |
2598 | + <link rel="stylesheet" type="text/css" media="screen" href="//juju.ubuntu.com/wp-content/themes/juju-website/css/base.css" /> |
2599 | + <link rel="stylesheet" type="text/css" media="screen" href="//juju.ubuntu.com/wp-content/themes/juju-website/css/home-new.css" /> |
2600 | + <link rel='stylesheet' id='stacktack-css' href='//juju.ubuntu.com/wp-content/plugins/stacktack/css/stacktack.min.css?ver=3.4.2' type='text/css' media='all' /> |
2601 | + <link href="css/main.css?1375975745" rel="stylesheet" type="text/css"/> |
2602 | + |
2603 | + <!--[if lt IE 9]> |
2604 | + <script type="text/javascript" src="//html5shim.googlecode.com/svn/trunk/html5.js"></script> |
2605 | + <![endif]--> |
2606 | +</head> |
2607 | + <body class="resources"> |
2608 | + <header class="global clearfix" role="banner"> |
2609 | + <div class="header-navigation"> |
2610 | + <div> |
2611 | + <nav role="navigation"> |
2612 | + <ul> |
2613 | + <li class="page_item page-item-6"><a href="https://juju.ubuntu.com/">Home</a></li> |
2614 | + <li class="page_item page-item-7"><a href="https://juju.ubuntu.com/get-started/">Get started</a></li> |
2615 | + <li class="page_item page-item-9 current_page_item"><a href="https://juju.ubuntu.com/resources/">Resources</a></li> |
2616 | + <li class="page_item page-item-13"><a href="https://juju.ubuntu.com/community/">Community</a></li> |
2617 | + <li class="page_item page-item-3688"><a href="https://juju.ubuntu.com/charm-store/">Charm Store</a></li> |
2618 | + <li class="page_item page-item-3691"><a href="https://juju.ubuntu.com/events/">Events</a></li> |
2619 | + <li class="page_item page-item-4474"><a href="https://juju.ubuntu.com/charm-championship/">Charm Championship</a></li> |
2620 | + <li class="page_item page-item-4249"><a href="https://juju.ubuntu.com/survey/">Survey</a></li> |
2621 | + <li> |
2622 | + <form id="form-search" method="get" action="https://juju.ubuntu.com/"> |
2623 | + <fieldset> |
2624 | + <input id="input-search" type="text" name="s" value="Search" /> |
2625 | + </fieldset> |
2626 | + </form> |
2627 | + </li> |
2628 | + </ul> |
2629 | + </nav> |
2630 | + </div> |
2631 | + </div> |
2632 | + <div class="header-content"> |
2633 | + <div class="clearfix"> |
2634 | + <img src="https://juju.ubuntu.com/wp-content/themes/juju-website/img/arrow-nav.png" width="9" height="5" style="left:455px; display: block;" class="arrow-nav"> |
2635 | + <div class="header-navigation-secondary"></div> |
2636 | + <div class="header-image"></div> |
2637 | + <h1>Resources</h1> |
2638 | + <h2>A collection of some of the most important online references for Juju users and developers.</h2> |
2639 | + </div> |
2640 | + </div> |
2641 | +</header> |
2642 | + |
2643 | + <section id="content" class="container-12"> |
2644 | + <div class="grid-12 doc-container"> |
2645 | + <div id="navlinks" class="grid-3 doc-navigation">LINKS</div> |
2646 | + <div class="grid-9 doc-content"> |
2647 | + <article> |
2648 | + <section id="relations-in-depth"> |
2649 | + <h1>Relations in depth</h1> |
2650 | + |
2651 | + <p>A unit's <code>scope</code> consists of the group of units that are transitively connected to that unit within a particular relation. So, for a globally-scoped relation, that means every unit of each service in the relation; for a container-scoped relation, it means only those sets of units which are deployed alongside one another. That is to say: a globally-scoped relation has a single unit scope, whilst a container-scoped relation has one for each principal unit.</p> |
2652 | + <p>When a unit becomes aware that it is a member of a relation, its only self- directed action is to <code>join</code> its scope within that relation. This involves two steps:</p> |
2653 | + <ul> |
2654 | + <li>Write initial relation settings (just one value, <code>private-address</code>), to ensure that they will be available to observers before they're triggered by the next step;</li> |
2655 | + <li>Signal its existence, and role in the relation, to the rest of the system.</li> |
2656 | + </ul> |
2657 | + <p>The unit then starts observing and reacting to any other units in its scope which are playing a role in which it is interested. To be specific:</p> |
2658 | + <ul> |
2659 | + <li>Each provider unit observes every requirer unit</li> |
2660 | + <li>Each requirer unit observes every provider unit</li> |
2661 | + <li>Each peer unit observes every other peer unit</li> |
2662 | + </ul> |
2663 | + <p>Now, suppose that some unit as the very first unit to join the relation; and let's say it's a requirer. No provider units are present, so no hooks will fire. But, when a provider unit joins the relation, the requirer and provider become aware of each other almost simultaneously. (Similarly, the first two units in a peer relation become aware of each other almost simultaneously.)</p> |
2664 | + <p>So, concurrently, the units on each side of the relation run their relation-joined and relation-changed hooks with respect to their counterpart. The intent is that they communicate appropriate information to each other to set up some sort of connection, by using the relation-set and relation-get hook tools; but neither unit is safe to assume that any particular setting has yet been set by its counterpart.</p> |
2665 | + <p>This sounds kinda tricky to deal with, but merely requires suitable respect for the relation-get tool: it is important to realise that relation-get is never <em>guaranteed</em> to contain any values at all, because we have decided that it's perfectly legitimate for a unit to delete its own private-address value. But in normal circumstances, it's reasonable to treat <code>private-address</code> as guaranteed.</p> |
2666 | + <p>In one specific kind of hook, this is easy to deal with. A relation-changed hook can always exit without error when the current remote unit is missing data, because the hook is guaranteed to be run again when that data changes -- and, assuming the remote unit is running a charm that agrees on how to implement the interface, the data <em>will</em> change and the hook <em>will</em> be run again.</p> |
2667 | + <p>In <em>all</em> other cases -- unit hooks, relation hooks for a different relation, relation hooks for a different remote unit in the same relation, and even relation hooks other than -changed for the <em>same</em> remote unit -- there is no such guarantee. These hooks all run on their own schedule, and there is no reason to expect them to be re-run on a predictable schedule, or in some cases ever again.</p> |
2668 | + <p>This means that all such hooks need to be able to handle missing relation data, and to complete successfully; they mustn't fail, because the user is powerless to resolve the situation, and they can't even wait for state to change, because they all see their own sandboxed composite snapshot of fairly-recent state, which never changes.</p> |
2669 | + <p>So, outside a vey narrow range of circumstances, relation-get should be treated with particular care. The corresponding advice for relation-set is very simple by comparison: relation-set should be called early and often. Because the unit agent serializes hook execution, there is never any danger of concurrent changes to the data, and so a null setting change can be safely ignored, and will not cause other units to react.</p> |
2670 | + </section> |
2671 | + |
2672 | + <section id="relations-in-depth"> |
2673 | + <h2 id="departing-relations">Departing relations</h2> |
2674 | + <p>A unit will depart a relation when either the relation or the unit itself is marked for termination. In either case, it follows the same sequence:</p> |
2675 | + <ul> |
2676 | + <li>For every known related unit -- those which have joined and not yet departed -- run the relation-departed hook.</li> |
2677 | + <li>Run the relation-broken hook.</li> |
2678 | + <li><code>depart</code> from its scope in the relation.</li> |
2679 | + </ul> |
2680 | + <p>The unit's eventual departure from its scope will in turn be detected by units of the related service (if they have not already inferred its imminent departure by other means) and cause them to run relation-departed hooks. A unit's relation settings persist beyond its own departure from the relation; the final unit to depart a relation marked for termination is responsible for destroying the relation and all associated data.</p> |
2681 | + </section> |
2682 | + </article> |
2683 | + </div> |
2684 | + </div> |
2685 | + </section> |
2686 | + <div class="shadow"></div> |
2687 | + <footer class="global clearfix" role="contentinfo"> |
2688 | + <div class="row"> |
2689 | + <div class="inner-wrapper"> |
2690 | + <nav role="navigation" class="clearfix"> |
2691 | + <ul class="footer-a"> |
2692 | + <li class="grid-3 first-col"> |
2693 | + <h4><a href="/get-started">Get started</a></h4> |
2694 | + <ul> |
2695 | + <li class="page_item page-item-20"><a href="https://juju.ubuntu.com/get-started/local/">Local</a></li> |
2696 | + <li class="page_item page-item-22"><a href="https://juju.ubuntu.com/get-started/amazon/">Amazon Web Services</a></li> |
2697 | + <li class="page_item page-item-18"><a href="https://juju.ubuntu.com/get-started/hp-cloud/">HP Cloud</a></li> |
2698 | + <li class="page_item page-item-16"><a href="https://juju.ubuntu.com/get-started/rackspace/">Rackspace</a></li> |
2699 | + <li class="page_item page-item-3596"><a href="https://juju.ubuntu.com/get-started/openstack/">Openstack</a></li> |
2700 | + <li class="page_item page-item-3600"><a href="https://juju.ubuntu.com/get-started/maas/">MAAS</a></li> |
2701 | + </ul> |
2702 | + </li> |
2703 | + <li class="grid-3"> |
2704 | + <h4><a href="/resources">Resources</a></h4> |
2705 | + <ul> |
2706 | + <li><a href="http://juju.ubuntu.com/docs">Documentation</a></li> |
2707 | + <li><a href="/resources/videos/">Videos</a></li> |
2708 | + <li><a href="http://uistage.jujucharms.com:8080/">Juju GUI demo site</a></li> |
2709 | + </ul> |
2710 | + </li> |
2711 | + <li class="grid-3"> |
2712 | + <h4><a href="/community">Community</a></h4> |
2713 | + <ul> |
2714 | + <li class="page_item page-item-28"><a href="https://juju.ubuntu.com/community/juju-blog/">Juju Blog</a></li> |
2715 | + <li class="page_item page-item-4262"><a href="https://juju.ubuntu.com/community/weekly-charm-meeting/">Weekly Charm Meeting</a></li> |
2716 | + <li class="page_item page-item-4036"><a href="https://juju.ubuntu.com/community/charmers/">Charmers</a></li> |
2717 | + <li><a href="https://lists.ubuntu.com/mailman/listinfo/juju">Mailing List</a></li> |
2718 | + <li><a href="http://webchat.freenode.net/?channels=juju">Chat</a></li> |
2719 | + <li><a href="http://askubuntu.com/questions/tagged/juju?sort=faq&pagesize=50">FAQ</a></li> |
2720 | + </ul> |
2721 | + </li> |
2722 | + <li class="grid-3 last-col"> |
2723 | + <h4><a href="https://launchpad.net/juju">Code</a></h4> |
2724 | + <ul> |
2725 | + <li><a href="https://launchpad.net/juju-core">Juju Core</a></li> |
2726 | + <li><a href="https://launchpad.net/charms">Charms</a></li> |
2727 | + </ul> |
2728 | + </li> |
2729 | + </ul> |
2730 | + </nav> |
2731 | + </div> |
2732 | + </div> |
2733 | + <div class="row no-border"> |
2734 | + <div class="legal inner-wrapper"> |
2735 | + <p>© 2013 Canonical Ltd. Ubuntu and Canonical are registered trademarks of Canonical Ltd.</p> |
2736 | + <p><a href="https://bugs.launchpad.net/juju-website/+filebug">Report a bug on this site</a></p> |
2737 | + </div> |
2738 | + </div> |
2739 | +</footer> |
2740 | + |
2741 | + <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script> |
2742 | + <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jqueryui/1.8.14/jquery-ui.min.js"></script> |
2743 | + <script src="//d38yea5fb4e2oh.cloudfront.net/jquery.stacktack.min.js"></script> |
2744 | + <script type="text/javascript" src="js/main.js"></script> |
2745 | + <script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.js"></script> |
2746 | + </body> |
2747 | +</html> |
2748 | |
2749 | === renamed file 'htmldocs/authors-service-config.html' => 'htmldocs/authors-service-config.html.THIS' |
2750 | === modified file 'htmldocs/navigation.html' |
2751 | --- htmldocs/navigation.html 2013-09-05 12:01:47 +0000 |
2752 | +++ htmldocs/navigation.html 2013-09-11 07:54:25 +0000 |
2753 | @@ -24,18 +24,37 @@ |
2754 | <li class=" sub"><a href="howto-rails.html">Test and deploy on Rails</a></li> |
2755 | </ul> |
2756 | <h1>Charm Authors</h1> |
2757 | +<<<<<<< TREE |
2758 | <ul class="no-margin"> |
2759 | <li class=""><a href="authors-charm-anatomy.html">Anatomy of a charm</a></li> |
2760 | <li class=""><a href="authors-charm-writing.html">Writing a charm</a></li> |
2761 | +======= |
2762 | + <ul> |
2763 | + <li class=""><a href="authors-charm-contents.html">Charm Contents</a></li> |
2764 | + <li class=" sub"><a href="authors-charm-metadata.html">metadata.yaml</a></li> |
2765 | + <li class=" sub"><a href="authors-charm-config.html">config.yaml</a></li> |
2766 | + <li class=" sub"><a href="authors-hook-kinds.html">hooks</a></li> |
2767 | +>>>>>>> MERGE-SOURCE |
2768 | |
2769 | - <li class=" sub"><a href="authors-subordinate-services.html">Subordinate services</a></li> |
2770 | + <li class=""><a href="authors-charm-writing.html">Writing a Charm</a></li> |
2771 | + <li class=" sub"><a href="authors-hook-environment.html">Hook Environment</a></li> |
2772 | + <li class=" sub"><a href="authors-charm-interfaces.html">Relation Interfaces</a></li> |
2773 | + <li class=" sub"><a href="authors-relations-in-depth.html">Relations in Depth</a></li> |
2774 | + <li class=" sub"><a href="authors-testing.html">Charm Testing</a></li> |
2775 | + <li class=" sub"><a href="authors-hook-errors.html">Hook Errors</a></li> |
2776 | + <li class=" sub"><a href="authors-hook-debug.html">Hook Debugging</a></li> |
2777 | + <li class=" sub"><a href="authors-subordinate-services.html">Subordinate Services</a></li> |
2778 | <li class=" sub"><a href="authors-implicit-relations.html">Implicit Relations</a></li> |
2779 | +<<<<<<< TREE |
2780 | <li class=" sub"><a href="authors-testing.html">Charm Testing</a></li> |
2781 | <li class=" sub"><a href="authors-hooks.html">Hook debugging</a></li> |
2782 | <li class=" sub"><a href="authors-interfaces.html">Interfaces</a></li> |
2783 | <li class=" sub"><a href="authors-charms-in-action.html">Charms in action!</a></li> |
2784 | +======= |
2785 | + |
2786 | +>>>>>>> MERGE-SOURCE |
2787 | <li class=""><a href="authors-charm-store.html">The Juju Charm Store</a></li> |
2788 | - <li class=" sub"><a href="authors-charm-policy.html">Charm store policy</a></li> |
2789 | + <li class=" sub"><a href="authors-charm-policy.html">Charm Store Policy</a></li> |
2790 | <li class=" sub"><a href="authors-charm-best-practice.html">Best practices</a></li> |
2791 | <li class=" sub"><a href="authors-charm-quality.html">Charm Quality Rating</a></li> |
2792 | <li class=" sub"><a href="authors-charm-icon.html">Charm Icons</a></li> |
2793 | |
2794 | === modified file 'htmldocs/navigation.json' |
2795 | --- htmldocs/navigation.json 2013-09-05 12:01:47 +0000 |
2796 | +++ htmldocs/navigation.json 2013-09-11 07:54:25 +0000 |
2797 | @@ -38,17 +38,32 @@ |
2798 | |
2799 | }, |
2800 | "Charm Authors": { |
2801 | - "Anatomy of a Charm": "authors-charm-anatomy.html", |
2802 | + "Charm Contents": { |
2803 | + "link": "authors-charm-contents.html", |
2804 | + "children": { |
2805 | + "metadata.yaml": "authors-charm-metadata.html", |
2806 | + "config.yaml": "authors-charm-config.html", |
2807 | + "hooks": "authors-hook-kinds.html", |
2808 | + } |
2809 | + }, |
2810 | "Writing a Charm": { |
2811 | "link": "authors-charm-writing.html", |
2812 | "children": { |
2813 | - "Charms in Action": "authors-charms-in-action.html", |
2814 | + "Hook Environment": "authors-hook-environment.html", |
2815 | + "Relation Interfaces": "authors-charm-interfaces.html", |
2816 | + "Relations in Depth": "authors-relations-in-depth.html", |
2817 | + "Charm Testing": "authors-testing.html", |
2818 | + "Hook Errors": "authors-hook-errors.html", |
2819 | + "Hook Debugging": "authors-hook-debug.html", |
2820 | "Subordinate Services": "authors-subordinate-services.html", |
2821 | "Implicit Relations": "authors-implicit-relations.html", |
2822 | +<<<<<<< TREE |
2823 | "Charm Testing": "authors-testing.html", |
2824 | "Hook Debugging": "authors-hooks.html", |
2825 | "Interfaces": "authors-interfaces.html" |
2826 | |
2827 | +======= |
2828 | +>>>>>>> MERGE-SOURCE |
2829 | } |
2830 | }, |
2831 | "The Juju Charm Store": { |
2832 | @@ -57,6 +72,7 @@ |
2833 | "Charm Store Policy": "authors-charm-policy.html", |
2834 | "Best Practices": "authors-charm-best-practices.html", |
2835 | "Charm Quality Rating": "authors-charm-quality.html" |
2836 | + "Charm Icons": "authors-charm-icon.html" |
2837 | } |
2838 | } |
2839 | }, |
You have a lot of conflicts. you might want to merge 'docs' sort out the conflicts and push it up again.