mcontrol.sh (Minecraft-Server Steuerung)
Mit diesem Shell-Script kann man einen oder mehrere Minecraft-Server steuern, starten, beenden, neustarten, (inkrementelle) Backups erstellen, Befehle an den Server senden, usw.
Wir verwenden dieses Script für unsere Minecraft-Server.
Die aktuelle Version gibt es bei Github zum Herunterladen:
https://github.com/Natenom/mcontrol/tags.
Aktuell ist die Version 0.0.15.
Dieses Script basiert auf Server_startup_script version 0.3.2 2011-01-27; hat mittlerweile aber nicht mehr viel gemeinsam.
Ich habe es sehr stark überarbeitet, verschlankt und an eigene Bedürfnisse angepasst. Z.B. war das Original nicht in der Lage, mehrere Server zu verwalten und war ziemlich grausig gemacht; statt z.B. Funktionen zu verwenden wurde derselbe Code mehrmals geschrieben.
Lizenz
Wie auch das Original liegt dieses abgeleitete Script unter der Lizenz “CC Attribution-NonCommercial-ShareAlike 3.0 Unported“.
Kommandos von mcontrol.sh
start|stop|restart
Sollte der Minecraft-Server bei restart/stop nicht mehr reagieren, so wird mittels kill trotzdem gewährleistet, dass er beendet wird.
Beispiel:
$ mcontrol.sh /etc/minecraft-server/mcuser/kagube-survival restart craftbukkit-1.1-R4-SNAPSHOT.jar is running... stopping. craftbukkit-1.1-R4-SNAPSHOT.jar is not running... starting. craftbukkit-1.1-R4-SNAPSHOT.jar is now running.
Jeder Server wird in einer eigenen Screen-Session gestartet die dem jeweiligen Benutzer gehört. Trotzdem kann man das Script auch als root ausführen.
status
Gibt aus ob der Server läuft oder nicht.
Beispiel:
$ mcontrol.sh /etc/minecraft-server/mcuser/kagube-survival status craftbukkit-1.1-R4-SNAPSHOT.jar is running.
sendcommand|sc|c
Befehle an einen Server senden, z.B. say oder administrative Dinge
Beispiel:
$ mcontrol.sh /etc/minecraft-server/mcuser/kagube-survival sc "say Hallo"
backup
Weitere Informationen siehe hier: Inkrementelles Backupsystem.
Bei Verwendung von BACKUPSYSTEM=rdiff wird auch sichergestellt, dass das Quota eingehalten wird; dieses kann in der Konfiguration jedes Servers hinterlegt werden (BACKUP_QUOTA_MiB).
Hier die Ausgabe auf der Konsole beim Aufruf des Backups unter Verwendung von rdiff-backup:
mcuser@server:~$ mcontrol.sh /etc/minecraft-server/mcuser/kagube-survival backup craftbukkit-1.1-R4-SNAPSHOT.jar is running... suspending saves Backing up mc-server-mcuser-kagube-survival. Total backup size (2051 MiB) is less or equal quota (5000 MiB). craftbukkit-1.1-R4-SNAPSHOT.jar is running... re-enabling saves
s-to-ramd
Sync-to-Ramdisk. Synchronisiert den Inhalt von SERVERDIR_PRERUN nach SERVERDIR.
Funktioniert nur, wenn der Server aus ist.
s-from-ramd
Sync-from-Ramdisk. Synchronisiert den Inhalt von SERVERDIR nach SERVERDIR_PRERUN.
Funktioniert nur, wenn der Server aus ist.
listbackups
Funktioniert nur bei BACKUPSYSTEM=rdiff.
Zeigt eine Liste der ikrementellen Backups des Server an.
Beispiel:
mcuser@server:~$ mcontrol.sh /etc/minecraft-server/mcuser/kagube-survival backup
Backups for server "kagube-survival"
Found 230 increments:
increments.2012-02-18T23:00:12+01:00.dir Sat Feb 18 23:00:12 2012
increments.2012-02-18T23:30:13+01:00.dir Sat Feb 18 23:30:13 2012
increments.2012-02-19T00:00:12+01:00.dir Sun Feb 19 00:00:12 2012
increments.2012-02-19T00:30:15+01:00.dir Sun Feb 19 00:30:15 2012
increments.2012-02-19T01:00:15+01:00.dir Sun Feb 19 01:00:15 2012
...
Current mirror: Thu Feb 23 16:30:11 2012
Time Size Cumulative size
-----------------------------------------------------------------------------
Thu Feb 23 16:30:11 2012 379 MB 379 MB (current mirror)
Thu Feb 23 16:00:12 2012 16.5 MB 396 MB
Thu Feb 23 15:39:46 2012 4.29 MB 400 MB
Thu Feb 23 15:30:12 2012 2.37 MB 402 MB
...
lottery
Der Benutzer bekommt eine zufällige Anzahl x eines Gegenstands y.
Die notwendigen ID-Listen sind bereits im Download enthalten:
- id.list beinhaltet nur bestimmte Gegenstände; hier kann man selbst Hand anlegen.
- id.list-names beinhaltet die Namen der Gegenstände und wird automatisch erstellt; siehe Hinweis für Interessierte.
Beispiel:
$ mcontrol.sh /etc/minecraft-server/mcuser/kagube-survival lottery yourname Name: yourname Anzahl: 6 Bezeichnung(ID): SEEDS(295) Done.
Erzeugung der ID-Liste, für Interessierte:
Zuerst erstellt man aus dieser verfügbaren Liste eine eigene Liste mit ID:Name.
lynx -dump http://jd.bukkit.org/apidocs/src-html/org/bukkit/Material.html | \
sed -r -n -e 's#([A-Z_]{1,})\(([0-9]{1,3}).*#\2:\1#p' | \
awk '{ print $2 }' > /home/minecraft/id.list-names
Die generierte Liste sieht so aus:
cat /home/minecraft/id.list-names 0:AIR 1:STONE 2:GRASS 3:DIRT 4:COBBLESTONE 5:WOOD 6:SAPLING 7:BEDROCK 8:WATER 9:STATIONARY_WATER ...
Aus dieser Liste bekommen wir später für unser „gewürfeltes“ Item den Namen heraus.
pid
Man erhält die PID (Prozess ID) des Servers.
Beispiel:
$ mcontrol.sh /etc/minecraft-server/mcuser/kagube-survival status 96821
Einstellungen von mcontrol.sh
Konfigurationsdatei pro Server
Wo diese Datei liegt ist erstmal egal; jedoch sollte der Benutzer keine Schreibrechte darauf haben, damit er keinen Scheiss bauen kann, wie z.B. weitere Backupverzeichnisse hinzufügen um die Platte zu belasten, BackupQuota zu erhöhen, usw.
Z.B. für den oben aufgeführten user1 und dessen server1 die Datei /etc/minecraft-server/user1/server1:
- server1
SERVERDIR="/home/minecraft-server/mcuserx/server1-bukkit" SERVERDIR_PRERUN="/home/minecraft-server/mcuserx/server1-bukkit-prerun" BACKUPDIR="/home/minecraft-server/mcuserx/backup/serverbla" SERVERNAME="server1-bukkit" #This is the name which is used for backups and for screen sessions. Must be unique per system user. JAR_FILE="craftbukkit.jar" DONT_START="nostart" #If this file exists in ${SERVERDIR}, mcontrol won't start the server. CPU_COUNT=8 #Number of threads BACKUP_QUOTA_MiB=8000 MAX_RAM=2048M #Max RAM usage ... :/ BACKUPSYSTEM="rdiff" #This overrides setting in mcontrol.sh RUNSERVER_NICE="" #run Server with nicelevel (complete command needed, e.g. RUNSERVER_NICE="nice -n19") RUNSERVER_TASKSET="" #Set CPU affinity of a server with taskset command, e.g. RUNSERVER_TASKSET="taskset -c 1" RUNBACKUP_NICE="nice -n19" #run Backup with nicelevel (complete command needed, e.g. RUNBACKUP_NICE="nice -n19") RUNBACKUP_IONICE="ionice -c 3" #only relevant for backup
Inkrementelles Backupsystem
Es gibt zwei Programme, mittels derer das Backup erstellt wird:
- rdiff-backup (Standard)
- tar
Die Einstellung in der Konfiguration heißt BACKUPSYSTEM und findet sich am Anfang von mcontrol.sh oder kann auch in jeder Servereinstellungs-Datei eingetragen werden.
Wenn man BACKUPSYSTEM auf NONE oder irgendwas ungleich rdiff oder tar einstellt, wird kein Backup erstellt.
Standardwert bei Version 0.0.11 ist rdiff.
Mit rdiff-backup (bevorzugt)
Verwendet immer denselben Backupordner und legt dort seine differenziellen Backups ab. Man kann sehr einfach einen bestimmten Zeitpunkt wiederherstellen. Diese Einstellung wird für „Anfänger“ empfohlen.
Ausserdem verbraucht rdiff sehr viel weniger Platz für die Backups, da es lediglich die Unterschiede von Dateien komprimiert ablegt, während tar die ganze Datei erneut ablegt. Wenn also tar im Durschschnitt für jedes neue differenzielle Backup zwischen 30-80 MiB verbraucht, verbraucht rdiff-backup zwischen 3-11 MiB :)
Es wird bei Verwendung von rdiff-backup ein Quota verwendet und arbeitet seit der Version 0.0.11 auf 1 MiB genau. Bei Überschreibung wird solange das jeweils älteste Backup gelöscht, bis das Quota wieder unterschritten ist.
Weitere Informationen zu rdiff-backup gibt es hier: http://www.nongnu.org/rdiff-backup/.
Mit tar
Beim ersten Start mit dem Parameter Backup jeden Tag wird ein Vollbackup des Servers erstellt, für den Rest des Tages dann nur noch inkrementelle Backups (also nur das, was sich im Vergleich zum vorherigen Backup auch geändert hat).
Wenn das Quota überschritten ist werden solange die ältesten, kompletten Tagesbackups gelöscht, bis genug Platz frei ist.
Vorteile:
- tar ist auf jedem System bereits vorinstalliert.
- Für jeden Tag wird ein eigener Ordner erstellt.
Nachteile:
- Die Handhabung beim Restore ist etwas schwieriger als bei rdiff-backup.
Server in Ramdisk (tmpfs) laufen lassen
Seit Version 0.1.14 ist es auch möglich, den Server in einer Ramdisk (tmpfs) laufen zu lassen.
Dafür gibt es eine neue Variable SERVERDIR_PRERUN. In diesem Verzeichnis liegt der eigentliche Server.
SERVERDIR wird vom Administrator des Servers als tmpfs gemountet.
mcontrol kümmert sich darum, bei einem entsprechenden Aufruf (s-to-ramd) die Daten von SERVERDIR_PRERUN nach SERVERDIR in die Ramdisk zu kopieren (mittels rsync).
Dabei wird folgendes überprüft:
- ob der Server läuft
- ob das Verzeichnis von SERVERDIR_PRERUN leer ist, falls ja, kann etwas nicht stimmen und die Aktion wird abgebrochen
- ob in SERVERDIR ein tmpfs gemountet ist
Ein weiteres Kommando (s-from-ramd) kopiert die Daten von der Ramdisk wieder zurück ins Verzeichnis von SERVERDIR_PRERUN.
Danach kann die RAMDisk in SERVERDIR deaktiviert werden.
Anmerkungen
Man muss sich manuell darum kümmern, zu welchem Zeitpunkt gesynct wird; das bei jedem Start/Stop eines Server automatisch zu tun, wäre vermutlich sinnlos.
Im Idealfall braucht man das s-to-ramd nur nach dem Starten des gesamten Linux-Servers und s-from-ramd nur vor dem Herunterfahren.
Kompatibilität
Generell
Da sich das Verzeichnis, in dem der Server dann letztlich läuft, nicht ändert, funktioniert alles Weitere ohne Änderungen.
Backup
Das in mcontrol integrierte Backup verwendet weiterhin das Verzeichnis SERVERDIR für Backups, allerdings prüft es vor dem Backup, ob das Verzeichnis leer ist.
Ist es leer, so läuft entweder der Server nicht oder es gab einen Fehler. Gerade bei inkrementellen Backups wäre es schädlich, ein Backup zu machen, da dies das Backupverzeichnis jedes Mal aufblähen würde.
Mehrere Server pro Benutzer direkt möglich
Einstellungen und Screen-Sessions sind Serverbasiert, nicht Benutzer basiert.
Solange eine bestimmte Datei existiert, startet der Server nicht
Name der Datei ist einstellbar in der Konfiguration pro Server.
Überprüft wird die Existenz der Datei nur bei der Funktion mc_start().
Hilfe
Beim Aufruf ohne weitere Angaben:
Usage: mcontrol.sh SETTINGS_FILE COMMAND [ARGUMENT]
COMMANDS
start Start the server.
stop Stop the server.
restart Restart the server.
backup Backup the server.
listbackups List current inkremental backups (only available for BACKUPSYSTEM="rdiff").
status Prints current status of the server (online/offline)
sendcommand|sc|c Send command to the server given as [ARGUMENT]
lottery <playername> Gives a player a random count of a random item. (Player must have a free inventory slot.)
pid Get pid of a server process.
EXAMPLES
Send a message to all players on the server:
mcontrol.sh SETTINGS_FILE sendcommand "say We are watching you :P"
Give me some golden apples:
mcontrol.sh /etc/minecraft-server/userx/serverx sendcommand "give yourname 322 100"
Todo
- Durchgehend Englisch verwenden.
- http://www.nongnu.org/duplicity/index.html zusätzlich zu tar und rdiff ermöglichen.
- hidepid … neu in Kernel 3.3
mcontrol mag es nicht wenn man /proc mit hidepid > 0 gemountet hat
Verzeichnisstrukturen
Serververzeichnisse
Als Beispiel eine Verzeichnisstruktur der Minecraft-Server/Benutzer:
/home/minecraft-server/
user1/
server1/...
server2/...
user2/
server1/...
server2/...
Backupverzeichnis bei Verwendung von tar
Als Beispiel eine Verzeichnisstruktur für Backups, die alle 30 Minuten gemacht werden:
/home/minecraft-server/user/backups/server1/2011-07-18/
servername.snap
servername.00-00-00.full.tar
servername-00-30-00.inc.tar
servername-01-00-00.inc.tar
servername-01-30-00.inc.tar
...
/home/minecraft-server/user/backups/server1/2011-07-19/
servername.snap
servername.21-00-00.full.tar
servername-21-30-00.inc.tar
servername-22-00-00.inc.tar
servername-22-30-00.inc.tar
Die .snap-Datei wird nur von tar verwendet um Metainformationen zu Dateien zu speichern um herauszufinden welche sich geändert haben und gesichert werden müssen.
Und wie funktioniert der Restore?
Bei Verwendung von BACKUPSYSTEM="tar"
Bei Verwendung von BACKUPSYSTEM="rdiff"
In mcontrol selbst kann man sich nur die bisher gemachten inkrementellen Backups ansehen:
mcontrol.sh file/to/settings/serverx listbackups
Zum Restore verweise ich auf die Manpage:
Die Manpage von rdiff-backup ist ziemlich ausführlich und mit Beispielen gespickt; es ist also nicht notwendig bestimmte Funktionen ins Script einzubauen.
Für das Restore sollte man also am besten direkt das Kommando rdiff-backup verwenden :)
