You are not logged in.
Hey all, I just finished editing and setting up a nice script to run a Minecraft server at boot in Arch. This is based on the original script on the minecraft wiki here. I've edited it to be suitable to place in your /etc/rc.d/ folder with the name "minecraft" (/etc/rc.d/minecraft).
This requires a user "minecraft" with the home directory /home/minecraft to work by default.
I decided I wanted to run the server entirely in RAM so I store all my files in /home/minecraft/backup while the server is offline. When it starts up it makes a tmpfs mount at /home/minecraft/minecraft and copies all the files there and runs from there. It makes an hourly backup using /etc/rc.d/backup stored in /home/minecraft/onlinebackup, first erasing the current backup and creating a new one. This is simply to save space. In the event of a crash without proper stopping of the daemon you will have a backup from your previous reboot (or restart of your minecraft server) in /home/minecraft/backup and one from within the previous hour in /home/minecraft/onlinebackup which I figure ought to be enough. You can manually backup at any time by restarting the daemon.
All paths can be altered. You can run this game under your normal user if you wish, just change the Settings section at the top of the file. RAM amounts may need to be increased for both the server and for the tmpfs, depending on how large your files are (mine are tiny and I have not heard of over 48MB for a game world, but you never know). Just check up on df -h every now and again to make sure your tmpfs has plenty of space, or just increase the allocated maximum size from the start. If you have low RAM you can always change the script to simply not use tmpfs.
If anyone wants, just ask and I can put up a version without tmpfs (should be easy enough to remove yourself but if you're not sure I'll do it for you)
All you need to start off with (if starting your server for the first time, using the scrip as is) is the user minecraft created, with the folders backup, onlinebackup and minecraft in the folder /home/minecraft, your minecraft_server.jar file in /home/minecraft/backup and your oninebackup file in /home/minecraft/backup.
NOTE: onlinebackup file runs from /home/minecraft/minecraft so that if your system crashes, the cron job to run the backups will fail because the link will point to a non-existant file until server is started again.
You can use these commands to with the server: /etc/rc.d/minecraft {start|stop|restart|update|backup}
The backup system is designed to wipe all previous sessions' backups upon starting the server, so do not set it to start the server at boot.
/etc/rc.d/minecraft
#!/bin/bash
# /etc/rc.d/minecraft
. /etc/rc.conf
. /etc/rc.d/functions
#Uncomment line below if using Sun JRE
#. /etc/profile
#Settings
SERVICE='minecraft_server.jar'
USERNAME="minecraft"
MCPATH='/home/minecraft/minecraft'
MCOFFLINEPATH='/home/minecraft/backup'
INVOCATION='java -Xmx768M -Xms768M -jar minecraft_server.jar nogui'
BACKUPPATH='/home/minecraft/onlinebackup'
ME=`whoami`
as_user() {
if [ "$ME" == "$USERNAME" ] ; then
bash -c "$1"
else
su -c - $USERNAME "$1"
fi
}
mc_start() {
stat_busy "Starting Minecraft Server"
if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null
then
echo "Tried to start but $SERVICE was already running!"
else
echo "$SERVICE was not running... starting."
#Move minecraft from backup folder to ram
mount -t tmpfs tmpfs -o size=50m $MCPATH
cp -a $MCOFFLINEPATH/* $MCPATH
echo "Files moved to RAM."
cd $MCPATH
as_user "cd $MCPATH && screen -dmS minecraft $INVOCATION"
sleep 7
if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null
then
echo "$SERVICE is now running."
#Create hourly backups while running
ln -s $MCPATH/onlinebackup /etc/cron.hourly/minecraftonlinebackup
echo "Hourly backups initiated."
else
echo "Could not start $SERVICE."
umount $MCPATH
fi
fi
add_daemon minecraft
stat_done
}
mc_saveoff() {
if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null
then
echo "$SERVICE is running... suspending saves."
as_user "screen -p 0 -S minecraft -X eval 'stuff \"say SERVER BACKUP STARTING. Server going readonly...\"\015'"
as_user "screen -p 0 -S minecraft -X eval 'stuff \"save-off\"\015'"
as_user "screen -p 0 -S minecraft -X eval 'stuff \"save-all\"\015'"
sync
sleep 10
else
echo "$SERVICE was not running. Not suspending saves."
fi
}
mc_saveon() {
if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null
then
echo "$SERVICE is running... re-enabling saves."
as_user "screen -p 0 -S minecraft -X eval 'stuff \"save-on\"\015'"
as_user "screen -p 0 -S minecraft -X eval 'stuff \"say SERVER BACKUP ENDED. Server going read-write...\"\015'"
else
echo "$SERVICE was not running. Not resuming saves."
fi
}
mc_stop() {
stat_busy "Stopping Minecraft Server"
if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null
then
echo "$SERVICE is running... stopping."
as_user "screen -p 0 -S minecraft -X eval 'stuff \"say SERVER SHUTTING DOWN IN 10 SECONDS. Saving map...\"\015'"
as_user "screen -p 0 -S minecraft -X eval 'stuff \"save-all\"\015'"
sleep 10
as_user "screen -p 0 -S minecraft -X eval 'stuff \"stop\"\015'"
sleep 7
if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null
then
echo "$SERVICE could not be shut down... still running."
else
echo "$SERVICE is shut down."
#Stop hourly backups
rm /etc/cron.hourly/minecraftonlinebackup
echo "Hourly backup halted."
#Unmount tmpfs
cp -a $MCPATH/* $MCOFFLINEPATH
umount $MCPATH
echo "Files copied to HDD."
fi
else
echo "$SERVICE was not running."
fi
rm_daemon minecraft
stat_done
}
mc_update() {
if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null
then
echo "$SERVICE is running! Will not start update."
else
MC_SERVER_URL=http://minecraft.net/`wget -q -O - http://www.minecraft.net/download.jsp | grep minecraft_server.jar\</a\> | cut -d \" -f 2`
as_user "cd $MCPATH && wget -q -O $MCPATH/minecraft_server.jar.update $MC_SERVER_URL"
if [ -f $MCPATH/minecraft_server.jar.update ]
then
if `diff $MCPATH/minecraft_server.jar $MCPATH/minecraft_server.jar.update >/dev/null`
then
echo "You are already running the latest version of $SERVICE."
else
as_user "mv $MCPATH/minecraft_server.jar.update $MCPATH/minecraft_server.jar"
echo "Minecraft successfully updated."
fi
else
echo "Minecraft update could not be downloaded."
fi
fi
}
mc_backup() {
echo "Backing up minecraft world"
if [ -d $BACKUPPATH/world_`date "+%m.%d.%Y"` ]
then
for i in 1 2 3 4 5 6
do
if [ -d $BACKUPPATH/world_`date "+%m.%d.%Y"`-$i ]
then
continue
else
as_user "cd $MCPATH && cp -r world $BACKUPPATH/world_`date "+%m.%d.%Y"`-$i"
break
fi
done
else
as_user "cd $MCPATH && cp -r world $BACKUPPATH/world_`date "+%m.%d.%Y"`"
echo "Backed up world"
fi
echo "Backing up the minecraft server executable"
if [ -f "$BACKUPPATH/minecraft_server_`date "+%m.%d.%Y"`.jar" ]
then
for i in 1 2 3 4 5 6
do
if [ -f "$BACKUPPATH/minecraft_server_`date "+%m.%d.%Y"`-$i.jar" ]
then
continue
else
as_user "cd $MCPATH && cp minecraft_server.jar \"$BACKUPPATH/minecraft_server_`date "+%m.%d.%Y"`-$i.jar\""
break
fi
done
else
as_user "cd $MCPATH && cp minecraft_server.jar \"$BACKUPPATH/minecraft_server_`date "+%m.%d.%Y"`.jar\""
fi
echo "Backup complete"
}
#Start-Stop here
case "$1" in
start)
mc_start
;;
stop)
mc_stop
;;
restart)
mc_stop
mc_start
;;
update)
mc_stop
mc_backup
mc_update
mc_start
;;
backup)
mc_saveoff
mc_backup
mc_saveon
;;
status)
if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null
then
echo "$SERVICE is running."
else
echo "$SERVICE is not running."
fi
;;
*)
echo "Usage: /etc/rc.d/minecraft {start|stop|update|backup|status|restart}"
exit 1
;;
esac
exit 0/home/minecraft/backup/onlinebackup
#!/bin/bash
# /home/minecraft/backup/onlinebackup
rm -rf /home/minecraft/onlinebackup/*
/etc/rc.d/minecraft backupUPDATE:
rationalOgre has created an alternate script with a different backup system, which will keep compressed copies of your world indefinitely, along with a working update function. https://bbs.archlinux.org/viewtopic.php … 97#p944797
Last edited by PIMPinator (2011-06-08 14:00:54)
Offline
I have been using aur/bukkit. but i actually want to run the original server. Will try out your script. Thanks PIMPinator!
Nice that you added the backup script... I have lost 'chunks' of my map including the seed file on a crash.. fortunately i had a backup from a couple weeks before... was able to merge the (old) missing chunks... and seed. All is good now ![]()
Definitely plan on running cron backup.
Last edited by Splex (2011-03-01 07:15:22)
Offline
Cleaned up script (in first post), changed where backups and things execute, just stop your current script and overwrite with this one then start again.
Offline
Nice script! I'll have to give it a shot. Mine is much simpler; its only functionality is to start the server via screen. I perform the backups manually.
Offline
I'm having trouble getting this to work. When I run the daemon, it moves the files to RAM and then says that it "Could not start minecraft_server.jar". After that it complains that /home/minecraft/minecraft is busy. I guess my question is; did you give the user "minecraft" a password when you created it? Is that why I'm having trouble (i.e. because I gave mine a password).
Edit: I deleted the minecraft user's password and it's still complaining about not being able to start minecraft_server.jar. I'm not really sure why. I don't get any kind of output in the server.log or anything like that. I've tried running each of the commands in the script individually and I can get it started that way.
Last edited by phekno (2011-04-06 18:37:19)
Offline
The minecraft user has a password on my server.
EDIT: Ignore that, make sure you have java installed correctly. I'm using jre but I see no reason that you can't use openjdk
Last edited by PIMPinator (2011-04-12 11:12:03)
Offline
Offline
I'm having trouble getting this to work. When I run the daemon, it moves the files to RAM and then says that it "Could not start minecraft_server.jar". After that it complains that /home/minecraft/minecraft is busy. I guess my question is; did you give the user "minecraft" a password when you created it? Is that why I'm having trouble (i.e. because I gave mine a password).
Edit: I deleted the minecraft user's password and it's still complaining about not being able to start minecraft_server.jar. I'm not really sure why. I don't get any kind of output in the server.log or anything like that. I've tried running each of the commands in the script individually and I can get it started that way.
I know it's been awhile since this was asked but I recently ran into this issue while attempting to set up my own minecraft server using this code. It took the better part of forever (ok, 2 hours really but hey, this is my first time in Arch) but I finally spotted the issue. Below, for your perusal, the patch...
--- minecraft 2011-05-23 14:51:38.434887236 -0400
+++ minecraft-fix 2011-05-23 19:50:12.813208175 -0400
@@ -18,7 +18,7 @@
if [ "$ME" == "$USERNAME" ] ; then
bash -c "$1"
else
- su - $USERNAME -c "$1"
+ su -c - $USERNAME "$1"
fi
}All is now working perfectly fine. Hope that helps!
EDIT: Oh and I almost forgot, I had to add ". /etc/profile" to the sourcing section of the file at the top. (This is because I use the sun JRE instead of OpenJDK.)
Last edited by rationalOgre (2011-05-24 02:43:18)
Offline
How could I use this script for my bukkit server?
I didn't install bukkit from aur, if you need to know...
archlinux on Macbook Pro 10,1
Offline
I know it's been awhile since this was asked but I recently ran into this issue while attempting to set up my own minecraft server using this code. It took the better part of forever (ok, 2 hours really but hey, this is my first time in Arch) but I finally spotted the issue. Below, for your perusal, the patch...
All is now working perfectly fine. Hope that helps!
EDIT: Oh and I almost forgot, I had to add ". /etc/profile" to the sourcing section of the file at the top. (This is because I use the sun JRE instead of OpenJDK.)
I changed the line in the script, although I haven't tested this yet and I don't really see what difference it would make, as it was working as is for me. I'll trust you on this one ![]()
@froli
I'm sorry, I don't even know what bukkit is.
To be consistent with other rc.d scripts, you should consider putting the settings in /etc/conf.d/minecraft and sourcing this file in your script.
I would, but since I haven't bothered making this an installer or anything, creating and editing the one file for now is easier.
Last edited by PIMPinator (2011-06-01 16:53:20)
Offline
@PIMPinator - To be fair, I'm not sure why. The man pages for SU on my server box says that -c is an option, instead of an argument. However, on my laptop (Ubuntu) the man page for SU says that -c can come after the {username}. All I know is when I tried changing that, it suddenly spurred to life where before it was refusing to do so.
Also, Bukkit is a minecraft_server.jar modification that provides addon support and some other stuff.
@froli - There would be a couple things you would have to change. You might just find & replace through the file for all instances of minecraft_server.jar and replace them with craftbukkit-0.0.1-SNAPSHOT.jar. Also you probably would want to change the INVOCATION='blahblahblah' line to use whatever invocation of craftbukkit you want
Offline
Then maybe some of you guys can help me. I don't really want the server to be started by a daemon. I am more interested by the tempfs part. I want a script that would launch my minecraft (bukkit) server in RAM and the backup script, like in the OP.
The command to launch the server would be something like:
tmux new-window -n bukkit /home/froli/Minecraft/minecraft.shWhere /home/froli/Minecraft/ is my minecraft folder
ls /home/froli/Minecraft/:
banned-ips.txt bukkit_update craftbukkit-0.0.1-SNAPSHOT.jar minecraft.sh nether ops.txt RUN.bat server.log.1 userdata world
banned-players.txt bukkit.yml lib mmCfg.txt onlinebackup~ plugins server.log server.properties white-list.txt world_netherand minecraft.sh is the script from the bukkit wiki that really starts the server. I want to use tmux to launch it because I could acces to the server console whenever I want.
cat minecraft.sh: (if you want to see it)
#! /bin/sh
BINDIR="$(dirname "$(readlink -fn "$0")")"
cd "$BINDIR"
java -Xincgc -Xmx1G -jar craftbukkit-0.0.1-SNAPSHOT.jarI hope some of you can help me! I have absolutely zero coding skills
... Thanks in advance!
archlinux on Macbook Pro 10,1
Offline
@froli: You should be able to access the server by simply logging in as the user minecraft (or just doing a "su minecraft" in a terminal) then "screen -R" (assuming you use the minecraft user for nothing else, it will be the only screen running). Other than that I'll take a look at running it with bukkit, I haven't reinstalled minecraft since I migrated servers last week.
@rationalOgre: I just realised I was running minecraft with Sun JRE and not OpenJDK and did not have ./etc/profile at the start of the script.
Offline
@PIMPinator - Weird. On mine, if I don't source /etc/profile it won't work. No clue what the difference is. I tested it after I got it up and running, removing different elements to see if one or the other was the problem. Without it all in place it just didn't work.
I made some modifications to your script today. Fixed "update" so it works properly. (You had it running mc_backup after mc_stop, which never worked on my system.) I basically reworked it so it runs the backup, then stops the server and performs the update in the ~/backup directory, then restarts the server. I also completely overhauled the "backup" system. (for this to work you have to comment out the rm -rf ~/onlinebackup/* directive in the onlinebackup script.) Now, it creates 4 rolling backups of the server, in tar.gz format. What this means is that over time, you will accumulate the last 4 backups for each day in your ~/onlinebackup folder. I thought about creating a cleanup function to cull anything over 2 days old but to be honest, even if your world was > 50MB, zipped up it's going to be about ~20mb which means you can have 50 of them and only be taking up a gig of server space. Anyway, here's the code if you are interested.
#!/bin/bash
# /etc/init.d/minecraft
. /etc/rc.conf
. /etc/rc.d/functions
#Comment out the following if using OpenJDK
. /etc/profile
#Settings
SERVICE='minecraft_server.jar'
USERNAME="minecraft"
MCPATH='/home/minecraft/minecraft'
MCOFFLINEPATH='/home/minecraft/backup'
INVOCATION='java -Xmx768M -Xms768M -jar minecraft_server.jar nogui'
BACKUPPATH='/home/minecraft/onlinebackup'
ME=`whoami`
as_user() {
if [ "$ME" == "$USERNAME" ] ; then
bash -c "$1"
else
su -c - $USERNAME "$1"
fi
}
mc_start() {
stat_busy "Starting Minecraft Server"
if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null
then
echo "Tried to start but $SERVICE was already running!"
else
echo "$SERVICE was not running... starting."
#Move minecraft from backup folder to ram
mount -t tmpfs tmpfs -o size=50m $MCPATH
cp -a $MCOFFLINEPATH/* $MCPATH
echo "Files moved to RAM."
cd $MCPATH
as_user "cd $MCPATH && screen -dmS minecraft $INVOCATION"
sleep 7
if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null
then
echo "$SERVICE is now running."
#Create hourly backups while running
ln -s $MCPATH/onlinebackup /etc/cron.hourly/minecraftonlinebackup
echo "Hourly backups initiated."
else
echo "Could not start $SERVICE."
umount $MCPATH
fi
fi
add_daemon minecraft
stat_done
}
mc_saveoff() {
if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null
then
echo "$SERVICE is running... suspending saves."
as_user "screen -p 0 -S minecraft -X eval 'stuff \"say SERVER BACKUP STARTING. Server going readonly...\"\015'"
as_user "screen -p 0 -S minecraft -X eval 'stuff \"save-off\"\015'"
as_user "screen -p 0 -S minecraft -X eval 'stuff \"save-all\"\015'"
sync
sleep 10
else
echo "$SERVICE was not running. Not suspending saves."
fi
}
mc_saveon() {
if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null
then
echo "$SERVICE is running... re-enabling saves."
as_user "screen -p 0 -S minecraft -X eval 'stuff \"save-on\"\015'"
as_user "screen -p 0 -S minecraft -X eval 'stuff \"say SERVER BACKUP ENDED. Server going read-write...\"\015'"
else
echo "$SERVICE was not running. Not resuming saves."
fi
}
mc_stop() {
stat_busy "Stopping Minecraft Server"
if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null
then
echo "$SERVICE is running... stopping."
as_user "screen -p 0 -S minecraft -X eval 'stuff \"say SERVER SHUTTING DOWN IN 10 SECONDS. Saving map...\"\015'"
as_user "screen -p 0 -S minecraft -X eval 'stuff \"save-all\"\015'"
sleep 10
as_user "screen -p 0 -S minecraft -X eval 'stuff \"stop\"\015'"
sleep 7
if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null
then
echo "$SERVICE could not be shut down... still running."
else
echo "$SERVICE is shut down."
#Stop hourly backups
rm /etc/cron.hourly/minecraftonlinebackup
echo "Hourly backup halted."
#Unmount tmpfs
cp -a $MCPATH/* $MCOFFLINEPATH
umount $MCPATH
echo "Files copied to HDD."
fi
else
echo "$SERVICE was not running."
fi
rm_daemon minecraft
stat_done
}
mc_update() {
if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null
then
echo "$SERVICE is running! Will not start update."
else
MC_SERVER_URL=http://minecraft.net/`wget -q -O - http://www.minecraft.net/download.jsp | grep minecraft_server.jar\</a\> | cut -d \" -f 2`
as_user "cd $MCOFFLINEPATH && wget -q -O $MCOFFLINEPATH/minecraft_server.jar.update $MC_SERVER_URL"
if [ -f $MCOFFLINEPATH/minecraft_server.jar.update ]
then
if `diff $MCOFFLINEPATH/minecraft_server.jar $MCOFFLINEPATH/minecraft_server.jar.update >/dev/null`
then
echo "You are already running the latest version of $SERVICE."
rm $MCOFFLINEPATH/minecraft_server.jar.update
else
as_user "mv $MCOFFLINEPATH/minecraft_server.jar.update $MCOFFLINEPATH/minecraft_server.jar"
echo "Minecraft successfully updated."
fi
else
echo "Minecraft update could not be downloaded."
fi
fi
}
mc_backup() {
echo "Backing up minecraft world"
local COUNTER=
if [ -f $BACKUPPATH/co ]
then
COUNTER=`cat $BACKUPPATH/co`
if [ $COUNTER -gt 4 ]
then
#Loop back to 1 if greater than the max number of desired saves (4 hardcoded)
as_user "echo 1 > $BACKUPPATH/co"
COUNTER=1
fi
else
COUNTER=1
as_user "echo 1 > $BACKUPPATH/co"
fi
if [ -f $BACKUPPATH/world_`date "+%m.%d.%Y"`-$COUNTER.tar.gz ]
then
as_user "rm $BACKUPPATH/world_`date "+%m.%d.%Y"`-$COUNTER.tar.gz"
fi
as_user "cd $MCPATH && tar -czf $BACKUPPATH/world_`date "+%m.%d.%Y"`-$COUNTER.tar.gz world"
#now to update the counter
as_user "echo $(($COUNTER + 1)) > $BACKUPPATH/co"
echo "Backup complete..."
}
#Start-Stop here
case "$1" in
start)
mc_start
;;
stop)
mc_stop
;;
restart)
mc_stop
mc_start
;;
update)
mc_saveoff
mc_backup
mc_saveon
mc_stop
mc_update
mc_start
;;
backup)
mc_saveoff
mc_backup
mc_saveon
;;
status)
if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null
then
echo "$SERVICE is running."
else
echo "$SERVICE is not running."
fi
;;
*)
echo "Usage: /etc/rc.d/minecraft {start|stop|update|backup|status|restart}"
exit 1
;;
esac
exit 0I hope you don't mind.
EDIT: Made a small change later that I came back and put in. If you are currently at the latest release it removes the .update file it created.
Last edited by rationalOgre (2011-06-07 23:05:58)
Offline
Hey that's pretty nice. I prefer only having the previous hour's backup and one from the last start up, but personal preference I guess. Is there any chance you can throw up a version with just the auto-update fixed?
I'd look through what's wrong but I'm a bit tired atm. Also, I tend to update manually anyway. I'll merge your fixed update with my script then and link yours in the top post.
Also, I reinstalled the server, and once again it works fine with Sun JRE and without . /etc/profile in the script. Just a straight default install of java etc with no changes.
Offline
#!/bin/bash
# /etc/rc.d/minecraft
. /etc/rc.conf
. /etc/rc.d/functions
#Uncomment line below if using Sun JRE
#. /etc/profile
#Settings
SERVICE='minecraft_server.jar'
USERNAME="minecraft"
MCPATH='/home/minecraft/minecraft'
MCOFFLINEPATH='/home/minecraft/backup'
INVOCATION='java -Xmx768M -Xms768M -jar minecraft_server.jar nogui'
BACKUPPATH='/home/minecraft/onlinebackup'
ME=`whoami`
as_user() {
if [ "$ME" == "$USERNAME" ] ; then
bash -c "$1"
else
su -c - $USERNAME "$1"
fi
}
mc_start() {
stat_busy "Starting Minecraft Server"
if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null
then
echo "Tried to start but $SERVICE was already running!"
else
echo "$SERVICE was not running... starting."
#Move minecraft from backup folder to ram
mount -t tmpfs tmpfs -o size=50m $MCPATH
cp -a $MCOFFLINEPATH/* $MCPATH
echo "Files moved to RAM."
cd $MCPATH
as_user "cd $MCPATH && screen -dmS minecraft $INVOCATION"
sleep 7
if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null
then
echo "$SERVICE is now running."
#Create hourly backups while running
ln -s $MCPATH/onlinebackup /etc/cron.hourly/minecraftonlinebackup
echo "Hourly backups initiated."
else
echo "Could not start $SERVICE."
umount $MCPATH
fi
fi
add_daemon minecraft
stat_done
}
mc_saveoff() {
if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null
then
echo "$SERVICE is running... suspending saves."
as_user "screen -p 0 -S minecraft -X eval 'stuff \"say SERVER BACKUP STARTING. Server going readonly...\"\015'"
as_user "screen -p 0 -S minecraft -X eval 'stuff \"save-off\"\015'"
as_user "screen -p 0 -S minecraft -X eval 'stuff \"save-all\"\015'"
sync
sleep 10
else
echo "$SERVICE was not running. Not suspending saves."
fi
}
mc_saveon() {
if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null
then
echo "$SERVICE is running... re-enabling saves."
as_user "screen -p 0 -S minecraft -X eval 'stuff \"save-on\"\015'"
as_user "screen -p 0 -S minecraft -X eval 'stuff \"say SERVER BACKUP ENDED. Server going read-write...\"\015'"
else
echo "$SERVICE was not running. Not resuming saves."
fi
}
mc_stop() {
stat_busy "Stopping Minecraft Server"
if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null
then
echo "$SERVICE is running... stopping."
as_user "screen -p 0 -S minecraft -X eval 'stuff \"say SERVER SHUTTING DOWN IN 10 SECONDS. Saving map...\"\015'"
as_user "screen -p 0 -S minecraft -X eval 'stuff \"save-all\"\015'"
sleep 10
as_user "screen -p 0 -S minecraft -X eval 'stuff \"stop\"\015'"
sleep 7
if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null
then
echo "$SERVICE could not be shut down... still running."
else
echo "$SERVICE is shut down."
#Stop hourly backups
rm /etc/cron.hourly/minecraftonlinebackup
echo "Hourly backup halted."
#Unmount tmpfs
cp -a $MCPATH/* $MCOFFLINEPATH
umount $MCPATH
echo "Files copied to HDD."
fi
else
echo "$SERVICE was not running."
fi
rm_daemon minecraft
stat_done
}
mc_update() {
if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null
then
echo "$SERVICE is running! Will not start update."
else
MC_SERVER_URL=http://minecraft.net/`wget -q -O - http://www.minecraft.net/download.jsp | grep minecraft_server.jar\</a\> | cut -d \" -f 2`
as_user "cd $MCOFFLINEPATH && wget -q -O $MCOFFLINEPATH/minecraft_server.jar.update $MC_SERVER_URL"
if [ -f $MCOFFLINEPATH/minecraft_server.jar.update ]
then
if `diff $MCOFFLINEPATH/minecraft_server.jar $MCOFFLINEPATH/minecraft_server.jar.update >/dev/null`
then
echo "You are already running the latest version of $SERVICE."
rm $MCOFFLINEPATH/minecraft_server.jar.update
else
as_user "mv $MCOFFLINEPATH/minecraft_server.jar.update $MCOFFLINEPATH/minecraft_server.jar"
echo "Minecraft successfully updated."
fi
else
echo "Minecraft update could not be downloaded."
fi
fi
}
mc_backup() {
echo "Backing up minecraft world"
if [ -d $BACKUPPATH/world_`date "+%m.%d.%Y"` ]
then
for i in 1 2 3 4 5 6
do
if [ -d $BACKUPPATH/world_`date "+%m.%d.%Y"`-$i ]
then
continue
else
as_user "cd $MCPATH && cp -r world $BACKUPPATH/world_`date "+%m.%d.%Y"`-$i"
break
fi
done
else
as_user "cd $MCPATH && cp -r world $BACKUPPATH/world_`date "+%m.%d.%Y"`"
echo "Backed up world"
fi
echo "Backing up the minecraft server executable"
if [ -f "$BACKUPPATH/minecraft_server_`date "+%m.%d.%Y"`.jar" ]
then
for i in 1 2 3 4 5 6
do
if [ -f "$BACKUPPATH/minecraft_server_`date "+%m.%d.%Y"`-$i.jar" ]
then
continue
else
as_user "cd $MCPATH && cp minecraft_server.jar \"$BACKUPPATH/minecraft_server_`date "+%m.%d.%Y"`-$i.jar\""
break
fi
done
else
as_user "cd $MCPATH && cp minecraft_server.jar \"$BACKUPPATH/minecraft_server_`date "+%m.%d.%Y"`.jar\""
fi
echo "Backup complete"
}
#Start-Stop here
case "$1" in
start)
mc_start
;;
stop)
mc_stop
;;
restart)
mc_stop
mc_start
;;
update)
mc_saveoff
mc_backup
mc_saveon
mc_stop
mc_update
mc_start
;;
backup)
mc_saveoff
mc_backup
mc_saveon
;;
status)
if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null
then
echo "$SERVICE is running."
else
echo "$SERVICE is not running."
fi
;;
*)
echo "Usage: /etc/rc.d/minecraft {start|stop|update|backup|status|restart}"
exit 1
;;
esac
exit 0There's the file without the changes to mc_backup. As for why you aren't having to source etc profile, I have no clue. I just know that I do. That is what resolved one of the errors I was getting.
I prefer having multiple days worth of backups because if my server reboots due to power failure or whatever and it comes back up, it could potentially overwrite my online backup if it goes on for an hour without me noticing it rebooted. (ex. I'm away from home for the day and the power goes out.) Then I'd end up with a corrupted backup and or a backup of the server from several days ago.
Last edited by rationalOgre (2011-06-08 16:27:22)
Offline
I prefer having multiple days worth of backups because if my server reboots due to power failure or whatever and it comes back up, it could potentially overwrite my online backup if it goes on for an hour without me noticing it rebooted. (ex. I'm away from home for the day and the power goes out.) Then I'd end up with a corrupted backup and or a backup of the server from several days ago.
I'm not autostarting is why it doesn't matter to me, I just start it when I boot.
Offline
#!/bin/bash
# /etc/rc.d/minecraft
. /etc/rc.conf
. /etc/rc.d/functions
. /etc/profile
ME=`whoami`
as_user() {
if [ "$ME" == "root" ] ; then
bash -c "$1"
else
su -c - root "$1"
fi
}
mc_start() {
stat_busy "Starting Minecraft Server"
if ps ax | grep -v grep | grep -v -i SCREEN | grep minecraft_server.jar > /dev/null
then
echo "Tried to start but Minecraft was already running!"
stat_fail
else
echo "Minecraft was not running... starting."
#Move minecraft from backup folder to ram
mount -t tmpfs tmpfs -o size=250m /mnt/minecraft
cp -a /srv/minecraft/current/* /mnt/minecraft
echo "Files moved to RAM."
cd /mnt/minecraft
as_user "cd /mnt/minecraft && screen -dmS minecraft java -Xmx2048M -Xms2048M -jar minecraft_server.jar nogui"
sleep 3
if ps ax | grep -v grep | grep -v -i SCREEN | grep minecraft_server.jar > /dev/null
then
echo "Minecraft is now running."
#Create daily maps"
cp /srv/minecraft/minecraft-map.sh /etc/cron.daily/
echo "Daily map generation initiated."
#Create hourly backups while running
cp /srv/minecraft/minecraft-backup.sh /etc/cron.hourly/
echo "Hourly backups initiated."
#Create daily backup compression
cp /srv/minecraft/minecraft-compress.sh /etc/cron.daily/
echo "Daily backup compression initiated."
add_daemon minecraft
stat_done "Minecraft Server Stated"
else
echo "Could not start Minecraft."
echo "Unmounting /mnt/minecraft."
umount /mnt/minecraft
stat_fail
fi
fi
}
mc_stop() {
stat_busy "Stopping Minecraft Server"
if ps ax | grep -v grep | grep -v -i SCREEN | grep minecraft_server.jar > /dev/null
then
echo "Minecraft is running... stopping."
as_user "screen -p 0 -S minecraft -X eval 'stuff \"say SERVER SHUTTING DOWN IN 10 SECONDS. Saving map...\"\015'"
as_user "screen -p 0 -S minecraft -X eval 'stuff \"save-all\"\015'"
sleep 10
as_user "screen -p 0 -S minecraft -X eval 'stuff \"stop\"\015'"
sleep 7
if ps ax | grep -v grep | grep -v -i SCREEN | grep minecraft_server.jar > /dev/null
then
echo "Minecraft could not be shut down... still running."
stat_fail
else
echo "Minecraft is shut down."
#Stop map gens
rm /etc/cron.daily/minecraft-map.sh
echo "Daily map gen halted."
#Stop hourly backups
rm /etc/cron.hourly/minecraft-backup.sh
echo "Hourly backup halted."
#Stop map compression
rm /etc/cron.daily/minecraft-compress.sh
echo "Daily backup compression halted."
#Unmount tmpfs
cp -a /mnt/minecraft/* /srv/minecraft/current
umount /mnt/minecraft
echo "Files copied to HDD."
rm_daemon minecraft
stat_done "Minecraft Server stopped"
fi
else
echo "Minecraft was not running."
stat_fail
fi
}
mc_update() {
stat_busy "Updating up minecraft_server.jar"
if ps ax | grep -v grep | grep -v -i SCREEN | grep minecraft_server.jar > /dev/null
then
echo "Minecraft is running! Can't start update."
stat_fail
else
#MC_SERVER_URL=http://minecraft.net/`wget -q -O - http://www.minecraft.net/download.jsp | grep minecraft_server.jar\</a\> | cut -d \" -f 2`
as_user "cd /srv/minecraft/current && wget -O /srv/minecraft/current/minecraft_server.jar.update "https://s3.amazonaws.com/MinecraftDownload/launcher/minecraft_server.jar""
if [ -f /srv/minecraft/current/minecraft_server.jar.update ]
then
if `diff /srv/minecraft/current/minecraft_server.jar /srv/minecraft/current/minecraft_server.jar.update >/dev/null`
then
echo "Minecraft is already up to date."
rm /srv/minecraft/current/minecraft_server.jar.update
stat_done
else
as_user "mv /srv/minecraft/current/minecraft_server.jar.update /srv/minecraft/current/minecraft_server.jar"
echo "Minecraft has been updated."
rm /srv/minecraft/current/minecraft_server.jar.update
stat_done
fi
else
echo "Minecraft update could not be downloaded."
stat_fail
fi
fi
}
mc_backup() {
stat_busy "Backing up minecraft world"
if ps ax | grep -v grep | grep -v -i SCREEN | grep minecraft_server.jar > /dev/null
then
echo "Setting server to readonly."
as_user "screen -p 0 -S minecraft -X eval 'stuff \"say SERVER BACKUP STARTING. Server going readonly...\"\015'"
as_user "screen -p 0 -S minecraft -X eval 'stuff \"save-off\"\015'"
as_user "screen -p 0 -S minecraft -X eval 'stuff \"save-all\"\015'"
sync
sleep 10
echo "Server ready to backup."
fi
if [ -d /srv/minecraft/backup/world_`date "+%m.%d.%Y_%H"` ]
then
for i in 1 2 3 4 5 6
do
if [ -d /srv/minecraft/backup/world_`date "+%m.%d.%Y_%H"`-$i ]
then
continue
else
as_user "cd /mnt/minecraft && cp -r world /srv/minecraft/backup/world_`date "+%m.%d.%Y_%H"`-$i"
break
fi
done
else
as_user "cd /mnt/minecraft && cp -r world /srv/minecraft/backup/world_`date "+%m.%d.%Y_%H"`"
echo "Backed up world."
fi
if ps ax | grep -v grep | grep -v -i SCREEN | grep minecraft_server.jar > /dev/null
then
echo "Setting server to read-write."
as_user "screen -p 0 -S minecraft -X eval 'stuff \"save-on\"\015'"
as_user "screen -p 0 -S minecraft -X eval 'stuff \"say SERVER BACKUP ENDED. Server going read-write...\"\015'"
fi
echo "Backup complete."
stat_done
}
mc_map() {
stat_busy "Mapping Minecraft Server"
echo "Running c10t..."
as_user "c10t -w /mnt/minecraft/world -o /srv/minecraft/map/map_`date "+%m.%d.%Y_%H"`.png" > /dev/null
echo "Map generated."
stat_done
}
mc_status() {
if ps ax | grep -v grep | grep -v -i SCREEN | grep minecraft_server.jar > /dev/null
then
echo "Minecraft is running."
else
echo "Minecraft is not running."
fi
}
mc_compress(){
stat_busy "Compressing save..."
as_user "7z a -mx9 /srv/minecraft/backup.7z /srv/minecraft/backup/ > /dev/null"
echo "Backup folder compressed."
stat_done
}
case "$1" in
start)
mc_start
;;
stop)
mc_stop
;;
restart)
mc_stop
mc_start
;;
update)
mc_update
;;
backup)
mc_backup
;;
map)
mc_map
;;
status)
mc_status
;;
compress)
mc_compress
;;
*)
echo "Usage: /etc/rc.d/minecraft {start|stop|update|backup|status|map|compress|restart}"
exit 1
;;
esac
exit 0I edited your script. I set 7zip to compress saves into an archive because i like to hold on to the saves for a bit, just in case. The daily and hourly cron scripts just call the daemon script.
This one uses
/srv/minecraft/ , main directory (source for cron scripts, backup archive, log file for c10t)
/srv/minecraft/current/ , main source dir for minecraft
/srv/minecraft/backup/ , hourly backup dir
/mnt/minecraft/ , mount location for the running copy of minecraft (from /srv/minecraft/current/)
Offline
Hey all. I'm looking at implementing this startup script on my server and I had a couple of questions:
EDIT: I figured out the "sceen ... -X eval 'stuff ...'" part after (more than) a bit of research, so you can skip this part: First off (this is more of a basic bash question), in trying to understand the script, everything makes sense with the exception of the mc_saveoff() and mc_saveon() functions.
I'm not very familiar with screen + eval, but from what I can gather, this is sending commands to the tty that's running minecraft? ...This makes sense... but the 'stuff \" part before the command is what's confusing me.
Would someone mind giving me the quick version?
Second, I was curious as to why the hourly backup seems to save only the map and the server jar file. I could see maybe only saving the map since the map is the only thing that will be modified during runtime, but in that case, why save the server jar? Also, my world name isn't world, so with the setup I would have to modify the script, where I wouldn't if it just backed up the entire directory recursively like in the stop function.
I can of course make these changes myself, I was just curious if there was a particular reason you choose to do it this way.
And finally, an idea:
Since the server needs to be stopped in order for an update to be applied anyways, why not modify the update function to simply download the update into the offline backup dir, then modify the start function to look for the updated jar and swap it out at next startup if present? This way you could call update while the server was running, and the next time the server was restarted, the update would be applied seamlessly?
Let me know what you think.
Thanks a lot for this script, it's pretty awesome. Looking forward to getting it running on my box ![]()
Last edited by IgnisFatuus85 (2012-03-04 02:42:59)
Offline