lib/common.cf

Table of Contents

See the common promise attributes documentation for a comprehensive reference on the body types and attributes used here.

To use these bodies, add the following to your policy:

body file control
{
    inputs => { "common.cf" }
}

action bodies

if_elapsed

Prototype: if_elapsed(x)

Description: Evaluate the promise every x minutes

Arguments:

  • x: The time in minutes between promise evaluations

Implementation:

body action if_elapsed(x)
{
      ifelapsed => "$(x)";
      expireafter => "$(x)";
}

if_elapsed_day

Prototype: if_elapsed_day

Description: Evalute the promise once every 24 hours

Implementation:

body action if_elapsed_day
{
      ifelapsed => "1440";    # 60 x 24
      expireafter => "1400";
}

measure_performance

Prototype: measure_performance(x)

Description: Measure repairs of the promiser every x minutes

Repair-attempts are cancelled after x minutes.

Arguments:

  • x: The time in minutes between promise evaluations.

Implementation:

body action measure_performance(x)
{
      measurement_class => "Detect changes in $(this.promiser)";
      ifelapsed => "$(x)";
      expireafter => "$(x)";
}

measure_promise_time

Prototype: measure_promise_time(identifier)

Description: Performance will be measured and recorded under identifier

Arguments:

  • identifier: Measurement name.

Implementation:

body action measure_promise_time(identifier)
{
      measurement_class => "$(identifier)";
}

warn_only

Prototype: warn_only

Description: Warn once an hour if the promise needs to be repaired

The promise does not get repaired.

Implementation:

body action warn_only
{
      action_policy => "warn";
      ifelapsed => "60";
}

bg

Prototype: bg(elapsed, expire)

Description: Evaluate the promise in the background every elapsed minutes, for at most expire minutes

Arguments:

  • elapsed: The time in minutes between promise evaluations
  • expire: The time in minutes after which a repair-attempt gets cancelled

Implementation:

body action bg(elapsed,expire)
{
      ifelapsed   => "$(elapsed)";
      expireafter => "$(expire)";
      background  => "true";
}

ifwin_bg

Prototype: ifwin_bg

Description: Evaluate the promise in the background when running on Windows

Implementation:

body action ifwin_bg
{
    windows::
      background => "true";
}

immediate

Prototype: immediate

Description: Evaluate the promise at every cf-agent execution.

Implementation:

body action immediate
{
      ifelapsed => "0";
}

policy

Prototype: policy(p)

Description: Set the action_policy to p

Arguments:

  • p: The action policy

Implementation:

body action policy(p)
{
      action_policy => "$(p)";
}

log_repaired

Prototype: log_repaired(log, message)

Description: Log message to a file log=[/file|stdout]

Arguments:

  • log: The log file for repaired messages
  • message: The log message

Implementation:

body action log_repaired(log,message)
{
      log_string => "$(sys.date), $(message)";
      log_repaired => "$(log)";
}

log_verbose

Prototype: log_verbose

Description: Sets the log_level attribute to "verbose"

Implementation:

body action log_verbose
{
      log_level => "verbose";
}

sample_rate

Prototype: sample_rate(x)

Description: Evaluate the promise every x minutes, A repair-attempt is cancelled after 10 minutes

Arguments:

  • x: The time in minutes between promise evaluation

Implementation:

body action sample_rate(x)
{
      ifelapsed => "$(x)";
      expireafter => "10";
}

classes bodies

if_repaired

Prototype: if_repaired(x)

Description: Define class x if the promise has been repaired

Arguments:

  • x: The name of the class

Implementation:

body classes if_repaired(x)
{
      promise_repaired => { "$(x)" };
}

if_else

Prototype: if_else(yes, no)

Description: Define the classes yes or no depending on promise outcome

Arguments:

  • yes: The name of the class that should be defined if the promise is kept or repaired
  • no: The name of the class that should be defined if the promise could not be repaired

Implementation:

body classes if_else(yes,no)
{
      promise_kept     => { "$(yes)" };
      promise_repaired => { "$(yes)" };
      repair_failed    => { "$(no)" };
      repair_denied    => { "$(no)" };
      repair_timeout   => { "$(no)" };
}

cf2_if_else

Prototype: cf2_if_else(yes, no)

Description: Define the classes yes or no, depending on promise outcome

A version of if_else that matches CFEngine2 semantics. Neither class is set if the promise does not require any repair.

Arguments:

  • yes: The name of the class that should be defined if the promise is repaired
  • no: The name of the class that should be defined if the promise could not be repaired

Implementation:

