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

kamailio: systemd and register monitoring #1550

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
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
232 changes: 166 additions & 66 deletions heartbeat/kamailio.in
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@
# OCF_RESKEY_kamuser
# OCF_RESKEY_kamgroup
# OCF_RESKEY_extra_options
# OCF_RESKEY_systemd
# OCF_RESKEY_register
# OCF_RESKEY_register_array

# Initialization:

Expand All @@ -62,6 +65,9 @@ RESKEY_kamctlrc_default="/etc/kamailio/kamctlrc"
RESKEY_kamuser_default=""
RESKEY_kamgroup_default=""
RESKEY_extra_options_default=""
RESKEY_systemd_default=false
RESKEY_register_default=false
RESKEY_register_array_default="127.0.0.1;100;test.domain.com;sip1234"

#######################################################################
: ${OCF_RESKEY_binary=${RESKEY_binary_default}}
Expand All @@ -76,6 +82,9 @@ RESKEY_extra_options_default=""
: ${OCF_RESKEY_kamuser=${RESKEY_kamuser_default}}
: ${OCF_RESKEY_kamgroup=${RESKEY_kamgroup_default}}
: ${OCF_RESKEY_extra_options=${RESKEY_extra_options_default}}
: ${OCF_RESKEY_systemd=${RESKEY_systemd_default}}
: ${OCF_RESKEY_register=${RESKEY_register_default}}
: ${OCF_RESKEY_register_array=${RESKEY_register_array_default}}

