Promises: Difference between revisions

From techdocs
Jump to navigation Jump to search
No edit summary
No edit summary
 
(2 intermediate revisions by the same user not shown)
Line 8: Line 8:
# 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.
# 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 <code>[[/var/lib/cfengine3/inputs/promises.cf]]</code> on each client and, indeed, it is a promise in this file that causes <code>[[cf-agent]]</code> to check for and download a new instance of the file when it changes on the hub.
Promises are stored in the file <code>[[promises.cf]]</code> on each client and, indeed, it is a promise in this file that causes <code>[[cf-agent]]</code> 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 <code>/etc/hostname</code> file, or to the abovementioned automounter configuration, or to the [[LDAP]] configuration, etc.
Promises are stored in "bundles". These are simply collections of related promises, such as promises related to the <code>/etc/hostname</code> file, or to the abovementioned automounter configuration, or to the [[LDAP]] configuration, etc.
Line 29: Line 29:
|classes
|classes
|Setting cfengine classes
|Setting cfengine classes
|-
|methods
|Invoking parameterised promise bundles (a bit like subroutines)
|}
|}


Line 56: Line 59:
Here's what the different parts mean:
Here's what the different parts mean:


{|
{|class="firstcolfixed"
!Text
!Text
!Explanation
!Explanation
|-
|-
|'''bundle agent''' policy
|bundle '''agent''' policy
|This is a bundle of promises for <code>cf-'''agent'''</code>. This bundle's name is "policy" but the name is just a choice for readability
|This is a bundle of promises for <code>cf-'''agent'''</code>. This bundle's name is "policy" but the name is just a choice for readability
|-
|-
Line 70: Line 73:
|-
|-
|$(sys.workdir)
|$(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 <code>cf-agent</code> 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.
|Expansion of a "system" variable. cfengine variables differ from classes in that classes only either exist or not, while variables can have values as well as exist. System variables are set by the <code>cf-agent</code> before it starts processing promises and can contain values 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.
Variables can be set by promises and can have a global scope or just a bundle scope.
|-
|-
|copy_from =>
|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).
|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 the live "remote_cp" 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 =>
|classes =>
Line 90: Line 93:
|-
|-
|"promises_changed" expression => "any";
|"promises_changed" expression => "any";
|Set the class "promises_changed" unconditionally. This particular class name is specified elsewhere in the promises file as being a class which, on being set, causes <code>cf-agent</code> to terminate immediately without processing any more promises.
|Set the class "promises_changed" unconditionally. This particular class name is specified elsewhere in the promises file as being a class which, on being set, causes <code>cf-agent</code> to terminate immediately without processing any more promises. This is the mechanism used to ensure <code>cf-agent</code> doesn't run with an outdated promises file.
|}
|}

Latest revision as of 13:52, 26 July 2022

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:

  1. 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.
  2. 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 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
methods Invoking parameterised promise bundles (a bit like subroutines)

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 only either exist or not, while variables can have values as well as exist. System variables are set by the cf-agent before it starts processing promises and can contain values 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 the live "remote_cp" 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":: Indicates that the following reports promises should only be executed when the given class is set. See above.
classes: Start of a series of classes promises
"promises_changed" expression => "any"; Set the class "promises_changed" unconditionally. This particular class name is specified elsewhere in the promises file as being a class which, on being set, causes cf-agent to terminate immediately without processing any more promises. This is the mechanism used to ensure cf-agent doesn't run with an outdated promises file.