body classes cf2_if_else(yes,no)
{
      promise_repaired => { "$(yes)" };
      repair_failed    => { "$(no)" };
      repair_denied    => { "$(no)" };
      repair_timeout   => { "$(no)" };
}

if_notkept

Prototype: if_notkept(x)

Description: Define the class x if the promise is not kept and cannot be repaired.

Arguments:

  • x: The name of the class that should be defined

Implementation:

body classes if_notkept(x)
{
      repair_failed   => { "$(x)" };
      repair_denied   => { "$(x)" };
      repair_timeout  => { "$(x)" };
}

if_ok

Prototype: if_ok(x)

Description: Define the class x if the promise is kept or could be repaired

Arguments:

  • x: The name of the class that should be defined

Implementation:

body classes if_ok(x)
{
      promise_repaired => { "$(x)" };
      promise_kept => { "$(x)" };
}

if_ok_cancel

Prototype: if_ok_cancel(x)

Description: Cancel the class x if the promise is kept or repaired

Arguments:

  • x: The name of the class that should be cancelled

Implementation:

body classes if_ok_cancel(x)
{
      cancel_repaired => { "$(x)" };
      cancel_kept => { "$(x)" };
}

cmd_repair

Prototype: cmd_repair(code, cl)

Description: Define the class cl if an external command in a commands, file or packages promise is executed with return code code

Arguments:

  • code: The return codes that indicate a successful repair
  • cl: The name of the class that should be defined

See also: repaired_returncodes

Implementation:

body classes cmd_repair(code,cl)
{
      repaired_returncodes => { "$(code)" };
      promise_repaired => { "$(cl)" };
}

classes_generic

Prototype: classes_generic(x)

Description: Define x prefixed/suffixed with promise outcome

Arguments:

  • x: The unique part of the classes to be defined

Implementation:

body classes classes_generic(x)
{
      promise_repaired => { "promise_repaired_$(x)", "$(x)_repaired", "$(x)_ok", "$(x)_reached" };
      repair_failed => { "repair_failed_$(x)", "$(x)_failed", "$(x)_not_ok", "$(x)_error", "$(x)_not_kept", "$(x)_reached" };
      repair_denied => { "repair_denied_$(x)", "$(x)_denied", "$(x)_not_ok", "$(x)_error", "$(x)_not_kept", "$(x)_reached" };
      repair_timeout => { "repair_timeout_$(x)", "$(x)_timeout", "$(x)_not_ok", "$(x)_error", "$(x)_not_kept", "$(x)_reached" };
      promise_kept => { "promise_kept_$(x)", "$(x)_kept", "$(x)_ok", "$(x)_reached" };
}

results

Prototype: results(scope, class_prefix)

Description: Define classes prefixed with class_prefix and suffixed with appropriate outcomes: _kept, _repaired, _not_kept, _error, _failed, _denied, _timeout, _reached

Arguments:

  • scope: The scope in which the class should be defined (bundle or namespace)
  • class_prefix: The prefix for the classes defined

This body can be applied to any promise and sets global (namespace) or local (bundle) classes based on its outcome. For instance, with class_prefix set to abc:

  • if the promise is to change a file's owner to nick and the file was already owned by nick, the classes abc_reached and abc_kept will be set.

  • if the promise is to change a file's owner to nick and the file was owned by adam and the change succeeded, the classes abc_reached and abc_repaired will be set.

This body is a simpler, more consistent version of the body scoped_classes_generic, which see. The key difference is that fewer classes are defined, and only for outcomes that we can know. For example this body does not define "OK/not OK" outcome classes, since a promise can be both kept and failed at the same time.

It's important to understand that promises may do multiple things, so a promise is not simply "OK" or "not OK." The best way to understand what will happen when your specific promises get this body is to test it in all the possible combinations.

Suffix Notes:

  • _reached indicates the promise was tried. Any outcome will result in a class with this suffix being defined.

  • _kept indicates some aspect of the promise was kept

  • _repaired indicates some aspect of the promise was repaired

  • _not_kept indicates some aspect of the promise was not kept. error, failed, denied and timeout outcomes will result in a class with this suffix being defined

  • _error indicates the promise repair encountered an error

  • _failed indicates the promise failed

  • _denied indicates the promise repair was denied

  • _timeout indicates the promise timed out

Example:

bundle agent example
{
  commands:
    "/bin/true"
      classes => results("bundle", "my_class_prefix");

  reports:
    my_class_prefix_kept::
      "My promise was kept";

    my_class_prefix_repaired::
      "My promise was repaired";
}

See also: scope, scoped_classes_generic, classes_generic