#######################################################################
usage() {
Expand Down Expand Up @@ -161,9 +170,9 @@ Parameters for a third Kamailio instance:
Usually the same IP address value as for parameter listen_address should be
provided.

In order to respond with a 200 OK response to the SIP OOPTION requests,
In order to respond with a 200 OK response to the SIP OPTION requests,
the kamailio.cfg file needs to contain following section:
Note: The following "kamailio.cfg" code snippet is part of an XML section.
Note: The following "kamailio.cfg" code snippet is part of an XML section.
Therefore it contains two & characters, which need to be replaced
with two ampersand characters within "kamailio.cfg":

Expand All @@ -181,7 +190,7 @@ Parameters for a third Kamailio instance:
<content type="string" default="${RESKEY_monitoring_ip_default}" />
</parameter>

<parameter name="listen_address" unique="0" required="1">
<parameter name="listen_address" unique="0" required="0">
<longdesc lang="en">
SIP IP address the kamailio will listen on.
</longdesc>
Expand Down Expand Up @@ -234,6 +243,19 @@ Parameters for a third Kamailio instance:
<content type="string" default="${RESKEY_kamctl_default}" />
</parameter>

<parameter name="systemd" unique="0" required="0">
<longdesc lang="en">
If systemd is used for management of the Kamailio process, its possible to keep it,
setting systemd=true.
Consider that in this case, all other parameters are overridden and should be defined
inside Kamailio systemd definition, with exception of pidfile and monitoring_ip
are used for monitoring and may be defined.
</longdesc>
<shortdesc lang="en">systemd management</shortdesc>
<content type="boolean" default="${RESKEY_systemd_default}" />
</parameter>


<parameter name="kamctlrc" unique="0" required="0">
<longdesc lang="en">
The location of the "kamctlrc" file for the Kamailio instance.
Expand Down Expand Up @@ -283,6 +305,32 @@ Parameters for a third Kamailio instance:
<shortdesc lang="en">kamailio group</shortdesc>
<content type="string" default="${RESKEY_kamgroup_default}" />
</parameter>

<parameter name="register" unique="0" required="0">
<longdesc lang="en">
Monitor if kamailio can register an extension. In some cases, kamailio responds to options
but is not possible to register an extension. Uses UDP to send the register message.
If enabled, use register_array to set the register parameters.
</longdesc>
<shortdesc lang="en">enable extension register</shortdesc>
<content type="string" default="${RESKEY_register_default}" />
</parameter>

<parameter name="register_array" unique="0" required="0">
<longdesc lang="en">
The extension parameters to use in the registration monitoring. It is possible to set multiple
extensions to test.
The extensions must be separated by a space (" "), each extension
containing the following parameters, separated by a semicolon:
Socket IP: The kamailio interface to send the register to (Ex:127.0.0.1);
Extension: The extension;
Domain: The domain to register the extension;
Extension password: The password of the extension;
Ex: "127.0.0.1;1000;test.domain.com;sip1234 192.168.0.1;2000;test.domain.com;sip5678"
</longdesc>
<shortdesc lang="en">register extension</shortdesc>
<content type="string" default="${RESKEY_register_array_default}" />
</parameter>
</parameters>

<actions>
Expand Down Expand Up @@ -401,20 +449,27 @@ kamailio_cmd()
kamailio_get_pid() {
if [ -f ${OCF_RESKEY_pidfile} ]; then
PID=`head -n 1 $OCF_RESKEY_pidfile`
if [ ! -z "$PID" ]; then
#Cross check if the PID file really contains a process of our kamailio instance:
kamailio_cmd
CROSSPID=`pgrep -o -f "${kam_cmd}"`
if [ x"$PID" == x"$CROSSPID" ]; then
#ocf_log debug "Found kamailio process PID with value: $PID."
return 0
fi
#ocf_log debug "PID file does not contain a PID of a $OCF_RESKEY_binary process!"

if [ -z "$PID" ]; then
#PID file does not contain a valid PID
rm -f ${OCF_RESKEY_pidfile}
return 2
fi

#PID file does not contain a valid PID
rm -f ${OCF_RESKEY_pidfile}
# if systemd is defined, one can not validate our own kamailio instance
if [ $OCF_RESKEY_systemd == true ]; then
#ocf_log debug "Found kamailio process PID with value: $PID."
return 0
fi

#Cross check if the PID file really contains a process of our kamailio instance:
kamailio_cmd
CROSSPID=`pgrep -o -f "${kam_cmd}"`
if [ x"$PID" == x"$CROSSPID" ]; then
#ocf_log debug "Found kamailio process PID with value: $PID."
return 0
fi
#ocf_log debug "PID file does not contain a PID of a $OCF_RESKEY_binary process!"
return 2
fi

Expand Down Expand Up @@ -459,7 +514,7 @@ kamailio_status() {
fi

rc=0
# In case that OCF_RESKEY_kamctlrc we perfom a health check via "kamctl monitor 1"
# In case that OCF_RESKEY_kamctlrc we perform a health check via "kamctl monitor 1"
if [ ! -z ${OCF_RESKEY_kamctlrc} ]; then
# PID is running now but it is not save to check via kamctl without care, because
# the implementation analysis in the case that we kill all running processes
Expand Down Expand Up @@ -499,9 +554,39 @@ kamailio_status() {
rm -f $errorfile

if [ $result -ne 0 ]; then
ocf_log $not_running_log_level "Kamailio is running, but not functional as sipsak ${OCF_RESKEY_proto} failed with $(kamailio_format_result $result "$output" "$error")"
ocf_log $not_running_log_level "Kamailio is running, but not functional as sipsak OPTIONS ${OCF_RESKEY_proto} failed with $(kamailio_format_result $result "$output" "$error")"
return $OCF_ERR_GENERIC
fi

# Checks if it is possible to register an extension.
if [ ${OCF_RESKEY_register} == true ]; then
# Iterate on the extensions array
for extension in ${OCF_RESKEY_register_array[@]}; do
# Split the extension parameters into an array:
# Ex: "127.0.0.1;100;test.domain.com;sip1234" -> ("127.0.0.1" "100" "test.domain.com" "sip1234")
IFS=';' read -ra EXTADDR <<< "$extension"
reg_hostname=${EXTADDR[0]}
reg_extension=${EXTADDR[1]}
reg_domain=${EXTADDR[2]}
[[ -z ${EXTADDR[3]} ]] && reg_password="" || reg_password="-a ${EXTADDR[3]}"

# Builds sipsak usrloc-mode string.
reg_forced_timeout="timeout 3"
reg_sipsak_opts="-U -d -x 5 -p $reg_hostname -H $reg_hostname"
reg_sip_uri="-s sip:$reg_extension@$reg_domain"
output=`${reg_forced_timeout} $OCF_RESKEY_sipsak ${reg_sipsak_opts} ${reg_sip_uri} ${reg_password}>/dev/null 2>>$errorfile`
result=$?

error=`cat $errorfile`
rm -f $errorfile
# If cannot register the extension, raise an OCF_ERR
if [ $result -ne 0 ]; then
ocf_log $not_running_log_level "Kamailio is running, but not functional as sipsak REGISTER ${OCF_RESKEY_proto} failed with $(kamailio_format_result $result "$output" "$error")"
return $OCF_ERR_GENERIC
fi
echo "RESULT: $result"
done
fi

return $OCF_SUCCESS
}
Expand Down Expand Up @@ -529,17 +614,25 @@ kamailio_start() {
fi
fi

kamailio_cmd
if [ "$OCF_RESKEY_kamuser" != "" ]; then
kam_cmd="su -s @BASH_SHELL@ $OCF_RESKEY_kamuser -c \"$kam_cmd\""
fi
if
$OCF_RESKEY_systemd
then
ocf_log info "start kamailio with systemd."
systemctl start kamailio
result=$?
else
kamailio_cmd
if [ "$OCF_RESKEY_kamuser" != "" ]; then
kam_cmd="su -s @BASH_SHELL@ $OCF_RESKEY_kamuser -c \"$kam_cmd\""
fi

ocf_log info "start kamailio with $kam_cmd."
errorfile=`mktemp`
output=$(eval ${kam_cmd} 2>>$errorfile)
result=$?
error=`cat $errorfile`
rm -f $errorfile
ocf_log info "start kamailio with $kam_cmd."
errorfile=`mktemp`
output=$(eval ${kam_cmd} 2>>$errorfile)
result=$?
error=`cat $errorfile`
rm -f $errorfile
fi

if [ $result -eq 0 ]; then
result=1
Expand Down Expand Up @@ -573,59 +666,66 @@ kamailio_stop() {
local TRIES=0
result=$OCF_SUCCESS

kamailio_cmd
if
$OCF_RESKEY_systemd
then
ocf_log info "stop kamailio with systemd."
systemctl stop kamailio
else
kamailio_cmd

ocf_log info "Stopping kamailio by sending SIGTERM to ${kam_cmd}"
pkill -SIGTERM -x -f "${kam_cmd}"
if [ $? -eq 1 ]; then
# already stopped. no processes found
# in case of not specified pidfile, delete the created directory
# otherwise only the pidfile itself
if [ "${OCF_RESKEY_pidfile}" == "${RESKEY_pidfile_default}" ]; then
piddir=`dirname "${OCF_RESKEY_pidfile}"`
rm -rf "$piddir"
else
rm -f "${OCF_RESKEY_pidfile}"
fi
return $result
fi

ocf_log info "Stopping kamailio by sending SIGTERM to ${kam_cmd}"
pkill -SIGTERM -x -f "${kam_cmd}"
if [ $? -eq 1 ]; then
# already stopped. no processes found
# in case of not specified pidfile, delete the created directory
# otherwise only the pidfile itself
if [ "${OCF_RESKEY_pidfile}" == "${RESKEY_pidfile_default}" ]; then
piddir=`dirname "${OCF_RESKEY_pidfile}"`
rm -rf "$piddir"
if [ "$OCF_RESKEY_CRM_meta_timeout" != "" ]; then
KAMAILIO_STOP_TIMEOUT=$(( ($OCF_RESKEY_CRM_meta_timeout/1000) - 7 ))
else
rm -f "${OCF_RESKEY_pidfile}"
KAMAILIO_STOP_TIMEOUT=20
fi
return $result
fi

if [ "$OCF_RESKEY_CRM_meta_timeout" != "" ]; then
KAMAILIO_STOP_TIMEOUT=$(( ($OCF_RESKEY_CRM_meta_timeout/1000) - 7 ))
else
KAMAILIO_STOP_TIMEOUT=20
fi

while isRunning_cmd "${kam_cmd}" && [ "$TRIES" -lt "${KAMAILIO_STOP_TIMEOUT}" ]
do
sleep 1
ocf_log info "kamailio ${kam_cmd} is still running after SIGTERM"
((TRIES++))
done

isRunning_cmd "${kam_cmd}"
RET=$?

if [ "$RET" -eq 0 ]; then
ocf_log info "Killing ${kam_cmd} with SIGKILL"
TRIES=0
pkill -SIGKILL -x -f "${kam_cmd}" > /dev/null 2>&1

while isRunning_cmd "${kam_cmd}" && [ "$TRIES" -lt 3 ]
while isRunning_cmd "${kam_cmd}" && [ "$TRIES" -lt "${KAMAILIO_STOP_TIMEOUT}" ]
do
sleep 1
ocf_log info "kamailio ${kam_cmd} is still running after SIGKILL"
ocf_log info "kamailio ${kam_cmd} is still running after SIGTERM"
((TRIES++))
done

isRunning_cmd "${kam_cmd}"
RET=$?

if [ "$RET" -eq 0 ]; then
ocf_log fatal "kamailio is still running even after SIGKILL"
result=$OCF_ERR_GENERIC
ocf_log info "Killing ${kam_cmd} with SIGKILL"
TRIES=0
pkill -SIGKILL -x -f "${kam_cmd}" > /dev/null 2>&1

while isRunning_cmd "${kam_cmd}" && [ "$TRIES" -lt 3 ]
do
sleep 1
ocf_log info "kamailio ${kam_cmd} is still running after SIGKILL"
((TRIES++))
done

isRunning_cmd "${kam_cmd}"
RET=$?
if [ "$RET" -eq 0 ]; then
ocf_log fatal "kamailio is still running even after SIGKILL"
result=$OCF_ERR_GENERIC
fi
else
ocf_log info "${kam_cmd} has stopped."
fi
else
ocf_log info "${kam_cmd} has stopped."
fi

# in case of not specified pidfile, delete the created directory
Expand Down