Added executable updater

This commit is contained in:
Andrew McManus 2021-07-24 21:09:39 -04:00
parent 47305d74d9
commit 9cb46a86fb
9 changed files with 105 additions and 1 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

View File

@ -12,6 +12,7 @@ import logging
import html import html
import zipfile import zipfile
import pathlib import pathlib
import shutil
from datetime import datetime from datetime import datetime
from socket import gethostname from socket import gethostname
@ -561,5 +562,31 @@ class Helpers:
zf.write(os.path.join(root, file), zf.write(os.path.join(root, file),
os.path.relpath(os.path.join(root, file), os.path.relpath(os.path.join(root, file),
os.path.join(path, '..'))) os.path.join(path, '..')))
@staticmethod
def copy_files(source, dest):
if os.path.isfile(source):
shutil.copyfile(source, dest)
logger.info("Copying jar %s to %s", source, dest)
else:
logger.info("Source jar does not exist.")
@staticmethod
def download_file(executable_url, jar_path):
try:
r = requests.get(executable_url, timeout=5)
except Exception as ex:
logger.error("Could not download executable: %s", ex)
return False
if r.status_code != 200:
logger.error("Unable to download file from %s", executable_url)
return False
try:
open(jar_path, "wb").write(r.content)
except Exception as e:
logger.error("Unable to finish executable download. Error: %s", e)
return False
return True
helper = Helpers() helper = Helpers()

View File

@ -122,6 +122,7 @@ class Servers(BaseModel):
auto_start_delay = IntegerField(default=10) auto_start_delay = IntegerField(default=10)
crash_detection = BooleanField(default=0) crash_detection = BooleanField(default=0)
stop_command = CharField(default="stop") stop_command = CharField(default="stop")
executable_update_url = CharField(default="")
server_ip = CharField(default="127.0.0.1") server_ip = CharField(default="127.0.0.1")
server_port = IntegerField(default=25565) server_port = IntegerField(default=25565)
logs_delete_after = IntegerField(default=0) logs_delete_after = IntegerField(default=0)

View File

@ -42,6 +42,7 @@ class Server:
self.settings = None self.settings = None
self.updating = False self.updating = False
self.server_id = None self.server_id = None
self.jar_update_url = None
self.name = None self.name = None
self.is_crashed = False self.is_crashed = False
self.restart_count = 0 self.restart_count = 0
@ -341,3 +342,39 @@ class Server:
return [{"path": os.path.relpath(f['path'], start=conf['backup_path']), "size": f["size"]} for f in files] return [{"path": os.path.relpath(f['path'], start=conf['backup_path']), "size": f["size"]} for f in files]
else: else:
return [] return []
def jar_update(self):
#checks if server is running. Calls shutdown if it is running.
if self.check_running():
logger.info("Server with PID %s is running. Sending shutdown command", self.PID)
self.stop_threaded_server()
else:
backup_dir = os.path.join(self.settings['path'], 'crafty_executable_backups')
#checks if backup directory already exists
if os.path.isdir(backup_dir):
backup_executable = os.path.join(backup_dir, 'old_server.jar')
else:
logger.info("Executable backup directory not found for Server: {}}. Creating one.", self.name)
os.mkdir(backup_dir)
backup_executable = os.path.join(backup_dir, 'old_server.jar')
if os.path.isfile(backup_executable):
#removes old backup
logger.info("Old backup found for server: {}. Removing...", self.name)
os.remove(backup_executable)
logger.info("Old backup removed for server: {}.", self.name)
else:
logger.info("No old backups found for server: {}", self.name)
current_executable = os.path.join(self.settings['path'], self.settings['executable'])
#copies to backup dir
helper.copy_files(current_executable, backup_executable)
#boolean returns true for false for success
downloaded = helper.download_file(self.settings['executable_update_url'], current_executable)
if downloaded:
logger.info("Executable updated successfully.")
else:
logger.error("Executable download failed.")

View File

@ -110,6 +110,9 @@ class TasksManager:
elif command == "backup_server": elif command == "backup_server":
svr.backup_server() svr.backup_server()
elif command == "update_executable":
svr.jar_update()
db_helper.mark_command_complete(c.get('command_id', None)) db_helper.mark_command_complete(c.get('command_id', None))
time.sleep(1) time.sleep(1)

View File

@ -426,6 +426,7 @@ class PanelHandler(BaseHandler):
auto_start_delay = self.get_argument('auto_start_delay', '10') auto_start_delay = self.get_argument('auto_start_delay', '10')
server_ip = self.get_argument('server_ip', None) server_ip = self.get_argument('server_ip', None)
server_port = self.get_argument('server_port', None) server_port = self.get_argument('server_port', None)
executable_update_url = self.get_argument('executable_update_url', None)
auto_start = int(float(self.get_argument('auto_start', '0'))) auto_start = int(float(self.get_argument('auto_start', '0')))
crash_detection = int(float(self.get_argument('crash_detection', '0'))) crash_detection = int(float(self.get_argument('crash_detection', '0')))
logs_delete_after = int(float(self.get_argument('logs_delete_after', '0'))) logs_delete_after = int(float(self.get_argument('logs_delete_after', '0')))
@ -454,6 +455,7 @@ class PanelHandler(BaseHandler):
Servers.server_ip: server_ip, Servers.server_ip: server_ip,
Servers.server_port: server_port, Servers.server_port: server_port,
Servers.auto_start: auto_start, Servers.auto_start: auto_start,
Servers.executable_update_url: executable_update_url,
Servers.crash_detection: crash_detection, Servers.crash_detection: crash_detection,
Servers.logs_delete_after: logs_delete_after, Servers.logs_delete_after: logs_delete_after,
}).where(Servers.server_id == server_id).execute() }).where(Servers.server_id == server_id).execute()

