From 54895153bc296dcf44fa3f2a01bbb8afce300622 Mon Sep 17 00:00:00 2001 From: Daniel Gibbs Date: Wed, 2 Mar 2016 21:39:53 +0000 Subject: [PATCH] improvements to stop command improvements to graceful shutdown using functions more for easy reading --- functions/command_stop.sh | 295 ++++++++++++++++++++++---------------- 1 file changed, 169 insertions(+), 126 deletions(-) diff --git a/functions/command_stop.sh b/functions/command_stop.sh index d5d589beb..9d75fbc5a 100644 --- a/functions/command_stop.sh +++ b/functions/command_stop.sh @@ -9,40 +9,146 @@ lgsm_version="271215" local modulename="Stopping" function_selfname="$(basename $(readlink -f "${BASH_SOURCE[0]}"))" -sdtd_telnet(){ - sdtdshutdown=$( expect -c ' - proc abort {} { - puts "Timeout or EOF\n" - exit 1 - } - spawn telnet '"${telnetip}"' '"${telnetport}"' - expect { - "password:" { send "'"${telnetpass}"'\r" } - default abort - } - expect { - "session." { send "shutdown\r" } - default abort - } - expect { eof } - puts "Completed.\n" - ') +# Attempts Graceful of source using rcon 'quit' command. +fn_stop_graceful_source(){ +fn_print_dots "Graceful: rcon quit" +fn_scriptlog "Graceful: rcon quit" +# sends quit +tmux send -t "${servicename}" quit ENTER > /dev/null 2>&1 +# waits up to 30 seconds giving the server time to shutdown gracefuly +for seconds in {1..30}; do + pid=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -Ec "^${servicename}:") + if [ "${pid}" == "0" ]; then + fn_print_ok_nl "Graceful: rcon quit: ${seconds}" + fn_scriptlog "Graceful: rcon quit: OK: ${seconds} seconds" + break + fi + sleep 1 + fn_print_dots "Graceful: rcon quit: ${seconds}" +done +if [ "${pid}" != "0" ]; then + fn_print_fail_nl "Graceful: rcon quit" + fn_scriptlog "Graceful: rcon quit: FAIL" +fi +sleep 1 +} + +# Attempts Graceful of goldsource using rcon 'quit' command. +# Goldsource 'quit' command restarts rather than shutsdown +# this function will only wait 3 seconds then force a tmux shutdown. +# preventing the server from coming back online. +fn_stop_graceful_goldsource(){ +fn_print_dots "Graceful: rcon quit" +fn_scriptlog "Graceful: rcon quit" +# sends quit +tmux send -t "${servicename}" quit ENTER > /dev/null 2>&1 +# waits 3 seconds as goldsource servers restart with the quit command +for seconds in {1..3}; do + sleep 1 + fn_print_dots "Graceful: rcon quit: ${seconds}" +done +fn_print_ok_nl "Graceful: rcon quit: ${seconds}" +sleep 1 +} + +# Attempts Graceful of 7 Days To Die using telnet. +fn_stop_telnet_sdtd(){ +sdtdshutdown=$( expect -c ' +proc abort {} { + puts "Timeout or EOF\n" + exit 1 +} +spawn telnet '"${telnetip}"' '"${telnetport}"' +expect { + "password:" { send "'"${telnetpass}"'\r" } + default abort +} +expect { + "session." { send "shutdown\r" } + default abort +} +expect { eof } +puts "Completed.\n" +') +} + +fn_stop_graceful_sdtd(){ +# Gets server IP. +info_config.sh + +fn_print_dots "Graceful: telnet" +fn_scriptlog "Graceful: telnet" +sleep 1 + +# uses localhost on first attempt. +telnetip=127.0.0.1 +fn_print_dots "Graceful: telnet: ${telnetip}" +fn_scriptlog "Graceful: telnet: ${telnetip}" +fn_stop_telnet_sdtd +sleep 1 + +# falls back to the server ip if localhost fails. +refused=$(echo -en "\n ${sdtdshutdown}"| grep "Timeout or EOF") +if [ -n "${refused}" ]; then + fn_print_warn_nl "Graceful: telnet: localhost: " + fn_print_fail_eol + fn_scriptlog "Graceful: telnet: localhost: FAIL" + sleep 1 + + telnetip=${ip} + fn_print_dots "Graceful: telnet: ${telnetip}" + fn_scriptlog "Graceful: telnet: ${telnetip}" + fn_stop_telnet_sdtd + refused=$(echo -en "\n ${sdtdshutdown}"| grep "Timeout or EOF") + + fn_print_warnnl "Graceful: telnet: ${telnetip}: " + fn_print_fail_eol + fn_scriptlog "Graceful: telnet: ${telnetip}: FAIL" + sleep 1 +fi + +# Checks if attempts have worked. +completed=$(echo -en "\n ${sdtdshutdown}"| grep "Completed.") +if [ -n "${completed}" ]; then + fn_print_ok_nl "Graceful: telnet: " + fn_print_ok_eol + fn_scriptlog "Graceful: telnet: OK" +elif [ -n "${refused}" ]; then + fn_print_fail_nl "Graceful: telnet: " + fn_print_fail_eol + fn_scriptlog "Graceful: telnet: ${telnetip}: FAIL" + echo -en "\n\n" | tee -a "${scriptlog}" + echo -en "Telnet output:" | tee -a "${scriptlog}" + echo -en "\n ${sdtdshutdown}" | tee -a "${scriptlog}" + echo -en "\n\n" | tee -a "${scriptlog}" +else + fn_print_fail_nl "Graceful: telnet: Unknown error" + fn_scriptlog "Graceful: telnet: Unknown error" + echo -en "\n\n" | tee -a "${scriptlog}" + echo -en "Telnet output:" | tee -a "${scriptlog}" + echo -en "\n ${sdtdshutdown}" | tee -a "${scriptlog}" + echo -en "\n\n" | tee -a "${scriptlog}" +fi +} + +fn_stop_graceful_select(){ +if [ "${gamename}" == "7 Days to Die" ]; then + fn_stop_graceful_sdtd +elif [ "${engine}" == "source" ]; then + fn_stop_graceful_source +elif [ "${engine}" == "goldsource" ]; then + fn_stop_graceful_goldsource +else + fn_stop_tmux } fn_stop_teamspeak3(){ -check.sh fn_print_dots "${servername}" fn_scriptlog "${servername}" sleep 1 -info_ts3status.sh -if [ "${ts3status}" = "No server running (ts3server.pid is missing)" ]; then - fn_print_fail "${servername} is already stopped" - fn_scriptlog "${servername} is already stopped" -else - ${filesdir}/ts3server_startscript.sh stop > /dev/null 2>&1 - fn_print_ok "${servername}" - fn_scriptlog "Stopped ${servername}" -fi +${filesdir}/ts3server_startscript.sh stop > /dev/null 2>&1 +fn_print_ok "${servername}" +fn_scriptlog "Stopped ${servername}" # Remove lock file rm -f "${rootdir}/${lockselfname}" sleep 1 @@ -50,110 +156,47 @@ echo -en "\n" } fn_stop_tmux(){ -check.sh -info_config.sh fn_print_dots "${servername}" fn_scriptlog "${servername}" sleep 1 - -if [ "${gamename}" == "7 Days To Die" ] ; then - # if game is 7 Days To Die, we need special, graceful shutdown via telnet connection. - # Set below variable to be called for expect to operate correctly.. - fn_print_dots "Attempting graceful shutdown via telnet" - fn_scriptlog "Attempting graceful shutdown via telnet" - sleep 1 - telnetip=127.0.0.1 - sdtd_telnet - - # If failed using localhost will use servers ip - refused=$(echo -en "\n ${sdtdshutdown}"| grep "Timeout or EOF") - if [ -n "${refused}" ]; then - telnetip=${ip} - fn_print_warn "Attempting graceful shutdown via telnet: localhost failed" - fn_scriptlog "Warning! Attempting graceful shutdown failed using localhost" - sleep 5 - echo -en "\n" - fn_print_dots "Attempting graceful shutdown via telnet: using ${telnetip}" - fn_scriptlog "Attempting graceful shutdown via telnet using ${telnetip}" - sdtd_telnet - sleep 1 - fi - - refused=$(echo -en "\n ${sdtdshutdown}"| grep "Timeout or EOF") - completed=$(echo -en "\n ${sdtdshutdown}"| grep "Completed.") - if [ -n "${refused}" ]; then - fn_print_fail "Attempting graceful shutdown via telnet" - fn_scriptlog "Attempting graceful shutdown failed" - fn_scriptlog "${refused}" - elif [ -n "${completed}" ]; then - fn_print_ok "Attempting graceful shutdown via telnet" - fn_scriptlog "Attempting graceful shutdown succeeded" - else - fn_print_fail "Attempting graceful shutdown via telnet: Unknown error" - fn_scriptlog "Attempting graceful shutdown failed" - fn_scriptlog "Unknown error" - fi - sleep 1 - echo -en "\n\n" - echo -en "Telnet output:" - echo -en "\n ${sdtdshutdown}" - echo -en "\n\n" - sleep 1 - fn_print_dots "${servername}" - fn_scriptlog "${servername}" - sleep 5 - pid=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -Ec "^${servicename}:") - if [ "${pid}" == "0" ]; then - fn_print_ok "${servername} is already stopped using graceful shutdown" - fn_scriptlog "${servername} is already stopped using graceful shutdown" - else - tmux kill-session -t "${servicename}" - fn_print_ok "${servername}" - fn_scriptlog "Stopped ${servername}" - fi - +# Kill tmux session +tmux kill-session -t "${servicename}" > /dev/null 2>&1 +pid=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -Ec "^${servicename}:") +if [ "${pid}" == "0" ]; then + fn_print_ok_nl "${servername}" + fn_scriptlog "Stopped ${servername}" + sleep 1 + # Remove lock file + rm -f "${rootdir}/${lockselfname}" else - pid=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -Ec "^${servicename}:") - if [ "${pid}" == "0" ]; then - fn_print_fail "${servername} is already stopped" - fn_scriptlog "${servername} is already stopped" - else - - if [ "${engine}" == "source" ]||[ "${engine}" == "goldsource" ]; then - sleep 1 - fn_print_dots "Attempting graceful shutdown" - fn_scriptlog "Attempting graceful shutdown" - tmux send -t "${servicename}" quit ENTER > /dev/null 2>&1 - counter=0 - while [ "${pid}" != "0" -a $counter -lt 30 ]; do - pid=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -Ec "^${servicename}:") - sleep 1 - let counter=counter+1 - if [ "${counter}" -gt "1" ]; then - fn_print_dots "Attempting graceful shutdown: ${counter}" - fi - done - pid=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -Ec "^${servicename}:") - if [ "${pid}" == "0" ]; then - fn_print_ok "Attempting graceful shutdown" - else - fn_print_fail "Attempting graceful shutdown" - fi - fi - - tmux kill-session -t "${servicename}" > /dev/null 2>&1 - fn_print_ok "${servername}" - fn_scriptlog "Stopped ${servername}" - fi + fn_print_fail_nl "Unable to stop${servername}" + fn_scriptlog "Unable to stop${servername}" fi - # Remove lock file - rm -f "${rootdir}/${lockselfname}" - sleep 1 - echo -en "\n" + } +# checks if the server is already stopped before trying to stop. +fn_stop_pre_check(){ if [ "${gamename}" == "Teamspeak 3" ]; then - fn_stop_teamspeak3 + info_ts3status.sh + if [ "${ts3status}" = "No server running (ts3server.pid is missing)" ]; then + fn_print_ok_nl "${servername} is already stopped" + fn_scriptlog "${servername} is already stopped" + else + fn_stop_teamspeak3 + fi else - fn_stop_tmux -fi \ No newline at end of file + pid=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -Ec "^${servicename}:") + if [ "${pid}" == "0" ]; then + fn_print_ok_nl "${servername} is already stopped" + fn_scriptlog "${servername} is already stopped" + else + fn_stop_graceful_select + fi +fi +} + + + +check.sh +fn_stop_pre_check \ No newline at end of file