Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/bin/bash
- # Script: /etc/init.d/dni
- # Description: Manage multiple minecraft servers.
- # Requires: bash, java, netcat, rsync, nohup
- # Author: Tom Arnold <tom9729@gmail.com>
- # Version: 2012.03.22
- ### BEGIN INIT INFO
- # Provides: dni
- # Required-Start: $local_fs $remote_fs
- # Required-Stop: $local_fs $remote_fs
- # Should-Start: $network
- # Should-Stop: $network
- # Default-Start: 2 3 4 5
- # Default-Stop: 0 1 6
- # Short-Description: Minecraft server
- # Description: Starts the minecraft server
- ### END INIT INFO
- ## Install:
- ##
- ## - Install reqs:
- ## 'sudo apt-get install openjdk-6-jre netcat rsync'
- ##
- ## - Make a minecraft user.
- ##
- ## - Make these directories (owned by minecraft)
- ## /opt/dni
- ## /opt/dni/backup
- ## /opt/dni/server
- ##
- ## - Save script to /etc/init.d/dni, make owned by root
- ## and give it execute perms.
- ##
- ## - Install as a system service: 'update-rc.d dni defaults'
- ##
- ## - Make a directory per-server in /opt/dni/server. This is a
- ## normal minecraft server directory. Make sure it's owned by
- ## minecraft user. ***NAME OF SERVER = NAME OF DIR***
- ##
- ## Eg. 'creative' server is /opt/dni/server/creative
- ##
- ## - Enable automatic backups by adding a line to root's crontab.
- ## 'sudo EDITOR=nano crontab -e'
- ##
- ## Eg. for backups every 15 minutes: '*/15 * * * * service dni backup'
- ##
- ## - Get a nice overview of all backups using 'tree'
- ## Eg. 'tree -L 7 /opt/dni/backup'
- ## Usage:
- ## 'sudo service dni <cmd> [server]'
- ##
- ## - To start a 'creative' server: 'sudo service dni start creative'
- ##
- ## - To backup all servers: 'sudo service dni backup'
- ##
- ## - To execute a MC console cmd: 'echo "give Tom9729 92" | sudo service dni cmd survival'
- ## ***MUST SPECIFY SERVER FOR CMD, DESIGN FLAW, SORRY***
- ##
- ## - 'sudo service dni' to see list of commands, or just look below.
- ## Backups:
- ## - Shadow backups are made using rsync. The entire server folder is backed up
- ## and stored in: /opt/dni/backup/<server>/<year>/<month>/<day>/<hr>/<min>/<sec>
- ## The first backup will take a long time because it must make a baseline copy.
- ## The baseline will be the full size of your world (in my case, ~700mb). Every
- ## backup after the initial baseline is made will be quick and small. The benefits
- ## to doing shadow backups are that backups are fast, small, and that a working
- ## snapshot of the server from any point of time can be quickly put into production.
- ## The general idea is that only changes are ever written to disk.
- ##
- ## - Latest backup link: '/opt/dni/backup/<server>/latest'
- DNI_USER="minecraft"
- DNI_DIR="/opt/dni"
- DNI_JAVA="java -Xincgc -server"
- DNI_MINECRAFT="minecraft_server.jar nogui"
- dni_start() {
- if [ $# -lt 1 ]; then exit 1; fi
- local server="$1"
- if [ `dni_status $server` ]; then return; fi
- local minecraft="nohup ${DNI_JAVA} -jar ${DNI_MINECRAFT} server_${server}"
- cd "${DNI_DIR}/server/${server}"
- ## Make sure we have a clean env.
- dni_clean $server
- ## Exec minecraft,
- ## pipe input to it from UNIX socket.
- echo "Starting $server" 1>&2
- nc -lUk dni-in.sock | $minecraft > /dev/null 2>&1 &
- }
- dni_cmd() {
- if [ $# -lt 1 ]; then exit 1; fi
- local server="$1"
- if [ ! `dni_status $server` ]; then return; fi
- local prefix="${DNI_DIR}/server/${server}"
- read stdin
- echo "$stdin" | nc -U "$prefix/dni-in.sock"
- }
- dni_clean() {
- if [ $# -lt 1 ]; then exit 1; fi
- local server="$1"
- local prefix="${DNI_DIR}/server/${server}"
- rm -f "$prefix/dni-in.sock" "$prefix/dni-out.sock"
- }
- dni_stop() {
- if [ $# -lt 1 ]; then exit 1; fi
- local server="$1"
- if [ `dni_status $server` ]
- then
- echo "Stopping $server" 1>&2
- fi
- echo "stop" | dni_cmd $server
- dni_clean $server
- }
- dni_status() {
- if [ $# -lt 1 ]; then exit 1; fi
- local server="$1"
- local pid=`ps aux |
- grep -v grep | grep "${DNI_MINECRAFT} server_${server}" |
- sed -e 's/^[0-9]*\s*\([0-9]*\).*/\1/g'`
- if [ "$pid" ]; then echo "$pid "; fi
- }
- dni_server_list() {
- for f in `ls -B "${DNI_DIR}/server"`
- do
- echo $f
- done
- }
- dni_restart() {
- local server="$1"
- dni_stop $server
- while [ `dni_status $server` ]; do sleep 0.01; done
- dni_start $server
- }
- dni_backup() {
- if [ $# -lt 1 ]; then exit 1; fi
- local server="$1"
- if [ ! `dni_status $server` ]; then return; fi
- local prefix="$DNI_DIR"
- ## Force level save, then disable saving so
- ## that we can make a backup safeishley.
- echo "save-all" | dni_cmd $server
- echo "save-off" | dni_cmd $server
- sleep 0.1
- ## Construct backup dir as
- ## <dni_path>/<server>/<year>/<month>/<day>/<hour>/<min>/<sec>
- local now="`date +%Y/%m/%d/%H/%M/%S`"
- local bk_root="$prefix/backup/$server"
- local bk_dir="$bk_root/$now"
- if [ ! -d "$bk_dir" ]; then mkdir -p "$bk_dir"; fi
- local bk_src="$prefix/server/$server"
- local bk_latest="$bk_root/latest"
- if [ -h "$bk_latest" ]
- then
- ## We have a baseline to diff from.
- local bk_prev=`readlink -f "$bk_latest"`
- rsync -a --delete --link-dest="$bk_prev" "$bk_src" "$bk_dir/"
- else
- ## Make a baseline.
- cp -a "$bk_src" "$bk_dir/"
- fi
- ## Relink to latest backup.
- rm -f "$bk_latest"
- ln -s "$bk_dir" "$bk_latest"
- ## Reenable saving.
- echo "save-on" | dni_cmd $server
- }
- main() {
- ## Make sure that this script is run as DNI_USER.
- case `whoami` in
- ## Escape if we are DNI_USER.
- ${DNI_USER});;
- ## Relaunch as appropriate user.
- root)
- su ${DNI_USER} $0 $@
- exit $?
- ;;
- ## Not DNI_USER and can't su, so die.
- *)
- echo "fatal: must be run as (root, ${DNI_USER})" 1>&2
- exit 1
- ;;
- esac
- ## Pop off command (arg 1).
- local cmd="$1"
- shift
- case "$cmd" in
- ## Valid commands.
- start|stop|cmd|restart|status|backup)
- ;;
- ## Otherwise die.
- *)
- echo "Usage: $0 {start|stop|restart|cmd|status|backup}" 1>&2
- exit 1
- ;;
- esac
- for server in ${@:-`dni_server_list`}
- do
- ## Make sure server actually exists.
- if [ ! -d "$DNI_DIR/server/$server" ]; then continue; fi
- ## Execute command.
- dni_$cmd $server
- done
- exit 0
- }
- main $@
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement