Methods are compound promises that refer to whole bundles of promises. Methods may be parameterized.

code
methods:

  "any"

     usebundle => method_id("parameter",...);

Methods are useful for encapsulating repeatedly used configuration issues and iterating over parameters. They are implemented as bundles that are run inline. Note that if the bundle you specify requires no parameters you may omit the usebundle attribute and give the bundle name directly in the promiser string.

code
bundle agent example
{
  vars:

   "userlist" slist => { "mark", "jeang", "jonhenrik", "thomas", "eben" };
   "userinfo" data => parsejson('{ "mark": 10, "jeang":20, "jonhenrik":30, "thomas":40, "eben":-1 }');

  methods:
   # Activate subtest once for each list item
   "any" usebundle => subtest("$(userlist)");

   # Activate subtest once passing the entire list
   "amy" usebundle => subtest(@(userlist));

   # Pass a data type variable aka data container
   "amp" usebundle => subtest_c(@(userinfo));
}

bundle agent subtest(user)
{
  commands:

   "/bin/echo Fix $(user)";

  reports:

    "Finished doing stuff for $(user)";
}

bundle agent subtest_c(info)
{
  reports:
   "user ID of mark is $(info[mark])";
}

Methods offer powerful ways to encapsulate multiple issues pertaining to a set of parameters.

Note in the above that a list can be passed as a implicitly iterated scalar and as a reference, while a data variable (a data container) can only be passed by reference.

As of version 3.5.0 a methods promise outcome is tied to the outcomes of its promises. For example if you activate a bundle and it has a promise that is not_kept, the bundle itself would have an outcome of not_kept. If you activate a bundle that has one promise that is repaired, and one promise that is kept, the bundle will have an outcome of repaired. A method will only have an outcome of kept if all promises inside that bundle are also kept. This acceptance test illustrates the behavior.

Starting from version 3.1.0, methods may be specified using variables. Care should be exercised when using this approach. In order to make the function call uniquely classified, CFEngine requires the promiser to contain the variable name of the method if the variable is a list.

code
bundle agent default
{
vars:
    "m" slist  => { "x", "y" };
    "p" string => "myfunction";

methods:
    "set of $(m)" usebundle => $(m)("one");
    "any"         usebundle => $(p)("two");
}

Please note that method names must be either simple strings or slists. They can't be array references, for instance. As a rule, they can only look like $(name) where name is either a string or an slist. They can't be "$(a)$(b)", $(a[b]), and so on.

Here's a full example of how you might encode bundle names and parameters in a slist, if you need to pack and unpack method calls in a portable (e.g. written in a file) format.

code
body common control
{
      bundlesequence => { run };
}

bundle agent run
{
  vars:
      "todo" slist => { "call_1,a,b", "call_2,x,y", "call_2,p,q" };

  methods:
      "call" usebundle => unpack($(todo));
}

bundle agent unpack(list)
{
  vars:
      "split" slist => splitstring($(list), ",", "100");
      "method" string => nth("split", "0");
      "param1" string => nth("split", "1");
      "param2" string => nth("split", "2");

  methods:
      "relay" usebundle => $(method)($(param1), $(param2));
}

bundle agent call_1(p1, p2)
{
  reports:
      "$(this.bundle): called with parameters $(p1) and $(p2)";
}

bundle agent call_2(p1, p2)
{
  reports:
      "$(this.bundle): called with parameters $(p1) and $(p2)";
}

Output:

code
2013-12-11T13:33:31-0500   notice: /run/methods/'call'/unpack/methods/'relay'/call_1: R: call_1: called with parameters a and b
2013-12-11T13:33:31-0500   notice: /run/methods/'call'/unpack/methods/'relay'/call_2: R: call_2: called with parameters x and y
2013-12-11T13:33:31-0500   notice: /run/methods/'call'/unpack/methods/'relay'/call_2: R: call_2: called with parameters p and q

Attributes

Common attributes

Common attributes are available to all promise types. Full details for common attributes can be found in the Common promise attributes section of the Promise types page. The common attributes are as follows:

action

classes

comment

depends_on

handle

if

meta

with


inherit

Description: If true this causes the sub-bundle to inherit the private classes of its parent

Inheriting the variables is unnecessary as the child can always access the parent's variables through a qualified reference using its bundle name. For example: $(bundle.variable).

Type: boolean

Default value: false

Example:

code
bundle agent name
{
methods:

  "group name" usebundle => my_method,
                 inherit => "true";
}


body edit_defaults example
{
inherit => "true";
}

History: Was introduced in 3.4.0, Enterprise 3.0.0 (2012)

usebundle

Type: bundle agent

useresult

Description: Specify the name of a local variable to contain any result/return value from the child

Return values are limited to scalars.

Type: string

Allowed input range: `[a-zA-Z0-9_$(){}[].:]+

Example:

code
bundle agent test
{
methods:

   "any" usebundle => child,
         useresult => "my_return_var";

reports:
    "My return was: \"$(my_return_var[1])\" and \"$(my_return_var[2])\"";
}

bundle agent child
{
reports:
   # Map these indices into the useresult namespace

   "this is a return value"
      bundle_return_value_index => "1";

   "this is another return value"
      bundle_return_value_index => "2";
}

See also: reports bundle_return_value_index attribute

History: Was introduced in 3.4.0 (2012)