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.
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