View File

@ -106,6 +106,11 @@
<input type="number" class="form-control" name="auto_start_delay" id="auto_start_delay" value="{{ data['server_stats']['server_id']['auto_start_delay'] }}" step="1" max="999" min="10" > <input type="number" class="form-control" name="auto_start_delay" id="auto_start_delay" value="{{ data['server_stats']['server_id']['auto_start_delay'] }}" step="1" max="999" min="10" >
</div> </div>
<div class="form-group">
<label for="executable_update_url">{{ translate('serverConfig', 'exeUpdateURL') }} <small class="text-muted ml-1"> - {{ translate('serverConfig', 'exeUpdateURLDesc') }}</small> </label>
<input type="text" class="form-control" name="executable_update_url" id="executable_update_url" value="{{ data['server_stats']['server_id']['executable_update_url'] }}" placeholder="{{ translate('serverConfig', 'exeUpdateURL') }}" >
</div>
<div class="form-group"> <div class="form-group">
<label for="server_ip">{{ translate('serverConfig', 'serverPort') }} <small class="text-muted ml-1"> - {{ translate('serverConfig', 'serverPortDesc') }}</small> </label> <label for="server_ip">{{ translate('serverConfig', 'serverPort') }} <small class="text-muted ml-1"> - {{ translate('serverConfig', 'serverPortDesc') }}</small> </label>
<input type="text" class="form-control" name="server_ip" id="server_ip" value="{{ data['server_stats']['server_id']['server_ip'] }}"> <input type="text" class="form-control" name="server_ip" id="server_ip" value="{{ data['server_stats']['server_id']['server_ip'] }}">
@ -159,9 +164,11 @@
</div> </div>
<div class="text-center"> <div class="text-center">
{% if data['server_stats']['running'] %} {% if data['server_stats']['running'] %}
<button onclick="send_command(server_id, 'update_executable');" id="update_executable" style="max-width: 7rem;" class="btn btn-warning m-1 flex-grow-1 disabled">{{ translate('serverConfig', 'update') }}</button>
<a class="btn btn-sm btn-danger disabled">{{ translate('serverConfig', 'deleteServer') }}</a><br /> <a class="btn btn-sm btn-danger disabled">{{ translate('serverConfig', 'deleteServer') }}</a><br />
<small>{{ translate('serverConfig', 'stopBeforeDeleting') }}</small> <small>{{ translate('serverConfig', 'stopBeforeDeleting') }}</small>
{% else %} {% else %}
<button onclick="send_command(server_id, 'update_executable');" id="update_executable" style="max-width: 7rem;" class="btn btn-warning m-1 flex-grow-1">{{ translate('serverConfig', 'update') }}</button>
<a href="/panel/remove_server?id={{ data['server_stats']['server_id']['server_id'] }}" class="btn btn-sm btn-danger">{{ translate('serverConfig', 'deleteServer') }}</a> <a href="/panel/remove_server?id={{ data['server_stats']['server_id']['server_id'] }}" class="btn btn-sm btn-danger">{{ translate('serverConfig', 'deleteServer') }}</a>
{% end %} {% end %}
@ -196,6 +203,28 @@
}); });
let server_id = '{{ data['server_stats']['server_id']['server_id'] }}';
function send_command (server_id, command){
<!-- this getCookie function is in base.html-->
var token = getCookie("_xsrf");
$.ajax({
type: "POST",
headers: {'X-XSRFToken': token},
url: '/server/command?command=' + command + '&id=' + server_id,
success: function(data){
console.log("got response:");
console.log(data);
setTimeout(function(){ location.reload(); }, 10000);
}
});bootbox.alert({
backdrop: true,
title: '{% raw translate("serverConfig", "sendingRequest") %}',
message: '<div align="center"><i class="fas fa-spin fa-spinner"></i> &nbsp; {% raw translate("serverConfig", "bePatientUpdate") %} </div>'
});
}
</script> </script>

View File

@ -198,7 +198,12 @@
"save": "Save", "save": "Save",
"cancel": "Cancel", "cancel": "Cancel",
"deleteServer": "Delete Server", "deleteServer": "Delete Server",
"stopBeforeDeleting": "Please stop the server before deleting it" "stopBeforeDeleting": "Please stop the server before deleting it",
"exeUpdateURLDesc": "Direct Download URL for updates.",
"exeUpdateURL": "Server Executable Update URL",
"update": "Update Executable",
"bePatientUpdate": "Please be patient while we update the server.<br /> This screen will refresh in a moment",
"sendingRequest": "Sending your request..."
}, },
"serverConfigHelp": { "serverConfigHelp": {
"title": "Server Config Area", "title": "Server Config Area",

BIN
paper-1.17.1.jar Normal file

Binary file not shown.