cf-reactor
cf-reactor is the event reaction daemon for CFEngine.
Instead of running policy on a fixed schedule like cf-agent, it watches for specific events on the host and runs policy as soon as one happens.
cf-reactor keeps the promises made in reactor bundles and is affected by the common control body.
On event, it runs the bundles of the then attribute of the events promise: reactor bundles without events promises, which behave like agent bundles, or agent and common bundles.
See Reactor bundles.
Notes:
cf-reactoralways considers the classreactorto be defined.- This daemon reloads its policy when the SIGHUP signal is received.
SIGUSR1sets the log level to debug.SIGUSR2sets the log level to notice.- On CFEngine Enterprise hubs,
cf-reactorhas extra responsibilities, see Enterprise hub tasks.
History:
- In 3.18.2 / 3.20.0
cf-reactorwas introduced as an Enterprise-only hub component. - In 3.29.0
cf-reactorwas moved to CFEngine community, andreactorbundles andeventspromises were introduced for event driven CFEngine policy.
Command reference
--debug , -d - Enable debugging output and run in foreground
--file , -f value - Specify an alternative input file than the default. This option is overridden by FILE if supplied as argument.
--no-fork , -F - Run as a foreground process (do not fork)
--log-level , -g value - Specify how detailed logs should be. Possible values: 'error', 'warning', 'notice', 'info', 'verbose', 'debug'
--help , -h - Print the help message
--inform , -I - Print basic information about actions being taken
--timestamp , -l - Log timestamps on each line of log output
--man , -M - Print the man page
--verbose , -v - Output verbose information about the behaviour of the agent
--version , -V - Output the version of the software
See also: Reactor normal ordering
Reactor bundles
There are two kinds of reactor bundles, depending on whether they have events promises:
reactorbundles witheventspromises set up the events to react to. Besideseventspromises, they can only havemeta,varsandclassespromises.cf-reactorevaluates them every time it reads the policy, see Reactor normal ordering.reactorbundles withouteventspromises are run on event, from thethenattribute ofeventspromises. They can have all the promise types ofagentbundles, including custom promise types, andcf-reactorruns them likecf-agentrunsagentbundles. They are not evaluated whencf-reactorreads the policy.
Having other promise types than meta, vars and classes alongside events promises is an error, and so is referring to a reactor bundle with events promises in a then attribute.
With reactor bundles without events promises, a policy for cf-reactor does not need agent bundles:
body when deleted(file)
{
file_deleted => "$(file)";
}
bundle reactor watch
{
vars:
"file" string => "/tmp/a";
events:
"Keep $(file)"
when => deleted("$(file)"),
then => { create_file("$(file)"), report_restored("$(file)") };
}
bundle reactor create_file(file)
{
files:
"$(file)" create => "true";
}
bundle reactor report_restored(file)
{
reports:
"$(file) was restored";
}Note: methods promises can call agent and common bundles, but not reactor bundles.
Under the hood
cf-reactor reads the policy and sets up event watchers based on the event promises declared in reactor bundles.
It then starts a thread that polls for each registered event.
When an event is detected, it is added to an event queue along with the corresponding event promise.
The daemon is then signaled to handle the event and run the bundles of the then attribute of the event promise, following the same execution model as cf-agent.
Notes:
- Event detection is based on polling, but
cf-reactordoes not use busy-waiting. Instead, the polling thread sleeps between polling cycles and remains dormant when no events are registered. cf-reactordoes not guarantee that an event will be handled immediately after it occurs. The delay depends on factors such as the polling interval, policy reloads, and slow code execution. However,cf-reactorguarantees that changes will be detected as fast as possible and the corresponding code executed, provided that execution does not fail.
Enterprise hub tasks
On CFEngine Enterprise hubs, cf-reactor also listens to NOTIFY events in the PostgreSQL database and performs actions when those events occur, and runs periodic hub tasks:
- Refreshing the
host_specific.jsonfiles whenever there is an event in thecmdb_refreshchannel. - Refreshing the inventory of hosts.
- Handling the requests of the Build application (cfbs requests and responses).
- Running alerts, scheduled reports, the cleanup of hosts, and the update of health failures.