Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes #7192: Rewrite the service_* methods #544

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#######################################################
#
# Manually stop service, start it using ncf and check
# if it's been started
#
#######################################################

bundle common acc_path
{
vars:
"root" string => getenv("NCF_TESTS_ACCEPTANCE", 1024);
}

body common control
{
inputs => { "${acc_path.root}/default.cf.sub", "${acc_path.root}/default_ncf.cf.sub", "@{ncf_inputs.default_files}" };
bundlesequence => { configuration, default("${this.promise_filename}") };
version => "1.0";
}

#######################################################

bundle agent init
{
vars:
!aix::
"service_name" string => "cron";
aix::
"service_name" string => "syslogd";

commands:
"/usr/sbin/service ${service_name} stop";
}

#######################################################

bundle agent test
{
methods:
"ph1" usebundle => service_ensure_running("${init.service_name}");
}

#######################################################

bundle agent check
{
vars:
"command_ps" string => "/bin/ps afux | /bin/grep ${init.service_name} | /bin/grep -v grep";

classes:
"service_running" expression => returnszero("${command_ps}", "useshell"),
ifvarclass => "service_ensure_running_${init.service_name}_reached";

"ok" expression => "service_running.(service_ensure_running_${init.service_name}_repaired.!service_ensure_running_${init.service_name}_error)";

reports:
ok::
"$(this.promise_filename) Pass";
!ok::
"$(this.promise_filename) FAIL";
!service_running::
"Service ${init.service_name} was not detected as running using ${command_ps} command";

}
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});
}
Loading