Completed minecraft backup feature

This commit is contained in:
Jamie Cameron
2013-03-10 21:59:31 -07:00
parent 4e1a32c78e
commit 268fb58bb9
9 changed files with 153 additions and 8 deletions

5
minecraft/CHANGELOG Normal file
View File

@@ -0,0 +1,5 @@
---- Changes since 1.0 ----
Added a page for setting up scheduled backups of some or all worlds on the server.
Added a warning message on the main page if the server version is out of date.
German translations from Raymond Vetter.
Added a list of recent events for a player to the Manage Player page.

BIN
minecraft/images/backup.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

@@ -61,16 +61,19 @@ if ($config{'last_size'}) {
my @links = ( "edit_conf.cgi", "edit_users.cgi",
"view_logs.cgi", "list_conns.cgi",
"list_worlds.cgi", "edit_cmds.cgi",
"console.cgi", "edit_manual.cgi" );
"console.cgi", "edit_backup.cgi",
"edit_manual.cgi" );
my @titles = ( $text{'conf_title'}, $text{'users_title'},
$text{'logs_title'}, $text{'conns_title'},
$text{'worlds_title'}, $text{'cmds_title'},
$text{'console_title'}, $text{'manual_title'} );
$text{'console_title'}, $text{'backup_title'},
$text{'manual_title'} );
my @icons = ( "images/conf.gif", "images/users.gif",
"images/logs.gif", "images/conns.gif",
"images/worlds.gif", "images/cmds.gif",
"images/console.gif", "images/manual.gif" );
&icons_table(\@links, \@titles, \@icons);
"images/console.gif", "images/backup.gif",
"images/manual.gif" );
&icons_table(\@links, \@titles, \@icons, 5);
print &ui_hr();
print &ui_buttons_start();

View File

@@ -257,6 +257,23 @@ download_err=Failed to setup Minecraft server
download_edir=Missing or non-absolute install directory
download_euser=User to run as does not exist
backup_title=Scheduled Backup
backup_header=Options for scheduled world backup
backup_sched=Backup schedule
backup_enabled=Backup enabled?
backup_dir=Backup to directory
backup_worlds=Worlds to include
backup_worlds1=All worlds
backup_worlds0=Only selected ..
backup_err=Failed to save scheduled backup
backup_edir=Missing or non-absolute destination directory
backup_eworlds=No worlds selected
backup_desc=This page allows you to setup automatic scheduled backups of your Minecraft server worlds. The destination directory can contain strftime-style date codes like %d, %m and %Y to save separate daily backups.
backup_email=Email backup report to
backup_noemail=Nobody
backup_email_err=Only send email on failure
backup_emailto=Address
log_conf=Changed server configuration
log_stop=Stopped Minecraft server
log_start=Started Minecraft server
@@ -267,3 +284,5 @@ log_ip=Updated banned IPs
log_manual=Manually edited configuration file
log_atboot=Enabled server at boot time
log_delboot=Disabled server at boot time
log_enable_backup=Enabled scheduled backups to $1
log_disable_backup=Disabled scheduled backups

View File

@@ -8,6 +8,11 @@ do 'minecraft-lib.pl';
sub parse_webmin_log
{
my ($user, $script, $action, $type, $object, $p) = @_;
return $text{'log_'.$action};
if ($object eq 'backup') {
return &text('log_'.$action.'_backup', $object);
}
else {
return $text{'log_'.$action};
}
}

View File

