From 440978c6ad55936fc3407cda7f2c29aa6c4740cd Mon Sep 17 00:00:00 2001 From: Craig Comstock Date: Fri, 18 Oct 2024 11:21:46 -0500 Subject: [PATCH] Added support for AIX System Resource Controller services promises On AIX the default will use AIX System Resource Controller commands to manage service state. bundle agent main { services: "sendmail" service_policy => "start"; } service_policy options supported are: start, stop and reload. Ticket: CFE-4447 Changelog: title --- lib/paths.cf | 3 ++ lib/services.cf | 83 +++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 83 insertions(+), 3 deletions(-) diff --git a/lib/paths.cf b/lib/paths.cf index 434a17c836..0748c8723a 100644 --- a/lib/paths.cf +++ b/lib/paths.cf @@ -168,6 +168,7 @@ bundle common paths "path[find]" string => "/usr/bin/find"; "path[grep]" string => "/usr/bin/grep"; "path[ls]" string => "/usr/bin/ls"; + "path[lssrc]" string => "/usr/bin/lssrc"; "path[netstat]" string => "/usr/bin/netstat"; "path[oslevel]" string => "/usr/bin/oslevel"; "path[ping]" string => "/usr/bin/ping"; @@ -175,6 +176,8 @@ bundle common paths "path[printf]" string => "/usr/bin/printf"; "path[sed]" string => "/usr/bin/sed"; "path[sort]" string => "/usr/bin/sort"; + "path[startsrc]" string => "/usr/bin/startsrc"; + "path[stopsrc]" string => "/usr/bin/stopsrc"; "path[tr]" string => "/usr/bin/tr"; "path[yum]" string => "/usr/bin/yum"; diff --git a/lib/services.cf b/lib/services.cf index 482e54709f..0787511103 100644 --- a/lib/services.cf +++ b/lib/services.cf @@ -111,11 +111,13 @@ bundle agent standard_services(service,state) # # Else, if chkconfig is present, it will be used. # -# Else, if the service command is available, if will be used. +# Else, if the service command is available, it will be used. # -# Else, if the svcadm command is available, if will be used. Note you +# Else, if the svcadm command is available, it will be used. Note you # have to supply the full SMF service identifier. # +# Else, if lssrc command is available (AIX), it will be used. +# # Else, control is passed to `classic_services`. # # Note you do **not** have to call this bundle from `services` @@ -170,7 +172,9 @@ bundle agent standard_services(service,state) "chkconfig" expression => "!systemd._stdlib_path_exists_chkconfig"; "sysvservice" expression => "!systemd.!chkconfig._stdlib_path_exists_service"; "smf" expression => "!systemd.!chkconfig.!sysvservice._stdlib_path_exists_svcadm"; - "fallback" expression => "!systemd.!chkconfig.!sysvservice.!smf"; + # AIX System Resource Controller https://www.ibm.com/docs/en/aix/7.2?topic=concepts-system-resource-controller + "aix_src" expression => "_stdlib_path_exists_lssrc"; + "fallback" expression => "!systemd.!chkconfig.!sysvservice.!smf.!aix_src"; "have_init" expression => fileexists($(init)); @@ -268,6 +272,8 @@ bundle agent standard_services(service,state) classes => kept_successful_command; methods: + aix_src:: + "aix_service" usebundle => aix_services($(service), $(state)); fallback:: "classic" usebundle => classic_services($(service), $(state)); @@ -1098,3 +1104,74 @@ bundle agent classic_services(service,state) "DEBUG $(this.bundle): The baseinit is NOT provided, using default" if => not(isvariable("baseinit[$(service)]")); } + +body service_method aix_service_method +{ + service_bundle => aix_services("$(this.promiser)","$(this.service_policy)"); +} + +# example of querying state of a service on AIX +# +# bash-5.1# /usr/bin/lssrc -s sendmail +# Subsystem Group PID Status +# sendmail mail 5308762 active +# +# according to https://docs.cfengine.com/docs/3.24/reference-promise-types-services.html#service_policy +# state can be one of start, stop, enable, disable, restart and reload. +# disable/enable might be available for services in /etc/inetd.conf +# e.g. https://www.ibm.com/support/pages/ibm-aix-how-disable-rsh-and-rlogin-services +# /usr/bin/lssrc -t login, comment out lines in /etc/inetd.conf +# +# Note: This service method bundle does NOT handle inetd services like rsh/rlogin +# only subsystems aka those services listed with /usr/bin/lssrc -a +# https://www.ibm.com/docs/en/aix/7.3?topic=daemons-subsystems-subservers +# +# Also note this from the lssrc man page: +# The lssrc command output can sometimes show two entries for a particular daemon. One instance will be active and another instance will be +# inoperative. This can happen if the subsystem is modified (using the mkssys command or chssys command) without stopping the subsystem. The +# original subsystem will remain active and the modified instance will be inoperative until the subsystem is stopped and started again. +# +# Additional output may appear prefixed with Q: for example if it takes some time to change the service state: +# +# notice: Q: "...in/stopsrc -s s": 0513-056 Timeout waiting for command response. If you specified a foreign host, +# Q: "...in/stopsrc -s s": see the /etc/inittab file on the foreign host to verify that the SRC daemon +# Q: "...in/stopsrc -s s": (srcmstr) was started with the -r flag to accept remote requests. +# Q: "...in/stopsrc -s s": 0513-059 The sendmail Subsystem has been started. Subsystem PID is 13042068. +# +# Another failure case. Likely on next agent run (default of 5 minutes) the service will have stopped or we will try again. +# error: Finished command related to promiser '/usr/bin/stopsrc -s sendmail' -- an error occurred, returned 1 +# notice: Q: "...in/stopsrc -s s": 0513-056 Timeout waiting for command response. If you specified a foreign host, +# Q: "...in/stopsrc -s s": see the /etc/inittab file on the foreign host to verify that the SRC daemon +# Q: "...in/stopsrc -s s": (srcmstr) was started with the -r flag to accept remote requests. +bundle agent aix_services(service, desired_state) +{ + vars: + # current state can be: active, inoperative, stopping + "current_state" string => execresult("$(paths.lssrc) -s $(service) | tail -1 | awk '{print $NF}'", useshell); + + classes: + "needs_start" expression => and( + strcmp("$(current_state)", "inoperative"), + strcmp("$(desired_state)", "start") + ); + "needs_restart" expression => and( + strcmp("$(desired_state)", "restart") + ); + "needs_stop" expression => and( + strcmp("$(current_state)", "active"), + strcmp("$(desired_state)", "stop") + ); + + commands: + needs_start:: + "$(paths.startsrc) -s $(service)"; + needs_restart:: + "$(paths.stopsrc) -s $(service); $(paths.startsrc) -s $(service)" + contain => useshell; + needs_stop:: + "$(paths.stopsrc) -s $(service)"; + + reports: + DEBUG:: + "Current state of service $(service) is $(current_state). Desired state is $(desired_state)."; +}