Skip to content

Instantly share code, notes, and snippets.

@lorinc
Last active August 29, 2015 14:14
Show Gist options
  • Save lorinc/58b033242fe157292ef2 to your computer and use it in GitHub Desktop.
Save lorinc/58b033242fe157292ef2 to your computer and use it in GitHub Desktop.
bash wrapper to (recursively) manage multiple Bukkit servers running in screens
#!/bin/bash
# todo:
# - one script to control all 3 servers
# - script to know expected screens per server
# - pull functionalities into seperate functions e.g. is_server_up()
logfolder="/home/mc/servers/logs/"
this_box=`hostname | awk 'BEGIN {FS="."} {print toupper($1)}'`
backup_folder='/home/mc/servers/backup/'
today=`date +"%Y-%m-%d"`
ban_file="/home/mc/admintools/banned-players.json.permaban"
# create an array of screen names
IFS=$'\n' servers=`screen -ls | awk '/^\t/ {print $1}' | cut -f2 -d"."`
# passing a string to a screen
to_screen() {
screen -S $1 -p 0 -X stuff "$2$(printf \\r)"
echo ' "'$2'" --> '$1
}
restart_sequence() {
to_screen $1 'say is restarting in 3 minutes.'
sleep 120
to_screen $1 'say is restarting in one minute.'
sleep 15
to_screen $1 'say is restarting in 45 seconds.'
sleep 15
to_screen $1 'say is restarting in 30 seconds.'
sleep 15
to_screen $1 'say is restarting in 15 seconds.'
sleep 5
to_screen $1 'say is restarting in 10 seconds.'
sleep 5
to_screen $1 'say is restarting in 5 seconds, but you can come back almost immediately.'
sleep 5
to_screen $1 'restart'
}
log_rotate() {
from_file="$logfolder""$1"".current.log"
to_file="$logfolder""$1"-`date +'%Y-%m-%d--%H-%M-%S'`".log"
cp "$from_file" "$to_file"
echo "" > "$from_file"
echo 'Logrotate: '"$from_file"' -> '"$to_file"
}
screen_fix() {
logfile="$logfolder""$1"".current.log"
if pgrep -f "serverID=""$1" ; then
echo 'Server is running in that screen. Stop the server first.'
exit 1
fi
if [ ! -d "$logfolder" ]; then
echo 'Log folder does not exist or script can not access it.'
exit 1
fi
if [ -f "$logfile" ]; then
echo 'Logfile exists, backing it up.'
log_rotate $1
fi
echo 'Sending EOT signal to screen.'
screen -S "$1" -p 0 -X stuff "$(printf \\004)"
sleep 1
if screen -list | grep -q ".""$1" ; then # this condition have not been tested yet
echo ' Screen "'"$1"'" could not be killed, exiting.'
exit 1
else
echo ' Screen "'"$1"'" is terminated.'
fi
echo ' Configuring .screenrc for log settings.'
echo 'logfile '"$logfile" > ~/.screenrc
echo ' Restarting screen with proper log settings.'
screen -S "$1" -d -m -L
echo ' Changing directory to server folder in screen.'
to_screen "$1" 'cd /home/mc/servers/'"$1"
echo ' You may start the server in it.'
exit 0
}
local_backup() { # backs up every pex and gm on HDD
for source_folder in `find /home/mc/servers/ -type d -regextype posix-extended -regex '/home/mc/servers/.*/plugins/(GroupManager|PermissionsEx)'`
do
echo -e "\n\e[31m\e[1m### "$source_folder" ###\e[0m"
target_folder=$backup_folder`echo $source_folder | awk 'BEGIN{FS="/"} {print $5"/"$6"/"$7}'`'_'$today
d ${target_folder} ] || mkdir -pv $target_folder
cp -avr $source_folder $target_folder
du -sh $target_folder
done
echo '--------- SUMMARY ---------'
du -sh $backup_folder
df -H /home/
echo '---------------------------'
}
# parameter checking
if [ $# -ne 2 ]
then
echo -e " Usage: server <servername> <command>"
echo -e " Servernames: "$servers
echo -e " Use 'all' as a servername to run a command on all servers"
echo -e ""
echo -e " Commands:"
echo -e " start Start the server"
echo -e " stop Stop the server"
echo -e " kind-restart Restart the server with a countdown"
echo -e " kill Kill it with fire!"
echo -e " console Show a READ-ONLY console -- Exit with CTRL+C"
echo -e " <command> Execute a command in the server console -- Example: server hub-lobby 'ban asshole offensive name'"
echo -e " backup Start the backup -- NOT WORKING YET"
echo -e " log-rotate Opens a new logfile and backs up the old one."
echo -e " log-purge Deletes console log files older than a week -- NOT WORKING YET."
echo -e " log-fix Restarts a screen session with proper logging configuration."
exit 1
fi
# iterate through all screens if server is "ALL"
if [ "$1" == 'all' ] ; then
echo 'Sending '$2' to all servers on node '"$this_box"'.'
for i in ${servers[@]} ; do
if [[ $i == lily* ]] && [[ "$2" != 'logrotate' ]]; then # not all commands allowed on lillies
echo " Skipping "$i", it is not a bukkit server."
continue
fi
"$0" "$i" "$2"
done
exit 0
fi
# screen name check
if ! [[ ${servers[@]} =~ "$1" ]]; then
echo ' ERROR: no screen exsist with name '$1'.'
echo ' Available screens: '$servers
exit 1
fi
backup_sequence() {
echo '=== BACKUP FUNCTION GOT CALLED ==='
}
# parsing command
case "$2" in
'start')
if pgrep -f "serverID="$1 > /dev/null ; then
echo -e " Dude, \e[1m'$1' is already running.\e[0m Really. Just checked it."
exit 1
else
echo -e " \e[1mSending start signal to "$1"\e[21m... Status check in 5 sec."
to_screen $1 './start.sh'
sleep 5
if pgrep -f "serverID="$1 > /dev/null ; then
echo -e " Dude, you just started "$1". Cool!"
exit 0
else
echo -e " \e[31m'$1' could not be started.\e[0m Sorry."
exit 1
fi
fi
;;
'console')
echo -e " \e[1mOpening READ-ONLY console to "$1"\e[0m"
tail -f /home/mc/servers/logs/$1.current.log
exit 0
;;
'kind-restart')
restart_sequence $1 $2
exit 0
;;
'backup')
backup_sequence $1
exit 0
;;
'kill')
victim=`pgrep -f "serverID="$1`
if ! [ -z $victim ]; then
echo -e " \e[31m\e[1m ### KILLING SERVER "$1" with JAVA PID "$victim" ###\e[0m"
kill -9 $victim
sleep 1
if pgrep -f "serverID="$1 > /dev/null ; then
echo ' Sorry, could not kill '$1'... :('
exit 1
else
echo -e " Just checked - \e[1m'$1' kicked the bucket hard.\e[0m You may send the \e[1mstart\e[0m signal now."
fi
else
echo -e " You can not kill something that is \e[1malready dead\e[0m, can you."
exit 1
fi
exit 0
;;
'logrotate')
log_rotate $1
;;
'screen-fix')
log_fix $1
;;
'local-backup')
local_backup
;;
*)
to_screen $1 $2
exit 0
;;
esac
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment