diff options
Diffstat (limited to 'heartbeat/azure-lb')
-rwxr-xr-x | heartbeat/azure-lb | 229 |
1 files changed, 229 insertions, 0 deletions
diff --git a/heartbeat/azure-lb b/heartbeat/azure-lb new file mode 100755 index 0000000..7f585bf --- /dev/null +++ b/heartbeat/azure-lb @@ -0,0 +1,229 @@ +#!/bin/sh +# + +# License: GNU General Public License (GPL) +# (c) 2017 O. Albrigtsen +# and Linux-HA contributors +# +# ----------------------------------------------------------------------------- +# O C F R E S O U R C E S C R I P T S P E C I F I C A T I O N +# ----------------------------------------------------------------------------- +# +# NAME +# azure-lb : OCF resource agent script for Azure Load Balancer +# +# Initialization: +: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat} +. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs + +# Defaults +if is_suse_based; then + OCF_RESKEY_nc_default="/usr/bin/socat" +else + OCF_RESKEY_nc_default="/usr/bin/nc" +fi + +OCF_RESKEY_port_default="61000" + +: ${OCF_RESKEY_nc=${OCF_RESKEY_nc_default}} +: ${OCF_RESKEY_port=${OCF_RESKEY_port_default}} + +process="$OCF_RESOURCE_INSTANCE" +pidfile="/var/run/$OCF_RESOURCE_INSTANCE.pid" + + +lb_usage() { + cat <<END + usage: $0 (start|stop|validate-all|meta-data|help|usage|monitor) + $0 manages service that answers Azure Load Balancer health probe requests as a OCF HA resource. + The 'start' operation starts the instance. + The 'stop' operation stops the instance. + The 'monitor' operation reports whether the instance seems to be working + The 'validate-all' operation reports whether the parameters are valid +END +} + +lb_metadata() { +cat <<END +<?xml version="1.0"?> +<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd"> +<resource-agent name="azure-lb" version="1.0"> +<version>1.0</version> +<longdesc lang="en"> +Resource agent to answer Azure Load Balancer health probe requests +</longdesc> +<shortdesc lang="en">Answers Azure Load Balancer health probe requests</shortdesc> + +<parameters> + +<parameter name="nc"> +<longdesc lang="en"> +The full path of the used binary. This can be nc or socat path. +The default is /usr/bin/nc and /usr/bin/socat for SUSE distributions. +</longdesc> +<shortdesc lang="en">Full path of the used binary (nc or socat are allowed)</shortdesc> +<content type="string" default="${OCF_RESKEY_nc_default}"/> +</parameter> + +<parameter name="port"> +<longdesc lang="en"> +Port to listen to. +</longdesc> +<shortdesc lang="en">Listen to port</shortdesc> +<content type="string" default="${OCF_RESKEY_port_default}"/> +</parameter> + +</parameters> + +<actions> +<action name="start" timeout="20s" /> +<action name="stop" timeout="20s" /> +<action name="monitor" depth="0" timeout="20s" interval="10s" /> +<action name="meta-data" timeout="5s" /> +<action name="validate-all" timeout="5s" /> +</actions> +</resource-agent> +END +exit 0 +} + +getpid() { + grep -o '[0-9]*' $1 +} + +lb_monitor() { + if test -f "$pidfile"; then + [ "$__OCF_ACTION" = "stop" ] && level="debug" || level="err" + + if pid=$(getpid "$pidfile") && [ -n "$pid" ]; then + output=$(kill -s 0 "$pid" 2>&1) + mon_rc=$? + + [ -n "$output" ] && ocf_log "$level" "$output" + [ "$mon_rc" -eq 0 ] && return $OCF_SUCCESS + fi + + # pidfile w/o process means the process died + return $OCF_ERR_GENERIC + else + return $OCF_NOT_RUNNING + fi +} + +lb_start() { + cmd="$OCF_RESKEY_nc -l -k $OCF_RESKEY_port" + if [ $( basename $OCF_RESKEY_nc ) = 'socat' ]; then + #socat has different parameters + cmd="$OCF_RESKEY_nc -U TCP-LISTEN:$OCF_RESKEY_port,backlog=10,fork,reuseaddr /dev/null" + fi + if ! lb_monitor; then + ocf_log debug "Starting $process: $cmd" + # Execute the command as created above + $cmd >/dev/null 2>&1 & + echo $! > $pidfile + if lb_monitor; then + ocf_log debug "$process: $cmd started successfully, calling monitor" + lb_monitor + return $? + else + ocf_log err "$process: $cmd could not be started" + return $OCF_ERR_GENERIC + fi + else + # If already running, consider start successful + ocf_log debug "$process: $cmd is already running" + return $OCF_SUCCESS + fi +} + +lb_stop() { + stop_rc=$OCF_SUCCESS + + if [ -n "$OCF_RESKEY_CRM_meta_timeout" ]; then + # Allow 2/3 of the action timeout for the orderly shutdown + # (The origin unit is ms, hence the conversion) + stop_timeout=$((OCF_RESKEY_CRM_meta_timeout/1500)) + else + stop_timeout=10 + fi + + if lb_monitor; then + pid=`getpid $pidfile` + kill $pid + + i=0 + while [ $i -lt $stop_timeout ]; do + if ! lb_monitor; then + rm -f $pidfile + return $OCF_SUCCESS + fi + sleep 1 + i=$((i+1)) + done + + ocf_log warn "Stop with SIGTERM failed/timed out, now sending SIGKILL." + kill -s 9 $pid + while :; do + if ! lb_monitor; then + ocf_log warn "SIGKILL did the job." + stop_rc=$OCF_SUCCESS + break + fi + ocf_log info "The job still hasn't stopped yet. Waiting..." + sleep 1 + done + fi + rm -f $pidfile + return $stop_rc +} + +lb_validate() { + check_binary "$OCF_RESKEY_nc" + + if ! ocf_is_decimal "$OCF_RESKEY_port"; then + ocf_exit_reason "$OCF_RESKEY_port is not a valid port" + exit $OCF_ERR_CONFIGURED + fi + + return $OCF_SUCCESS +} + +############################################################################### +# +# MAIN +# +############################################################################### + +case $__OCF_ACTION in + meta-data) + lb_metadata + exit $OCF_SUCCESS + ;; + usage|help) + lb_usage + exit $OCF_SUCCESS + ;; +esac + +if ! ocf_is_root; then + ocf_log err "You must be root for $__OCF_ACTION operation." + exit $OCF_ERR_PERM +fi + +case $__OCF_ACTION in + start) + lb_validate + lb_start;; + stop) + lb_stop;; + monitor) + lb_monitor;; + validate-all) + lb_validate;; + *) + echo $USAGE + exit $OCF_ERR_UNIMPLEMENTED + ;; +esac + +exit $? |