Skip to content

Commit

Permalink
Fixes #7192: Rewrite the service_* methods
Browse files Browse the repository at this point in the history
  • Loading branch information
amousset committed Mar 1, 2017
1 parent 9b20fc2 commit 3fbda7e
Show file tree
Hide file tree
Showing 16 changed files with 441 additions and 337 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ bundle agent test
bundle agent check
{
classes:
"ok" expression => "service_check_disabled_at_boot_${init.service_name}_ok.!service_check_disabled_at_boot_${init.service_name}_error.service_check_disabled_at_boot_${init.unknown_service_name}_error";
"ok" expression => "service_check_disabled_at_boot_${init.service_name}_ok.!service_check_disabled_at_boot_${init.service_name}_error.service_check_disabled_at_boot_${init.unknown_service_name}_ok";

reports:
ok::
Expand Down
Empty file.
307 changes: 307 additions & 0 deletions tree/20_cfe_basics/ncf_lib.cf

Large diffs are not rendered by default.

30 changes: 3 additions & 27 deletions tree/30_generic_methods/_service_check_running_smf.cf
Original file line number Diff line number Diff line change
Expand Up @@ -23,45 +23,21 @@
#
# @class_prefix service_check_running
# @class_parameter service_name
# @deprecated Use [service_check_running](#service_check_running) instead.

bundle agent _service_check_running_smf(service_name)
{
vars:
"canonified_service_name" string => canonify("${service_name}");

"old_class_prefix" string => canonify("service_check_running_${service_name}");
"promisers" slist => { @{this.callers_promisers}, cf_null }, policy => "ifdefined";
"class_prefix" string => canonify(join("_", "promisers"));
"args" slist => { "${service_name}" };

"check_command" string => "${paths.path[svcs]} -H ${service_name} | grep '^online'";
"check_command_canon" string => canonify("${check_command}");

methods:

svcs_utility_present::
"check_if_service_is_running" usebundle => command_execution_result("${check_command}", "0", "1");

"old_success_classes"
usebundle => _classes_success("${old_class_prefix}"),
ifvarclass => "command_execution_result_${check_command_canon}_kept";

"success_classes"
usebundle => _classes_success("${class_prefix}"),
ifvarclass => "${class_prefix}_check_if_service_is_running_kept";

"old_failure_class"
usebundle => _classes_failure("${old_class_prefix}"),
ifvarclass => canonify("command_execution_result_${check_command}_repaired");

"failure_class"
usebundle => _classes_failure("${class_prefix}"),
ifvarclass => "${class_prefix}_check_if_service_is_running_repaired";
"check_if_service_is_running" usebundle => service_check_running("${service_name}");

"report"
usebundle => _log("Check if the service ${service_name} is started using SMF", "${old_class_prefix}", "${class_prefix}", @{args});

!svcs_utility_present::
"old_force_failure_class" usebundle => _classes_failure("${old_class_prefix}");
"force_failure_class" usebundle => _classes_failure("${class_prefix}");
"report" usebundle => _log("Can't check if service ${service_name} is running, svcs is not available", "${old_class_prefix}", "${class_prefix}", @{args});
}
30 changes: 3 additions & 27 deletions tree/30_generic_methods/_service_check_running_src.cf
Original file line number Diff line number Diff line change
Expand Up @@ -23,45 +23,21 @@
#
# @class_prefix service_check_running
# @class_parameter service_name
# @deprecated Use [service_check_running](#service_check_running) instead.

bundle agent _service_check_running_src(service_name)
{
vars:
"canonified_service_name" string => canonify("${service_name}");

"old_class_prefix" string => canonify("service_check_running_${service_name}");
"promisers" slist => { @{this.callers_promisers}, cf_null }, policy => "ifdefined";
"class_prefix" string => canonify(join("_", "promisers"));
"args" slist => { "${service_name}" };

"check_command" string => "/usr/bin/lssrc -s ${service_name} | grep -q 'active'";
"check_command_canon" string => canonify("${check_command}");

methods:

lssrc_utility_present::
"check if subsystem is running" usebundle => command_execution_result("${check_command}", "0", "1");

"success_classes"
usebundle => _classes_success("${old_class_prefix}"),
ifvarclass => "command_execution_result_${check_command_canon}_kept";

"success_classes"
usebundle => _classes_success("${class_prefix}"),
ifvarclass => "has_promiser_stack.${class_prefix}_check_if_subsystem_is_running_kept";

"failure_class"
usebundle => _classes_failure("${old_class_prefix}"),
ifvarclass => canonify("command_execution_result_${check_command}_repaired");

"failure_class"
usebundle => _classes_failure("${class_prefix}"),
ifvarclass => "has_promiser_stack.${class_prefix}_check_if_subsystem_is_running_repaired";
"check if subsystem is running" usebundle => service_check_running("${service_name}");

"report"
usebundle => _log("Check if the service ${service_name} is started using SRC", "${old_class_prefix}", "${class_prefix}", @{args});

!lssrc_utility_present::
"force_failure_class" usebundle => _classes_failure("${class_prefix}");
"report" usebundle => _log("Can't check if service ${service_name} is running, lssrc is not available", "${old_class_prefix}", "${class_prefix}", @{args});

}
95 changes: 8 additions & 87 deletions tree/30_generic_methods/service_action.cf
Original file line number Diff line number Diff line change
Expand Up @@ -29,102 +29,23 @@ bundle agent service_action(service_name, action)
{
vars:

systemctl_utility_present::

"action_command" string => "${paths.path[systemctl]} ${action} ${service_name}.service";

!systemctl_utility_present.service_utility_present::

"action_command" string => "${paths.path[service]} ${service_name} ${action}";

!systemctl_utility_present.!service_utility_present.startsrc_utility_present::
"svc_action_cmd[restart]" string => "/usr/bin/stopsrc -s ${service_name} && until /usr/bin/lssrc -s ${service_name} | ${paths.grep} -q inoperative; do ${paths.perl} -e 'select(undef,undef,undef,.25)'; done; /usr/bin/startsrc -s ${service_name}";
"svc_action_cmd[refresh]" string => "/usr/bin/refresh -s ${service_name}";
"svc_action_cmd[reload]" string => "${svc_action_cmd[refresh]}";
"svc_action_cmd[start]" string => "/usr/bin/startsrc -s ${service_name}";
"svc_action_cmd[stop]" string => "/usr/bin/stopsrc -s ${service_name}";
"action_command" string => "${svc_action_cmd[${action}]}";

!systemctl_utility_present.!service_utility_present.!startsrc_utility_present.svcadm_utility_present::
"svc_action_cmd[restart]" string => "${paths.path[svcadm]} restart -s ${service_name}";
"svc_action_cmd[refresh]" string => "${paths.path[svcadm]} refresh -s ${service_name}";
"svc_action_cmd[reload]" string => "${svc_action_cmd[refresh]}";
"svc_action_cmd[enable]" string => "${paths.path[svcadm]} enable -s ${service_name}";
"svc_action_cmd[start]" string => "${paths.path[svcadm]} enable -s -t ${service_name}";
"svc_action_cmd[disable]" string => "${paths.path[svcadm]} disable -s ${service_name}";
"svc_action_cmd[stop]" string => "${paths.path[svcadm]} disable -s -t ${service_name}";
"action_command" string => "${svc_action_cmd[${action}]}";

!systemctl_utility_present.!service_utility_present.!startsrc_utility_present.!svcadm_utility_present.init_d_directory_present::

"action_command" string => "/etc/init.d/${service_name} ${action}";

any::

"canonified_service_name" string => canonify("${service_name}");
"canonified_action_command" string => canonify("${action_command}");
"canonified_action" string => canonify("${action}");

"old_class_prefix" string => "service_action_${canonified_service_name}";
"promisers" slist => { @{this.callers_promisers}, cf_null }, policy => "ifdefined";
"class_prefix" string => canonify(join("_", "promisers"));
"args" slist => { "${service_name}", "${action}" };

classes:

windows::
"is_valid_action" or => {
strcmp("start", "${action}"),
strcmp("stop", "${action}"),
strcmp("restart", "${action}"),
};
"is_restart_action" expression => strcmp("restart", "${action}");

methods:

service_utility_present|init_d_directory_present|startsrc_utility_present|svcadm_utility_present::

"action using command" usebundle => command_execution("${action_command}");

"class copy" usebundle => _classes_copy("command_execution_${canonified_action_command}", "${old_class_prefix}");
"new result classes" usebundle => _classes_copy("${class_prefix}_action_using_command", "${class_prefix}");

systemctl_utility_present|service_utility_present|init_d_directory_present|startsrc_utility_present|svcadm_utility_present|(windows.is_valid_action)::

"report" usebundle => _log("Run action ${action} on service ${service_name}", "${old_class_prefix}", "${class_prefix}", @{args}),
ifvarclass => "(!has_promiser_stack.${old_class_prefix}_reached)|(has_promiser_stack.${class_prefix}_reached)";

(!systemctl_utility_present.!service_utility_present.!init_d_directory_present.!startsrc_utility_present.!svcadm_utility_present.!windows)|(windows.!is_valid_action)::

"force_failure_class" usebundle => _classes_failure("${old_class_prefix}");
"force_failure_class" usebundle => _classes_failure("${class_prefix}");
"report" usebundle => _log("Running ${action} on service ${service_name} is not possible yet on this system", "${old_class_prefix}", "${class_prefix}", @{args});

services:

# Restart causes the agent to fail, so we must replace it by stop and start
windows.is_valid_action.!is_restart_action::
"${service_name}"
service_policy => "${action}",
classes => classes_generic_two("${old_class_prefix}", "${class_prefix}");

windows.is_restart_action::
"${service_name}"
service_policy => "stop",
classes => classes_generic_two("${old_class_prefix}_stop_service", "${class_prefix}_stop_service");

"${service_name}"
service_policy => "start",
classes => classes_generic_two("${old_class_prefix}", "${class_prefix}"),
ifvarclass => "(!has_promiser_stack.${old_class_prefix}_stop_service_ok)|(has_promiser_stack.${class_prefix}_stop_service_ok)";

commands:
"action" usebundle => ncf_services("${service_name}", "${action}");

# We need to use our own commands: implementation here rather than calling command_execution
# because of a CFEngine bug (https://dev.cfengine.com/issues/5840) that causes systemctl
# to fail if it can't find /dev/tty, which is the case unless using no_output => true
systemctl_utility_present::
"${action_command}"
contain => in_shell_and_silent,
classes => classes_generic("${class_prefix}");
"class copy" usebundle => _classes_copy("ncf_services_${canonified_service_name}_${canonified_action}", "${old_class_prefix}"),
ifvarclass => "ncf_services_${canonified_service_name}_${canonified_action}_reached";
"new result classes" usebundle => _classes_copy("${class_prefix}_action", "${class_prefix}"),
ifvarclass => "${class_prefix}_action_reached";

"report" usebundle => _log("Run action ${action} on service ${service_name}", "${old_class_prefix}", "${class_prefix}", @{args}),
ifvarclass => "(!has_promiser_stack.${old_class_prefix}_reached)|(has_promiser_stack.${class_prefix}_reached)";
}
50 changes: 9 additions & 41 deletions tree/30_generic_methods/service_check_disabled_at_boot.cf
Original file line number Diff line number Diff line change
Expand Up @@ -28,58 +28,26 @@
bundle agent service_check_disabled_at_boot(service_name)
{
vars:

pass1.systemctl_utility_present::
"command_to_check" string => "${paths.path[systemctl]} is-enabled ${service_name} | grep disabled";

pass1.!systemctl_utility_present.chkconfig_utility_present::
"command_to_check" string => "${paths.path[chkconfig]} --list ${service_name} | grep -q `runlevel | ${paths.path[cut]} -d' ' -f2`:off";

pass1.!systemctl_utility_present.!chkconfig_utility_present.lsitab_utility_present::
"command_to_check" string => "/usr/sbin/lsitab -a | egrep '^${service_name}:[0-9]+:(off):'";

pass1.!systemctl_utility_present.!chkconfig_utility_present.!lsitab_utility_present.svcs_utility_present::
"command_to_check" string => "${paths.path[svcs]} -l ${service_name} | egrep '^enabled [ ]+false'";

(pass1.!systemctl_utility_present.!chkconfig_utility_present.!lsitab_utility_present.!svcs_utility_present)|(pass1.broken_systemctl)::
"command_to_check" string => "${paths.path[test]} -f /etc/rc`runlevel | ${paths.path[cut]} -d' ' -f2`.d/K??${service_name}";

any::

"canonified_service_name" string => canonify("${service_name}");
"canonified_command" string => canonify("${command_to_check}");

"old_class_prefix" string => "service_check_disabled_at_boot_${canonified_service_name}";
"promisers" slist => { @{this.callers_promisers}, cf_null }, policy => "ifdefined";
"class_prefix" string => canonify(join("_", "promisers"));
"args" slist => { "${service_name}" };

classes:

# This is to workaround a bug in Debian Jessie, that makes systemctl is-enabled
# fail if run against a service that still uses SysV style scripts
# See https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=760616
"init_script_present" expression => fileexists("/etc/init.d/${service_name}");
"broken_systemctl" expression => "debian_8.init_script_present";

pass1::
"not_set_at_boot" expression => returnszero("${command_to_check}", "useshell");

any::
"pass2" expression => "pass1";
"pass1" expression => "any";

methods:
"check_enabled" usebundle => ncf_services("${service_name}", "is-enabled");

not_set_at_boot::
"success" usebundle => _classes_success("${old_class_prefix}");
"success" usebundle => _classes_success("${class_prefix}");
"success" usebundle => _classes_success("${old_class_prefix}"),
ifvarclass => "ncf_services_${canonified_service_name}_is_enabled_not_ok";
"success" usebundle => _classes_success("${class_prefix}"),
ifvarclass => "${class_prefix}_check_enabled_not_ok";

pass2.!not_set_at_boot::
"failure" usebundle => _classes_failure("${old_class_prefix}");
"failure" usebundle => _classes_failure("${class_prefix}");
"failure" usebundle => _classes_failure("${old_class_prefix}"),
ifvarclass => "ncf_services_${canonified_service_name}_is_enabled_ok";
"failure" usebundle => _classes_failure("${class_prefix}"),
ifvarclass => "${class_prefix}_check_enabled_ok";

pass2::
"reports" usebundle => _log("Check if service ${service_name} is disabled at boot", "${old_class_prefix}", "${class_prefix}", @{args});

}
20 changes: 8 additions & 12 deletions tree/30_generic_methods/service_check_running.cf
Original file line number Diff line number Diff line change
Expand Up @@ -27,24 +27,20 @@
bundle agent service_check_running(service_name)
{
vars:
"canonified_service_name" string => canonify("${service_name}");

"old_class_prefix" string => canonify("service_check_running_${service_name}");
"promisers" slist => { @{this.callers_promisers}, cf_null }, policy => "ifdefined";
"class_prefix" string => canonify(join("_", "promisers"));
"args" slist => { "${service_name}" };

methods:
"check_active" usebundle => ncf_services("${service_name}", "is-active");

lssrc_utility_present::
"check running" usebundle => _service_check_running_src("${service_name}");

svcs_utility_present::
"check running" usebundle => _service_check_running_smf("${service_name}");

!lssrc_utility_present.!svcs_utility_present::
# Will be replaced later with less naive conditions (using either service, upstart, ...
"check running" usebundle => service_check_running_ps("${service_name}");
"class copy" usebundle => _classes_copy("ncf_services_${canonified_service_name}_is_active", "${old_class_prefix}"),
ifvarclass => "ncf_services_${canonified_service_name}_is_active_reached";
"new result classes" usebundle => _classes_copy("${class_prefix}_check_active", "${class_prefix}"),
ifvarclass => "${class_prefix}_check_active_reached";

any::
"new result classes" usebundle => _classes_copy("${class_prefix}_check_running", "${class_prefix}");
"report" usebundle => _log("Check if the service ${service_regex} is started", "${old_class_prefix}", "${class_prefix}", @{args});
"report" usebundle => _log("Check if the service ${service_name} is started", "${old_class_prefix}", "${class_prefix}", @{args});
}
36 changes: 7 additions & 29 deletions tree/30_generic_methods/service_check_running_ps.cf
Original file line number Diff line number Diff line change
Expand Up @@ -27,44 +27,22 @@
bundle agent service_check_running_ps(service_regex)
{
vars:
"canonified_service_regex" string => canonify("${service_regex}");

"old_class_prefix" string => canonify("service_check_running_${service_regex}");
"promisers" slist => { @{this.callers_promisers}, cf_null }, policy => "ifdefined";
"class_prefix" string => canonify(join("_", "promisers"));
"args" slist => { "${service_regex}" };

classes:
any::
"pass2" expression => "pass1";
"pass1" expression => "any";

methods:
pass2::
"success_classes"
usebundle => _classes_success("${old_class_prefix}"),
ifvarclass => "${old_class_prefix}_checked_ok";

"success_classes"
usebundle => _classes_success("${class_prefix}"),
ifvarclass => "has_promiser_stack.${class_prefix}_checked_ok";

"error_classes"
usebundle => _classes_failure("${old_class_prefix}"),
ifvarclass => "${old_class_prefix}_checked_not_ok";
"check_active" usebundle => ncf_services("${service_regex}", "is-active-process");

"error_classes"
usebundle => _classes_failure("${class_prefix}"),
ifvarclass => "has_promiser_stack.${class_prefix}_checked_not_ok";
"class copy" usebundle => _classes_copy("ncf_services_${canonified_service_regex}_is_active_process", "${old_class_prefix}"),
ifvarclass => "ncf_services_${canonified_service_regex}_is_active_process_reached";
"new result classes" usebundle => _classes_copy("${class_prefix}_check_active", "${class_prefix}"),
ifvarclass => "${class_prefix}_check_active_reached";

"report"
usebundle => _log("Check if the service ${service_regex} is started using ps", "${old_class_prefix}", "${class_prefix}", @{args});

processes:

"${service_regex}"
process_count => any_count_two("${old_class_prefix}_checked_ok", "${class_prefix}_checked_ok");

"${service_regex}"
# missing new_class_prefix : we cannot put 2 classes here, so we put the only one that we are sure works
restart_class => "${old_class_prefix}_checked_not_ok";

}
Loading

0 comments on commit 3fbda7e

Please sign in to comment.