#!/bin/bash # Mumble # Server Management Script # Author: Daniel Gibbs # Website: http://danielgibbs.co.uk # Version: 250814 ### Variables #### # Notification Email # (on|off) emailnotification="off" email="email@example.com" # Server Details servername="Mumble" servicename="mumble-server" # Directorys rootdir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" selfname="$(basename $0)" lockselfname=".${servicename}.lock" filesdir="${rootdir}/serverfiles" ini="murmur.ini" executable="./murmur.x86 -fg -ini ${ini}" backupdir="backups" # Logging logdays="7" logdir="${rootdir}/log" scriptlogdir="${rootdir}/log/script" consolelogdir="${rootdir}/log/console" scriptlog="${scriptlogdir}/${servicename}-script.log" consolelog="${consolelogdir}/${servicename}-console.log" emaillog="${scriptlogdir}/${servicename}-email.log" scriptlogdate="${scriptlogdir}/${servicename}-script-$(date '+%d-%m-%Y-%H-%M-%S').log" consolelogdate="${consolelogdir}/${servicename}-console-$(date '+%d-%m-%Y-%H-%M-%S').log" ##### Script ##### # Do not edit # unless you know # what you are doing fn_scriptlog(){ echo -e "$(date '+%b %d %H:%M:%S') ${servicename}: '$1'" >> ${scriptlog} } # [ FAIL ] fn_printfail(){ echo -en "\r\033[K[\e[0;31m FAIL \e[0;39m] $@" } fn_printfailnl(){ echo -e "\r\033[K[\e[0;31m FAIL \e[0;39m] $@" } fn_printok(){ echo -en "\r\033[K[\e[0;32m OK \e[0;39m] $@" } # [ OK ] fn_printoknl(){ echo -e "\r\033[K[\e[0;32m OK \e[0;39m] $@" } fn_printinfo(){ echo -en "\r\033[K[\e[0;36m INFO \e[0;39m] $@" } fn_printinfonl(){ echo -e "\r\033[K[\e[0;36m INFO \e[0;39m] $@" } # [ INFO ] fn_printokinfonl(){ echo -e "\r\033[K[\e[0;36m INFO \e[0;39m] $@" } fn_printwarn(){ echo -en "\r\033[K[\e[1;33m WARN \e[0;39m] $@" } fn_printwarnnl(){ echo -e "\r\033[K[\e[1;33m WARN \e[0;39m] $@" } # [ .... ] fn_printdots(){ echo -en "\r\033[K[ .... ] $@" } fn_rootcheck(){ if [ `whoami` = "root" ]; then fn_printfailnl "Script will not run as root!" exit fi } fn_syscheck(){ if [ ! -e "${filesdir}" ]; then fn_printfailnl "Cannot access ${systemdir}: No such directory" exit fi } fn_inicheck(){ if [ ! -e ${filesdir}/${ini} ]; then fn_printwarnnl "${servicename}: ${filesdir}/${ini} is missing" fn_scriptlog "${servername} ${filesdir}/${ini} is missing" >> ${scriptlog} fi } fn_backupserver(){ fn_rootcheck fn_syscheck backupname="${servicename}-$(date '+%Y-%m-%d-%H%M%S')" echo "" echo "${gamename} Backup" echo "============================" echo "" echo "The following backup will be created." echo "" echo "${backupdir}/${backupname}.tar.gz" echo "" while true; do read -p "Continue? [y/N]" yn case $yn in [Yy]* ) break;; [Nn]* ) echo Exiting; return 1;; * ) echo "Please answer yes or no.";; esac done tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -v failed|grep -E "^${servicename}:"|wc -l) if [ ${tmuxwc} -eq 1 ]; then echo -e "\e[0;31mWARNING!\e[0;39m ${servicename} is currently running" while true; do read -p "Would you like to stop ${servicename} while running the backup? [y/N]" yn case $yn in [Yy]* ) fn_stopserver; break;; [Nn]* ) break;; * ) echo "Please answer yes or no.";; esac done fi fn_printdots "Starting backup ${servicename}: ${servername}" sleep 1 fn_printok "Starting backup ${servicename}: ${servername}" sleep 1 fn_scriptlog "Backup started" echo -en "\n" cd "${rootdir}" mkdir -pv "${backupdir}" > /dev/null 2>&1 tar -cvzf "${backupdir}/${backupname}.tar.gz" --exclude "${backupdir}" * echo -en "\r\033[K${servicename} Backup complete" fn_scriptlog "Backup complete" } fn_distro(){ arch=$(uname -m) kernel=$(uname -r) if [ -f /etc/lsb-release ]; then os=$(lsb_release -s -d) elif [ -f /etc/debian_version ]; then os="Debian $(cat /etc/debian_version)" elif [ -f /etc/redhat-release ]; then os=$(cat /etc/redhat-release) else os="$(uname -s) $(uname -r)" fi } fn_uptime(){ uptime=$( /dev/null 2>&1 tail -25 "${scriptlog}" >> "${emaillog}" if [ ! -z "${consolelog}" ]; then echo -e "\n\nConsole log\n====================\n" >> "${emaillog}" tail -25 "${consolelog}" >> "${emaillog}" fi if [ ! -z "${gamelogdir}" ]; then echo -e "\n\nServer log\n====================\n" >> "${emaillog}" tail "${gamelogdir}"/*|grep -v "==>"|sed '/^$/d'|tail -25 >> "${emaillog}" fi mail -s "${subject}" ${email} < "${emaillog}" fn_printinfo "Sent email notification to ${email}" sleep 1 echo -en "\n" fn_scriptlog "Sent email notification to ${email}" } fn_emailtest(){ fn_rootcheck fn_syscheck fn_scriptlog "Emailing test notification" if [ "${emailnotification}" = "on" ]; then subject="${servicename} Email Test Notification - Testing ${servername}" failurereason="Testing ${servicename} email notification" actiontaken="Sent test email...hello is this thing on?" fn_emailnotification else fn_printfailnl "Email notification not enabled" fn_scriptlog "Email notification not enabled" fi sleep 1 echo -en "\n" } fn_monitorserver(){ fn_rootcheck fn_syscheck if [ ! -f ${lockselfname} ]; then fn_printinfo "Monitoring ${servicename}: No lock file found: Monitor disabled" sleep 1 echo -en "\n" exit fi fn_printdots "Monitoring ${servicename}: ${servername}" sleep 1 fn_scriptlog "Monitoring ${servername}" fn_printdots "Monitoring ${servicename}: Checking session: CHECKING" sleep 1 fn_scriptlog "Checking session: CHECKING" tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -v failed|grep -E "^${servicename}:"|wc -l) if [ ${tmuxwc} -eq 1 ]; then fn_printok "Monitoring ${servicename}: Checking session: OK" sleep 1 echo -en "\n" fn_scriptlog "Checking session: OK" exit else fn_printfail "Monitoring ${servicename}: Checking session: FAIL" fn_scriptlog "Checking session: FAIL" sleep 1 echo -en "\n" if [ "${emailnotification}" = "on" ]; then subject="${servicename} Monitor - Starting ${servername}" failurereason="${servicename} process not running" actiontaken="${servicename} has been restarted" fn_emailnotification fi fn_scriptlog "Monitor is starting ${servername}" fn_startserver fi } fn_logmanager(){ if [ ! -e "${consolelog}" ]; then touch "${consolelog}" fi # log manager will active if finds logs older than ${logdays} if [ `find "${scriptlogdir}"/* -mtime +${logdays}|wc -l` -ne "0" ]; then fn_printdots "Starting log cleaner" sleep 1 fn_printok "Starting log cleaner" sleep 1 fn_scriptlog "Starting log cleaner" sleep 1 echo -en "\n" fn_printinfo "Removing logs older than ${logdays} days" sleep 1 echo -en "\n" fn_scriptlog "Removing logs older than ${logdays} days" sleep 1 find "${scriptlogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}" find "${consolelogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}" scriptcount=$(find "${scriptlogdir}"/* -mtime +${logdays}|wc -l) consolecount=$(find "${consolelogdir}"/* -mtime +${logdays}|wc -l) count=$((${scriptcount} + ${consolecount})) find "${scriptlogdir}"/* -mtime +${logdays} -exec rm {} \; find "${consolelogdir}"/* -mtime +${logdays} -exec rm {} \; fn_printok "Log cleaner removed ${count} log files" sleep 1 echo -en "\n" fn_scriptlog "Log cleaner removed ${count} log files" fi } fn_restartserver(){ fn_scriptlog "Restarting ${servername}" fn_stopserver fn_startserver } fn_stopserver(){ fn_rootcheck fn_syscheck pid=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -E "^${servicename}:"|wc -l) pidwc=$(screen -ls |grep -E "^${servicename}:" |awk -F . '{print $1}'|awk '{print $1}'|wc -l) fn_printdots "Stopping ${servicename}: ${servername}" sleep 1 fn_scriptlog "Stopping ${servername}" if [ "${pid}" == "0" ]; then fn_printfail "Stopping ${servicename}: ${servername} is already stopped" fn_scriptlog "${servername} is already stopped" else #Kill murmur process that spawns separate to tmux process for s in `tmux list-sessions -F '#{session_name}'` ; do for pid in `tmux list-panes -s -F '#{pane_pid}' -t "$s"` ; do kill $pid done tmux kill-session -t ${servicename} fn_printok "Stopping ${servicename}: ${servername}" fn_scriptlog "Stopped ${servername}" done fi # Remove lock file rm -f ${lockselfname} sleep 1 echo -en "\n" } fn_startserver(){ if [ ! -d ${logdir} ];then mkdir ${logdir} mkdir ${scriptlogdir} mkdir ${consolelogdir} echo -e "[\e[0;36m INFO \e[0;39m] ${servicename}: ${servername} Creating log directory ${logdir}" fn_scriptlog " Creating log directory ${logdir}" >> ${scriptlog} fi fn_rootcheck fn_syscheck fn_logmanager tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -v failed|grep -E "^${servicename}:"|wc -l) if [ ${tmuxwc} -eq 0 ]; then mv "${scriptlog}" "${scriptlogdate}" mv "${consolelog}" "${consolelogdate}" fi fn_printdots "Starting ${servicename}: ${servername}" sleep 1 fn_scriptlog "Starting ${servername}" if [ ${tmuxwc} -eq 1 ]; then fn_printinfo "Starting ${servicename}: ${servername} is already running" sleep 1 echo -en "\n" fn_scriptlog "${servername} is already running" exit fi # Create lock file date > ${lockselfname} cd ${filesdir} tmux new-session -d -s ${servicename} "${executable}" tmux pipe-pane -o -t ${servicename} "exec cat >> '${consolelog}'" sleep 1 tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -E "^${servicename}:"|wc -l) if [ ${tmuxwc} -eq 0 ]; then fn_printfail "Starting ${servicename}: Failed to start ${servername}" fn_scriptlog "failed to start ${servername}" else fn_printok "Starting ${servicename}: ${servername}" fn_scriptlog "Started ${servername}" fi sleep 1 echo -en "\n" } fn_debugserver(){ fn_rootcheck fn_syscheck echo "" echo "${gamename} Debug" echo "============================" echo "" echo -e "Use for identifying server issues only!" echo -e "Press CTRL+c to drop out of debug mode" echo -e "\e[0;31mWARNING!\e[0;39m If ${servicename} is already running it will be stopped" echo "" echo "Start parameters:" echo ${executable} echo "" while true; do read -p "Continue? [y/N]" yn case $yn in [Yy]* ) break;; [Nn]* ) echo Exiting; return 1;; * ) echo "Please answer yes or no.";; esac done fn_stopserver fn_printdots "Starting debug mode ${servicename}: ${servername}" sleep 1 fn_printok "Starting debug mode ${servicename}: ${servername}" sleep 1 fn_scriptlog "Started debug mode ${servername}" echo -en "\n" cd ${filesdir} ./murmur.x86 -fg -ini ${ini} } fn_console(){ fn_rootcheck fn_syscheck echo "" echo "${gamename} Console" echo "============================" echo "" echo "Press \"CTRL+b d\" to exit console" echo -e "\e[0;31mWARNING!\e[0;39m Do NOT press CTRL+c to exit" echo "" while true; do read -p "Continue? [y/N]" yn case $yn in [Yy]* ) break;; [Nn]* ) echo Exiting; return 1;; * ) echo "Please answer yes or no.";; esac done fn_printdots "Starting ${servicename} console" sleep 1 tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -v failed|grep -E "^${servicename}:"|wc -l) if [ ${tmuxwc} -eq 1 ]; then fn_printoknl "Starting ${servicename} console" sleep 1 fn_scriptlog "Console accessed" tmux attach-session -t ${servicename} else fn_printfailnl "Starting ${servicename} console: ${servername} not running" sleep 1 while true; do read -p "Do you want to start the server? [y/N]" yn case $yn in [Yy]* ) fn_startserver; break;; [Nn]* ) break;; * ) echo "Please answer yes or no.";; esac done fi } case "$1" in start) fn_startserver;; stop) fn_stopserver;; restart) fn_restartserver;; monitor) fn_monitorserver;; email-test) fn_emailtest;; backup) fn_backupserver;; console) fn_console;; debug) fn_debugserver;; *) echo "Usage: $0 {start|stop|restart|monitor|debug|backup|email-test}" exit 1;; esac exit