@@ -5,6 +5,7 @@ use strict;
use warnings;
use WebminCore;
use Time::Local;
use POSIX;
&init_config();
our ($module_root_directory, %text, %gconfig, $root_directory, %config,
$module_name, $remote_user, $base_remote_user, $gpgpath,
@@ -199,6 +200,7 @@ my $pid = &is_minecraft_server_running();
$pid || return "Not running!";
# Try graceful shutdown
&send_server_command("/save-all");
&send_server_command("/stop");
for(my $i=0; $i<10; $i++) {
last if (!&is_minecraft_server_running());
@@ -605,4 +607,115 @@ while(1) {
return $header{'content-length'};
}
# get_backup_job()
# Returns the webmincron job to backup worlds
sub get_backup_job
{
&foreign_require("webmincron");
my @jobs = &webmincron::list_webmin_crons();
my ($job) = grep { $_->{'module'} eq $module_name &&
$_->{'func'} eq "backup_worlds" } @jobs;
return $job;
}
# backup_worlds()
# This function is called by webmincron to perform a backup
sub backup_worlds
{
# Get worlds to include
my @allworlds = &list_worlds();
my @worlds;
if ($config{'backup_worlds'}) {
my %names = map { $_, 1 } split(/\s+/, $config{'backup_worlds'});
@worlds = grep { $names{$_->{'name'}} } @allworlds;
}
else {
@worlds = @allworlds;
}
if (!@worlds) {
&send_backup_email("No worlds were found to backup!", 1);
return;
}
# Get destination dir, with strftime
my @tm = localtime(time());
&clear_time_locale();
my $dir = strftime($config{'backup_dir'}, @tm);
&reset_time_locale();
# Create destination dir
if (!-d $dir) {
if (!&make_dir($dir, 0700)) {
&send_backup_email(
"Failed to create destination directory $dir : $!");
return;
}
if ($config{'unix_user'} ne 'root') {
&set_ownership_permissions($config{'unix_user'}, undef, undef,
$dir);
}
}
# Find active world
my $conf = &get_minecraft_config();
my $def = &find_value("level-name", $conf);
# Backup each world
my @out;
my $failed = 0;
foreach my $w (@worlds) {
my $file = "$dir/$w->{'name'}.zip";
push(@out, "Backing up $w->{'name'} to $file ..");
if ($w->{'name'} eq $def &&
&is_minecraft_server_running()) {
# World is live, flush state to disk
&execute_minecraft_command("save-off");
&execute_minecraft_command("save-all");
}
my $out = &backquote_command(
"cd ".quotemeta($config{'minecraft_dir'})." && ".
"zip -r ".quotemeta($file)." ".quotemeta($w->{'name'}));
my $ex = $?;
if ($w->{'name'} eq $def &&
&is_minecraft_server_running()) {
# Re-enable world writes
&execute_minecraft_command("save-on");
}
my @st = stat($file);
if (@st && $config{'unix_user'} ne 'root') {
&set_ownership_permissions($config{'unix_user'}, undef, undef,
$file);
}
if ($ex) {
push(@out, " .. ZIP of $w->{'name'} failed : $out");
$failed++;
}
elsif (!@st) {
push(@out, " .. ZIP of $w->{'name'} produced no output : $out");
$failed++;
}
else {
push(@out, " .. done (".&nice_size($st[7]).")");
}
push(@out, "");
}
&send_backup_email(join("\n", @out)."\n", $failed);
}
# send_backup_email(msg, error)
# Sends a backup report email, if configured
sub send_backup_email
{
my ($msg, $err) = @_;
return 0 if (!$config{'backup_email'});
return 0 if ($config{'backup_email_err'} && !$err);
&foreign_require("mailboxes");
&mailboxes::send_text_mail(
&mailboxes::get_from_address(),
$config{'backup_email'},
undef,
"Minecraft backup ".($err ? "FAILED" : "succeeded"),
$msg);
}
1;

View File

@@ -2,4 +2,4 @@ desc=Minecraft Server
depends=init proc
category=servers
desc_de=Minecraft Server
version=1.0
version=1.1

View File

@@ -112,8 +112,8 @@ elsif ($in{'download'} && $ENV{'PATH_INFO'}) {
if (&is_minecraft_server_running() &&
$def eq $in{'name'}) {
# Flush state to disk
&execute_minecraft_command("save-all");
&execute_minecraft_command("save-off");
&execute_minecraft_command("save-all");
}
my $temp = &transname().".zip";
my $out = &backquote_command(

View File

@@ -93,7 +93,7 @@ if ($c || 1) {
# Ban or un-ban player
my @banlist = &list_banned_players();
my ($b) = grep { $_ eq $in{'name'} } @banlist;
my ($b) = grep { lc($_) eq lc($in{'name'}) } @banlist;
if ($b) {
print &ui_table_row($text{'conn_banlist'},
"<font color=red>$text{'conn_banned'}</font> ".