You are on page 1of 9

Functions

1) getindices() or getvalues()
Synopsis: getindices(arg1) returns type slist
arg1 : Cfengine array identifier, in the range [a-zA-Z0-9_$(){}\[\].:]+
Get a list of keys to the array whose id is the argument and assign to variable
Example:
bodycommoncontrol
{
any::
bundlesequence=>{"testsetvar"};
}
#######################################################
bundleagenttestsetvar
{
vars:
"v[index_1]"string=>"value_1";
"v[index_2]"string=>"value_2";
"parameter_name"slist=>getindices("v");
reports:
Yr2008::
"Foundindex:$(parameter_name)";
}

2) fileexists()
Synopsis: fileexists(arg1) returns type class

arg1 : File object name, in the range "?(/.*)


True if the named file can be accessed
Example:
bodycommoncontrol
{
bundlesequence=>{"example"};
}
###########################################################

bundleagentexample
{
classes:
"exists"expression=>fileexists("/etc/passwd");
reports:
exists::
"Fileexists";
}

3) ifvarclass()
ype: string
Allowed input range: (arbitrary string)
Synopsis: Extended classes ANDed with context
Example:
The generic example has the form:

promisetype:

"promiser"

ifvarclass=>"$(program)_running|($(program)_notfound&Hr12)";

A specific example would be:


bundleagentexample
{
commands:
any::
"/bin/echoThisislinux"
ifvarclass=>"linux";

"/bin/echoThisissolaris"
ifvarclass=>"solaris";

Notes:
This is an additional class expression that will be evaluated after the class:: classes have
selected promises. It is provided in order to enable a channel between variables and classes. The
result is thus the logical AND of the ordinary classes and the variable classes.
This function is provided so that one can form expressions that link variables and classes, e.g.
#Checkthatallcomponentsarerunning

vars:
"component"slist=>{"cfmonitord","cfserverd"};
processes:
"$(component)"restart_class=>canonify("start_$(component)");
commands:
"/var/cfengine/bin/$(component)"
ifvarclass=>canonify("start_$(component)");

Notice that the function canonify() is provided to convert a general variable input into a string
composed only of legal characters, using the same algorithm that CFEngine uses.

4) regline()
5) Synopsis: regline(arg1,arg2) returns type class
6)
arg1 : Regular expression, in the range .*
arg2 : Filename to search, in the range .*
7) True if the regular expression in arg1 matches a line in file arg2
8) Example:
9) bundleagenttestbundle
10)
11)

12)

files:

13)
14)

"/tmp/testfile"edit_line=>test;

15)

16)
17)

########################################################

18)
19)
20)

bundleedit_linetest

21)

22)

classes:

23)
24)

"ok"expression=>regline(".*XYZ.*","$(edit.filename)");

25)
26)

reports:

27)
28)

ok::

29)
30)

"File$(edit.filename)hasalinewith\"XYZ\"init";

31)
32)

33)

34) Notes:
35) Note that the regular expression must match an entire line of the file in order to give a
true result. This function is useful for edit_line applications, where one might want to
set a class for detecting the presence of a string which does not exactly match one being
inserted. e.g.
36)

bundleedit_lineupgrade_cfexecd

37)

38)

classes:

39)
40)

#Checkthereisnotalreadyacrontabline,notidentical
to

41)
42)

#theoneproposedbelow...

43)
44)
45)

"exec_fix"not=>regline(".*cfexecd.*","$
(edit.filename)");

46)
47)

insert_lines:

48)
49)

exec_fix::

50)
51)

"0,5,10,15,20,25,30,35,40,45,50,55****
/var/cfengine/bin/cfexecdF";

52)
53)

reports:

54)
55)

exec_fix::

56)
57)

"Addeda5minutescheduletocrontabs";

58)

5) Regcmp()
Synopsis: regcmp(arg1,arg2) returns type class
arg1 : Regular expression, in the range .*
arg2 : Match string, in the range .*
True if arg1 is a regular expression matching that matches string arg2
Example:
bundleagentsubtest(user)
{
classes:
"invalid"not=>regcmp("[az]{4}","$(user)");
reports:
!invalid::
"Username$(user)isvalidatexactly4letters";
invalid::
"Username$(user)isinvalid";

Notes:
Compares a string to a regular expression.
ARGUMENTS:

regex
A regular expression to match the content. The regular expression must match the complete
content (that is, it is anchored, see Anchored vs. unanchored regular expressions).

string
Test data for the regular expression.
If there are multiple-lines in the data, it is necessary to code these explicitly, as regular expressions
do not normally match the end of line as a regular character (they only match end of string). You can
do this using either standard regular expression syntax or using the additional features of PCRE
(where (?ms) changes the way that ., ^ and $ behave), e.g.

bodycommoncontrol
{
bundlesequence=>{"example"};
}

bundleagentexample
{
vars:

"x"string=>"
NAME:apache2Apache2.2webserver
CATEGORY:application
ARCH:all
VERSION:2.2.3,REV=2006.09.01
BASEDIR:/
VENDOR:http://httpd.apache.org/packagedforCSWbyCoryOmand
PSTAMP:comand@thor20060901022929
INSTDATE:Dec14200616:05
HOTLINE:http://www.blastwave.org/bugtrack/
EMAIL:comand@blastwave.org
STATUS:completelyinstalled
";

classes:

"pkg_installed"expression=>regcmp("(.*\n)*STATUS:\s+completely
installed\n(.*\n)*",$(x));

"base_is_root"expression=>regcmp("(?ms).*^BASEDIR:\s+/$.*",$(x));

reports:

pkg_installed::

"installed";

base_is_root::

"inroot";
}

You might also like