CFEngine3 syntax only supports passing string arguments to
bundles; a technique is described in Diego Zamboni's
Learning CFEngine book to
pass arguments to a bundle using an array. In essence, the trick
is to pass the array by name and use CFEngine's getindices
function to list the array keys, and then re-create a local copy of
the array using a $($(arrayname)[$(key)])
construct. Somewhat
unreadable, but it works.
A variant of this technique also works with CFEngine's list types
(for which getindices
is not available). We need however to abuse
the grep function:
bundle agent test_slist_arg(listname) {
vars:
"param" slist => grep(".", "$(listname)");
reports:
linux::
"Got list argument: $(param)";
}
The above code makes an exact copy of list listname
into the
bundle-private list param
; the trick works because:
.
regular expression matches any content, so we just copy all
elements from the listname
list.And here's a runnable example, for demo purposes:
body common control
{
version => "CFEngine3 test file";
bundlesequence => { "test" };
}
bundle agent test
{
vars:
"a" slist => { "x", "y", "z" };
methods:
"test1" usebundle => test_slist_arg("test.a");
}
bundle agent test_slist_arg(listname) {
vars:
"param" slist => grep(".", "$(listname)");
reports:
linux::
"Got list argument: $(param)";
}
Running it produces the following output:
$ cf-agent -I -f TEST.cf
R: Got list argument: x
R: Got list argument: y
R: Got list argument: z