Promises
According to the cfengine documentation: A promise is the documentation or definition of an intention to act or behave in some manner. They are the rules which CFEngine clients are responsible for implementing.
Or, in other words, a promise tells cf-agent
what it should do. Note that cf-agent
runs on the client hosts, typically once every five minutes (see cf-execd
).
Here are some examples:
- Copy a file from the cfengine hub to a particular filesystem location on the client. Commonly this promise includes the caveat: "if the existing file is different to the one on the server". This sort of promise is good for setting up configuration files in
/etc
, for example. - Execute a command or script when a file is changed (such as by an instance of preceding example). This sort of promise is good for kicking (reloading or restarting) a daemon when there's a configuration file change, such as when an automounter configuration file changes.
Promises are stored in the file /var/lib/cfengine3/inputs/promises.cf
on each client and, indeed, it is a promise in this file that causes cf-agent
to check for and download a new instance of the file when it changes on the hub.
Promises are stored in "bundles". These are simply collections of related promises, such as promises related to the /etc/hostname
file, or to the abovementioned automounter configuration, or to the LDAP configuration, etc.
Types of promises
Promise type | Description |
---|---|
files | Actions on files or directories, including creating, copying, editing and deleting |
commands | Running external commands or scripts |
reports | Outputting messages to the message log |
classes | Setting cfengine classes |
All actions can be conditional, i.e., performed only when certain specified conditions are true.
An example bundle
Here's an example promises bundle. This one picks up a new promises.cf file from the cfengine hub, if one is available, and then causes cf-agent
to terminate early with a diagnostic message so that it doesn't continue to run with the old promises file. The next run of cf-agent
will use the new file.
bundle agent getpolicy { files: !policy_server:: "$(sys.workdir)/inputs/promises.cf" classes => file_changed(promises_cf), copy_from => remote_cp("$(sys.workdir)/inputs/promises.cf"); reports: promises_cf_changed:: "promises.cf changed. Terminating early to avoid using outdated promises"; classes: promises_cf_changed:: "promises_changed" expression => "any"; }
Here's what the different parts mean:
Text | Explanation |
---|---|
bundle agent policy | This is a bundle of promises for cf-agent . This bundle's name is "policy" but the name is just a choice for readability
|
files: | Start of a series of files promises |
!policy_server:: | A condition for executing the following promise(s). In this case, the following promises will be executed if the "policy server" class (indicated by the "::") is not set (indicated by the "!"). cfengine has built-in classes as well as classes which can be set by promises and classes which can be set on the command line when cf-agent is invoked. "policy server" is built in and is set when the host running cf-agent also runs a cf-serverd file and policy server.
|
$(sys.workdir) | Expansion of a "system" variable. cfengine variables differ from classes in that classes either exist or not, while variables can have values as well as exist. System variables are set by the cf-agent at before it starts processing promises and can contain things like the top-level directory containing cfengine work files (as in this example), the IP address of the host, type of operating system, etc.
Variables can be set by promises and can have a global scope or just a bundle scope. |
copy_from => | Indicates a file is to be copied to the local host. In this case exactly what, how and when are indicated by "remote_cp" which is specified elsewhere in the promises file (see live CSE promises file). The specification of "remote_cp" actually includes the source server, that a digest comparison should be made to determine if the file should be updated, and what to do with the old file (rename or delete). |
classes => | Indicates that one or more classes should be set or cleared. In this case, the separately defined "file_changed" (see live CSE promises file) specifies that the class "promises_cfchanged" should be set if the promises file is replaced. |
reports: | Start of a series of reports promises |
"promises_cf_changed":: | Indiocates that the following reports promises should only be executed when the class is set. See above. |