CFEngine provides the services promise type to manage the state of a given service. By default, bundle agent standard_services is used for the service_method. The standard_services bundle uses the status command and interprets the return codes according to the Linux Standard Base init script actions. Unfortunately some init scripts do not follow the standards. On sysvinit (non-systemd) hosts, if the status command returns zero when a service is not running, cfengine will issue the commands necessary to stop the service every time the agent is run. Similarly, if the status command returns zero when the service is not running, cfengine will never issue the commands necessary to start a service.
How can I handle a service status that does not comport with the standard?
One way to deal with misbehaving services is to implement a custom service_method that better understands the specifics for a given service.
For example, the MacAfee Agent status command simply emits the current status for it's services and does not use the expected return codes.
[root@host ~]# /etc/init.d/ma status McAfee agent service is not running. McAfee common services is not running. McAfee compat service is not running. [root@host ~]# echo $? 0
First, for testing, create a mock init script that matches the behavior seen in the output above.
|
|
Next you can write a custom bundle to implement services based on the McAfee behavior.
|
|
Then you can expose it as a service_method attribute value by defining a service_method body.
|
|
And then you could specify use the services promise
|
|
Execute the policy to see it in action:
|
|
error: Policy failed validation with command '"/home/nickanderson/.cfagent/bin/cf-promises" -c "./example_custom_services.cf"'
error: CFEngine was not able to get confirmation of promises from cf-promises, so going to failsafe
error: CFEngine failsafe.cf: /home/nickanderson/.cfagent/inputs /home/nickanderson/.cfagent/inputs/failsafe.cf
info: Unable to find host '$(sys.policy_hub)' service '$(sys.policy_hub_port)' (Servname not supported for ai_socktype)
info: No server is responding on port: $(sys.policy_hub_port)
info: Unable to establish connection to '$(sys.policy_hub)'
error: No suitable server found
info: Promise belongs to bundle 'failsafe_cfe_internal_update' in file '/home/nickanderson/.cfagent/inputs/failsafe.cf' near line 114
info: Unable to find host '$(sys.policy_hub)' service '$(sys.policy_hub_port)' (Servname not supported for ai_socktype)
info: No server is responding on port: $(sys.policy_hub_port)
info: Unable to establish connection to '$(sys.policy_hub)'
error: No suitable server found
info: Promise belongs to bundle 'failsafe_cfe_internal_update' in file '/home/nickanderson/.cfagent/inputs/failsafe.cf' near line 123
info: Unable to find host '$(sys.policy_hub)' service '$(sys.policy_hub_port)' (Servname not supported for ai_socktype)
info: No server is responding on port: $(sys.policy_hub_port)
info: Unable to establish connection to '$(sys.policy_hub)'
error: No suitable server found
info: Promise belongs to bundle 'failsafe_cfe_internal_update' in file '/home/nickanderson/.cfagent/inputs/failsafe.cf' near line 137
info: Comment is 'If we failed to fetch policy we try again using
the legacy default in case we are fetching policy
from a hub that is not serving mastefiles via a
shortcut.'
error: Method 'failsafe_cfe_internal_update' failed in some repairs
info: Executing 'no timeout' ... '"/home/nickanderson/.cfagent/bin/cf-agent" -f /home/nickanderson/.cfagent/inputs/update.cf --define failsafe_mode'
notice: Q: ".../cf-agent" -f /": error: No suitable server found
Q: ".../cf-agent" -f /": error: No suitable server found
Q: ".../cf-agent" -f /": error: No suitable server found
Q: ".../cf-agent" -f /": error: Method 'cfe_internal_update_policy_cpv' failed in some repairs
info: Last 4 quoted lines were generated by promiser '"/home/nickanderson/.cfagent/bin/cf-agent" -f /home/nickanderson/.cfagent/inputs/update.cf --define failsafe_mode'
info: Completed execution of '"/home/nickanderson/.cfagent/bin/cf-agent" -f /home/nickanderson/.cfagent/inputs/update.cf --define failsafe_mode'
R: Built-in failsafe policy triggered