Methods type promises are powerful abstraction tools in CFEngine 3. Methods allow you to activate bundles (optionally parametrized) from other bundles. This allows encapsulation of knowledge and lends itself to re-usability.
I just want to share an example of calling bundles dynamically. It’s a contrived example, but I thought it was neat so here it is.
<div class="gist-meta">
<a href="https://gist.github.com/raw/3901453/0b683269921c056b4e821dd2c63ca6b622122e26/output" style="float:right;">view raw</a> <a href="https://gist.github.com/3901453#file_output" style="float:right;margin-right:10px;color:#666">output</a> <a href="https://gist.github.com/3901453">This Gist</a> is brought to you using <a href="http://en.bainternet.info/2011/simple-gist-embed"><small>Simple Gist Embed</small></a>.
</div>
</div>
<div class="gist-file">
<div class="gist-data gist-syntax">
<div class="highlight">
<pre><div class='line' id='LC1'>
body common control {
<div class="gist-meta">
<a href="https://gist.github.com/raw/3901453/67c8bda449460da4d5b8c1983d5b0bbaacc63b13/test.cf" style="float:right;">view raw</a> <a href="https://gist.github.com/3901453#file_test.cf" style="float:right;margin-right:10px;color:#666">test.cf</a> <a href="https://gist.github.com/3901453">This Gist</a> is brought to you using <a href="http://en.bainternet.info/2011/simple-gist-embed"><small>Simple Gist Embed</small></a>.
</div>
</div>
Breakdown
bundle agent main
Here we define two lists, a list of bundle names and a list of values. Because of implicit list iteration we then call “handler_iterator” 2 times. Once for each value of the mybundles list. Each activation also passes in the myvalues list.
Bundle agent handler_iterator
handler_iterator is where the neat part happens. You can see that we call the bundle $(handler) (outside of quotes) with the parameter @(handler_iterator.values). This is what I found so interesting. I Have called bundles dynamically in the past, but I have always put the variable inside of quotes. That worked fine but it prevented me from using parameters when calling because the parameters were seen as part of the bundle name. Here is an example of the handler_iterator bundle trying to use a parametrized value inside of quotes.
<div class="gist-meta">
<a href="https://gist.github.com/raw/3901469/68b0a864b987496cdd8d936bb5d8777ca6fc6f6a/example%20of%20bundle%20inside%20quotes" style="float:right;">view raw</a> <a href="https://gist.github.com/3901469#file_example of bundle inside quotes" style="float:right;margin-right:10px;color:#666">example of bundle inside quotes</a> <a href="https://gist.github.com/3901469">This Gist</a> is brought to you using <a href="http://en.bainternet.info/2011/simple-gist-embed"><small>Simple Gist Embed</small></a>.
</div>
</div>
<div class="gist-file">
<div class="gist-data gist-syntax">
<div class="highlight">
<pre><div class='line' id='LC1'>
!! A method attempted to use a bundle “handler1(value1)” that was apparently not defined!
<div class="gist-meta">
<a href="https://gist.github.com/raw/3901469/718fbe133ea02c04d6d55badaf599f90fdc7679b/output" style="float:right;">view raw</a> <a href="https://gist.github.com/3901469#file_output" style="float:right;margin-right:10px;color:#666">output</a> <a href="https://gist.github.com/3901469">This Gist</a> is brought to you using <a href="http://en.bainternet.info/2011/simple-gist-embed"><small>Simple Gist Embed</small></a>.
</div>
</div>
Since $(handler) is a single value (we iterated over the list of bundles in bundle agent main) only one method activation will happen for each activation of handler_iterator.
bundle agent handlerx
The handlers themselves just report once for each item in the list passed to them.
Specific Use Case
Well, I don’t have one. I can however imagine that based on some variable event you might want to call a bundle with some variable parameter. Something like the nagios_plugin_agent sketch comes to mind. (It can call a variable bundle right now).