Implementation:

body classes results(scope, class_prefix)
{
  scope => "$(scope)";

  promise_kept => { "$(class_prefix)_reached",
                    "$(class_prefix)_kept" };

  promise_repaired => { "$(class_prefix)_reached",
                        "$(class_prefix)_repaired" };

  repair_failed => { "$(class_prefix)_reached",
                     "$(class_prefix)_error",
                     "$(class_prefix)_not_kept",
                     "$(class_prefix)_failed" };

  repair_denied => { "$(class_prefix)_reached",
                     "$(class_prefix)_error",
                     "$(class_prefix)_not_kept",
                     "$(class_prefix)_denied" };

  repair_timeout => { "$(class_prefix)_reached",
                      "$(class_prefix)_error",
                      "$(class_prefix)_not_kept",
                      "$(class_prefix)_timeout" };
}

diff_results

Prototype: diff_results(scope, x)

Description: Define x prefixed/suffixed with promise outcome with command return codes adjusted to align with diff.

Arguments:

  • scope: The scope the class should be defined with [bundle|namespace].
  • x: The unique part of the classes to be defined.

From man diff: Exit status is 0 if inputs are the same, 1 if different, 2 if trouble.

Example:

bundle agent example
{
  commands:
    "/usr/bin/diff"
      args => "/tmp/file1 /tmp/file2",
      classes => diff_results("diff");

  vars:
    "c" slist => classesmatching("diff_.*");

  reports:
    "Found class '$(c)'";
    "Files Differ!"
       if => "diff_failed|diff_error|diff_not_kept";
    "Files are the same."
       if => "diff_kept";
}

Implementation:

body classes diff_results(scope, x)
{
      inherit_from => results( $(scope), $(x) );
      kept_returncodes => { "0" };
      failed_returncodes => { "1","2" };
}

scoped_classes_generic

Prototype: scoped_classes_generic(scope, x)

Description: Define x prefixed/suffixed with promise outcome See also: scope

Arguments:

  • scope: The scope in which the class should be defined
  • x: The unique part of the classes to be defined

Implementation:

body classes scoped_classes_generic(scope, x)
{
      scope => "$(scope)";
      promise_repaired => { "promise_repaired_$(x)", "$(x)_repaired", "$(x)_ok", "$(x)_reached" };
      repair_failed => { "repair_failed_$(x)", "$(x)_failed", "$(x)_not_ok", "$(x)_error", "$(x)_not_kept", "$(x)_reached" };
      repair_denied => { "repair_denied_$(x)", "$(x)_denied", "$(x)_not_ok", "$(x)_error", "$(x)_not_kept", "$(x)_reached" };
      repair_timeout => { "repair_timeout_$(x)", "$(x)_timeout", "$(x)_not_ok", "$(x)_error", "$(x)_not_kept", "$(x)_reached" };
      promise_kept => { "promise_kept_$(x)", "$(x)_kept", "$(x)_ok", "$(x)_reached" };
}

u_kept_successful_command

Prototype: u_kept_successful_command

Description: Set command to "kept" instead of "repaired" if it returns 0

Implementation:

body classes u_kept_successful_command
{
      kept_returncodes => { "0" };
}

state_repaired

Prototype: state_repaired(x)

Description: Define x for 10 minutes if the promise was repaired

Arguments:

  • x: The name of the class that should be defined

Implementation:

body classes state_repaired(x)
{
      promise_repaired => { "$(x)" };
      persist_time => "10";
      scope => "namespace";
}

enumerate

Prototype: enumerate(x)

Description: Define x for 15 minutes if the promise is either kept or repaired This is used by commercial editions to count instances of jobs in a cluster

Arguments:

  • x: The unique part of the class that should be defined The class defined is prefixed with mXC_

Implementation:

body classes enumerate(x)
{
      promise_repaired => { "mXC_$(x)" };
      promise_kept => { "mXC_$(x)" };
      persist_time => "15";
      scope => "namespace";
}

always

Prototype: always(x)

Description: Define class x no matter what the outcome of the promise is

Arguments:

  • x: The name of the class to be defined

Implementation:

body classes always(x)
{
      promise_repaired => { "$(x)" };
      promise_kept => { "$(x)" };
      repair_failed => { "$(x)" };
      repair_denied => { "$(x)" };
      repair_timeout => { "$(x)" };
}

kept_successful_command

Prototype: kept_successful_command

Description: Set command to "kept" instead of "repaired" if it returns 0

Implementation:

body classes kept_successful_command
{
      kept_returncodes => { "0" };
}