Project

General

Profile

Download (13.4 KB) Statistics
| Branch: | Tag: | Revision:
#####################################################################################
# Copyright 2011 Normation SAS
#####################################################################################
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#####################################################################################

# Enforce the defined services parameters

bundle agent services_management
{
vars:

&SERVICE_MANAGED_NAME:{name |"service[&i&][name]" string => "&name&";
}&
&SERVICE_MANAGED_NAME:{name |"service[&i&][canon_name]" string => canonify("&name&");
}&
&PROCESS_MANAGED_NAME:{process |"service[&i&][process]" string => "&process&";
}&
&PROCESS_MANAGED_RUNNING:{running |"service[&i&][running]" string => "&running&";
}&
&PROCESS_MANAGED_KILLING_METHOD:{kill |"service[&i&][killMethod]" string => "&kill&";
}&
&PROCESS_MANAGED_MIN_INSTANCES:{min_instance |"service[&i&][min_instance]" string => "&min_instance&";
}&
&PROCESS_MANAGED_MAX_INSTANCES:{max_instance |"service[&i&][max_instance]" string => "&max_instance&";
}&
&TRACKINGKEY:{piuuid |"service[&i&][uuid]" string => "&piuuid&";
}&

"index" slist => getindices("service");

classes:
&PROCESS_MANAGED_NAME:{name |"defined_process_name_&i&" not => strcmp("&name&", "");
}&
&PROCESS_MANAGED_CHECK_RANGE:{check |"check_process_range_&i&" expression => strcmp("&check&", "true");
}&
&PROCESS_MANAGED_RUNNING:{running |"start_process_&i&" expression => strcmp("&running&", "true");
}&
&PROCESS_MANAGED_RUNNING:{running |"stop_process_&i&" expression => strcmp("&running&", "false");
}&
&PROCESS_MANAGED_KILLING_METHOD:{kill |"graceful_stop_process_&i&" expression => strcmp("&kill&", "graceful");
}&
&PROCESS_MANAGED_KILLING_METHOD:{kill |"term_stop_process_&i&" expression => strcmp("&kill&", "term");
}&
&PROCESS_MANAGED_KILLING_METHOD:{kill |"kill_stop_process_&i&" expression => strcmp("&kill&", "kill");
}&
&PROCESS_MANAGED_BOOTSTART:{bootstart |"bootstart_process_&i&" expression => strcmp("&bootstart&", "true");
}&
&PROCESS_MANAGED_BOOTSTART:{bootstart |"bootstart_prevent_process_&i&" expression => strcmp("&bootstart&", "false");
}&

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

files:

debian::

"/etc/rc2.d/S.*${service[${index}][name]}.*"
create => "true",
action => WarnOnly,
classes => if_else("service_${index}_bootstarted", "service_${index}_unbootstarted");

methods:

pass2::

"bootstart_process" usebundle => service_ensure_started_at_boot("${service[${index}][name]}"),
ifvarclass => "bootstart_process_${index}";

"unbootstart_process" usebundle => service_ensure_stopped("${service[${index}][name]}"),
ifvarclass => "bootstart_prevent_process_${index}|stop_process_${index}";


# On Windows, we can't use processes: promises to detect the current status, so
# we just call the service_{start,stop} bundles to ensure service state
"start_process" usebundle => service_start("${service[${index}][name]}"),
ifvarclass => "(process_${index}_restart|windows).start_process_${index}";

"stop_process" usebundle => service_stop("${service[${index}][name]}"),
ifvarclass => "(!process_${index}_restart|windows).stop_process_${index}";

"restart_process" usebundle => service_restart("${service[${index}][name]}"),
ifvarclass => canonify("${service[${index}][name]}_out_of_range");

pass3::

"any" usebundle => rudder_common_report("ServicesManagement", "result_success", "${service[${index}][uuid]}", "Process", "${service[${index}][name]}", "${service[${index}][name]} didn't need to have its process checked"),
ifvarclass => "!start_process_${index}.!stop_process_${index}";

# On windows, we don't use processes promises type to check if process are running, as we rely directly on services
!windows::
"any" usebundle => rudder_common_report("ServicesManagement", "result_error", "${service[${index}][uuid]}", "Process", "${service[${index}][name]}", "Cannot check the status of ${service[${index}][name]}: the process name is not filed"),
ifvarclass => "!defined_process_name_${index}.(start_process_${index}|stop_process_${index})";

"any" usebundle => rudder_common_report("ServicesManagement", "result_success", "${service[${index}][uuid]}", "Process", "${service[${index}][name]}", "Process of ${service[${index}][name]} is running"),
ifvarclass => "service_${index}_running.!service_${index}_anomaly.!process_${index}_restart.start_process_${index}";

"any" usebundle => rudder_common_report("ServicesManagement", "result_repaired", "${service[${index}][uuid]}", "Process", "${service[${index}][name]}", "Process of ${service[${index}][name]} was not running and has been restarted"),
ifvarclass => concat("process_${index}_restart", ".", "start_process_${index}", ".", canonify("service_start_${service[${index}][name]}_repaired");

"any" usebundle => rudder_common_report("ServicesManagement", "result_error", "${service[${index}][uuid]}", "Process", "${service[${index}][name]}", "${service[${index}][name]}: the process couldn't be started"),
ifvarclass => canonify("service_start_${service[${index}][name]}_not_ok");

"any" usebundle => rudder_common_report("ServicesManagement", "result_success", "${service[${index}][uuid]}", "Process", "${service[${index}][name]}", "Process of ${service[${index}][name]} is not running"),
ifvarclass => "stop_process_${index}.process_${index}_restart.graceful_stop_process_${index}";

"any" usebundle => rudder_common_report("ServicesManagement", "result_repaired", "${service[${index}][uuid]}", "Process", "${service[${index}][name]}", "Process of ${service[${index}][name]} was stopped"),
ifvarclass => concat("stop_process_${index}", ".!", "process_${index}_restart", ".", canonify("service_stop_${service[${index}][name]}_repaired"), ".", "graceful_stop_process_${index}");

"any" usebundle => rudder_common_report("ServicesManagement", "result_error", "${service[${index}][uuid]}", "Process", "${service[${index}][name]}", "${service[${index}][name]}: the process could't be stopped"),
ifvarclass => concat("stop_process_${index}", ".!", "process_${index}_restart", ".", canonify("service_stop_${service[${index}][name]}_not_ok"));


"any" usebundle => rudder_common_report("ServicesManagement", "result_success", "${service[${index}][uuid]}", "Process", "${service[${index}][name]}", "Process of ${service[${index}][name]} is not running"),
ifvarclass => "stop_process_${index}.service_${index}_already_stopped.!service_${index}_stopped.!graceful_stop_process_${index}";

"any" usebundle => rudder_common_report("ServicesManagement", "result_repaired", "${service[${index}][uuid]}", "Process", "${service[${index}][name]}", "Process of ${service[${index}][name]} was stopped"),
ifvarclass => "stop_process_${index}.service_${index}_stopped.!graceful_stop_process_${index}";

"any" usebundle => rudder_common_report("ServicesManagement", "result_error", "${service[${index}][uuid]}", "Process", "${service[${index}][name]}", "${service[${index}][name]}: the process count could't be stopped"),
ifvarclass => "stop_process_${index}.service_${index}_error.!graceful_stop_process_${index}";

# on windows, the generic methods are directly defining the correct classes, without relying on the process check before hand
windows::
"any" usebundle => rudder_common_reports_generic("ServicesManagement", "service_start_${service[${index}][canon_name]}", "${service[${index}][uuid]}", "Process", "${service[${index}][name]}", "Service ${service[${index}][name]} start" ),
ifvarclass => "start_process_${index}";
"any" usebundle => rudder_common_reports_generic("ServicesManagement", "service_stop_${service[${index}][canon_name]}", "${service[${index}][uuid]}", "Process", "${service[${index}][name]}", "Service ${service[${index}][name]} stop" ),
ifvarclass => "stop_process_${index}";

any::
"any" usebundle => rudder_common_report("ServicesManagement", "result_na", "${service[${index}][uuid]}", "Advanced options", "${service[${index}][name]}", "The process range is not to be checked for service ${service[${index}][name]}"),
ifvarclass => "!check_process_range_${index}";

# The number of process range is not checked on windows
!windows::
"any" usebundle => rudder_common_report("ServicesManagement", "result_error", "${service[${index}][uuid]}", "Advanced options", "${service[${index}][name]}", "The process range for service ${service[${index}][name]} cannot to be checked, for the process name is not set"),
ifvarclass => "check_process_range_${index}.!defined_process_name_${index}";


"any" usebundle => rudder_common_report("ServicesManagement", "result_success", "${service[${index}][uuid]}", "Advanced options", "${service[${index}][name]}", "The process range for service ${service[${index}][name]} is correct"),
ifvarclass => concat("check_process_range_${index}", ".", "defined_process_name_${index}", ".!", canonify("${service[${index}][canon_name]}_out_of_range"));


"any" usebundle => rudder_common_report("ServicesManagement", "result_repaired", "${service[${index}][uuid]}", "Advanced options", "${service[${index}][name]}", "The process range for service ${service[${index}][name]} was not correct, but was repaired"),
ifvarclass => concat("check_process_range_${index}", ".", "defined_process_name_${index}", ".", canonify("${service[${index}][canon_name]}_out_of_range"), ".", canonify("service_restart_${service[${index}][name]}_repaired"));


"any" usebundle => rudder_common_report("ServicesManagement", "result_error", "${service[${index}][uuid]}", "Advanced options", "${service[${index}][name]}", "The process range for service ${service[${index}][name]} was not correct, but was repaired"),
ifvarclass => concat("check_process_range_${index}", ".", "defined_process_name_${index}", ".", canonify("${service[${index}][canon_name]}_out_of_range"), ".", canonify("service_restart_${service[${index}][name]}_not_ok"));

windows::
"any" usebundle => rudder_common_report("ServicesManagement", "result_na", "${service[${index}][uuid]}", "Advanced options", "${service[${index}][name]}", "Checking the number of processes within a range is not implemened on Windows"),
ifvarclass => "check_process_range_${index}";


# Service boot starting parameters
any::
"any" usebundle => rudder_common_report("ServicesManagement", "result_na", "${service[${index}][uuid]}", "Service starting parameters", "${service[${index}][name]}", "${service[${index}][name]} starting parameters check not required"),
ifvarclass => "!bootstart_process_${index}.!bootstart_prevent_process_${index}";
"any" usebundle => rudder_common_report_generic("ServicesManagement", "service_ensure_started_at_boot_${service[${index}][name]}", "${service[${index}][uuid]}", "Service starting parameters", "${service[${index}][name]}", "The ${service[${index}][name]} boot starting configuration"),
ifvarclass => canonify("bootstart_process_${index}");
"any" usebundle => rudder_common_report_generic("ServicesManagement", "service_ensure_stopped_${service[${index}][name]}", "${service[${index}][uuid]}", "Service starting parameters", "${service[${index}][name]}", "The ${service[${index}][name]} boot starting configuration"),
ifvarclass => canonify("bootstart_prevent_process_${index}");


processes:
!windows::
# check the service status
"${service[${index}][process]}"
comment => "Check the process status",
restart_class => "process_${index}_restart",
classes => kept_if_else("service_${index}_running", "service_${index}_anomaly", "service_${index}_error"),
ifvarclass => "defined_process_name_${index}.(start_process_${index}|(stop_process_${index}.graceful_stop_process_${index}))";

# enforce that the process is stopped not so gracefully
"${service[${index}][process]}"
comment => "Stop not so gracefully the process",
signals => { "${service[${index}][killMethod]}" },
classes => kept_if_else("service_${index}_already_stopped", "service_${index}_stopped", "service_${index}_error"),
ifvarclass => "defined_process_name_${index}.stop_process_${index}.(term_stop_process_${index}|kill_stop_process_${index})";

# check the range
"${service[${index}][process]}"
comment => "Check the range of process",
process_count => check_range("${service[${index}][name]}", "${service[${index}][min_instance]}", "${service[${index}][max_instance]}"),
ifvarclass => "defined_process_name_${index}.check_process_range_${index}";

}
(3-3/3)