diff --git a/app/classes/controllers/management_controller.py b/app/classes/controllers/management_controller.py index 6f4da3cb..057ffd5e 100644 --- a/app/classes/controllers/management_controller.py +++ b/app/classes/controllers/management_controller.py @@ -75,7 +75,7 @@ class ManagementController: # Commands Methods # ********************************************************************************** - def send_command(self, user_id, server_id, remote_ip, command): + def send_command(self, user_id, server_id, remote_ip, command, action_id=None): server_name = HelperServers.get_server_friendly_name(server_id) # Example: Admin issued command start_server for server Survival @@ -86,7 +86,12 @@ class ManagementController: remote_ip, ) self.queue_command( - {"server_id": server_id, "user_id": user_id, "command": command} + { + "server_id": server_id, + "user_id": user_id, + "command": command, + "action_id": action_id, + } ) def queue_command(self, command_data): diff --git a/app/classes/shared/server.py b/app/classes/shared/server.py index a6c98b89..0302b803 100644 --- a/app/classes/shared/server.py +++ b/app/classes/shared/server.py @@ -207,9 +207,6 @@ class ServerInstance: self.server_scheduler.start() self.dir_scheduler.start() self.start_dir_calc_task() - self.backup_thread = threading.Thread( - target=self.backup_server, daemon=True, name=f"backup_{self.name}" - ) self.is_backingup = False # Reset crash and update at initialization self.stats_helper.server_crash_reset() @@ -940,8 +937,7 @@ class ServerInstance: WebSocketManager().broadcast_user(user, "send_start_reload", {}) def restart_threaded_server(self, user_id): - bu_conf = HelpersManagement.get_backup_config(self.server_id) - if self.is_backingup and bu_conf["shutdown"]: + if self.is_backingup: logger.info( "Restart command detected. Supressing - server has" " backup shutdown enabled and server is currently backing up." @@ -1111,12 +1107,12 @@ class ServerInstance: f.write("eula=true") self.run_threaded_server(user_id) - def a_backup_server(self): - if self.settings["backup_path"] == "": - logger.critical("Backup path is None. Canceling Backup!") - return + def a_backup_server(self, backup_id): backup_thread = threading.Thread( - target=self.backup_server, daemon=True, name=f"backup_{self.name}" + target=self.backup_server, + daemon=True, + name=f"backup_{self.name}", + args=[backup_id], ) logger.info( f"Starting Backup Thread for server {self.settings['server_name']}." @@ -1144,7 +1140,7 @@ class ServerInstance: logger.info(f"Backup Thread started for server {self.settings['server_name']}.") @callback - def backup_server(self): + def backup_server(self, backup_id): was_server_running = None logger.info(f"Starting server {self.name} (ID {self.server_id}) backup") server_users = PermissionsServers.get_server_user_list(self.server_id) @@ -1157,7 +1153,12 @@ class ServerInstance: ).format(self.name), ) time.sleep(3) - conf = HelpersManagement.get_backup_config(self.server_id) + conf = HelpersManagement.get_backup_config(backup_id) + backup_location = conf["backup_location"] + if not backup_location: + Console.critical("No backup path found. Canceling") + self.is_backingup = False + return None if conf["before"]: if self.check_running(): logger.debug( @@ -1177,10 +1178,10 @@ class ServerInstance: self.stop_server() was_server_running = True - self.helper.ensure_dir_exists(self.settings["backup_path"]) + self.helper.ensure_dir_exists(backup_location) try: backup_filename = ( - f"{self.settings['backup_path']}/" + f"{backup_location}/" f"{datetime.datetime.now().astimezone(self.tz).strftime('%Y-%m-%d_%H-%M-%S')}" # pylint: disable=line-too-long ) logger.info( @@ -1188,36 +1189,24 @@ class ServerInstance: f" (ID#{self.server_id}, path={self.server_path}) " f"at '{backup_filename}'" ) - excluded_dirs = HelpersManagement.get_excluded_backup_dirs(self.server_id) + excluded_dirs = HelpersManagement.get_excluded_backup_dirs(backup_id) server_dir = Helpers.get_os_understandable_path(self.settings["path"]) - if conf["compress"]: - logger.debug( - "Found compress backup to be true. Calling compressed archive" - ) - self.file_helper.make_compressed_backup( - Helpers.get_os_understandable_path(backup_filename), - server_dir, - excluded_dirs, - self.server_id, - ) - else: - logger.debug( - "Found compress backup to be false. Calling NON-compressed archive" - ) - self.file_helper.make_backup( - Helpers.get_os_understandable_path(backup_filename), - server_dir, - excluded_dirs, - self.server_id, - ) + + self.file_helper.make_backup( + Helpers.get_os_understandable_path(backup_filename), + server_dir, + excluded_dirs, + self.server_id, + conf["compress"], + ) while ( - len(self.list_backups()) > conf["max_backups"] + len(self.list_backups(backup_location)) > conf["max_backups"] and conf["max_backups"] > 0 ): backup_list = self.list_backups() oldfile = backup_list[0] - oldfile_path = f"{conf['backup_path']}/{oldfile['path']}" + oldfile_path = f"{backup_location}/{oldfile['path']}" logger.info(f"Removing old backup '{oldfile['path']}'") os.remove(Helpers.get_os_understandable_path(oldfile_path)) @@ -1297,28 +1286,26 @@ class ServerInstance: except: return {"percent": 0, "total_files": 0} - def list_backups(self): - if not self.settings["backup_path"]: + def list_backups(self, backup_location): + if not backup_location: logger.info( f"Error putting backup file list for server with ID: {self.server_id}" ) return [] if not Helpers.check_path_exists( - Helpers.get_os_understandable_path(self.settings["backup_path"]) + Helpers.get_os_understandable_path(backup_location) ): return [] files = Helpers.get_human_readable_files_sizes( Helpers.list_dir_by_date( - Helpers.get_os_understandable_path(self.settings["backup_path"]) + Helpers.get_os_understandable_path(backup_location) ) ) return [ { "path": os.path.relpath( f["path"], - start=Helpers.get_os_understandable_path( - self.settings["backup_path"] - ), + start=Helpers.get_os_understandable_path(backup_location), ), "size": f["size"], } diff --git a/app/classes/shared/tasks.py b/app/classes/shared/tasks.py index 57e3c4d0..af3d8227 100644 --- a/app/classes/shared/tasks.py +++ b/app/classes/shared/tasks.py @@ -140,7 +140,7 @@ class TasksManager: ) elif command == "backup_server": - svr.a_backup_server() + svr.a_backup_server(cmd["action_id"]) elif command == "update_executable": svr.jar_update() diff --git a/app/classes/web/routes/api/api_handlers.py b/app/classes/web/routes/api/api_handlers.py index a30350a5..20586b1a 100644 --- a/app/classes/web/routes/api/api_handlers.py +++ b/app/classes/web/routes/api/api_handlers.py @@ -273,7 +273,7 @@ def api_handlers(handler_args): handler_args, ), ( - r"/api/v2/servers/([a-z0-9-]+)/action/([a-z_]+)/?", + r"/api/v2/servers/([a-z0-9-]+)/action/([a-z_]+)/([a-z0-9-]+)/?", ApiServersServerActionHandler, handler_args, ), diff --git a/app/classes/web/routes/api/servers/server/action.py b/app/classes/web/routes/api/servers/server/action.py index aba06da3..3608058f 100644 --- a/app/classes/web/routes/api/servers/server/action.py +++ b/app/classes/web/routes/api/servers/server/action.py @@ -10,7 +10,7 @@ logger = logging.getLogger(__name__) class ApiServersServerActionHandler(BaseApiHandler): - def post(self, server_id: str, action: str): + def post(self, server_id: str, action: str, action_id=None): auth_data = self.authenticate_user() if not auth_data: return @@ -54,7 +54,7 @@ class ApiServersServerActionHandler(BaseApiHandler): return self._agree_eula(server_id, auth_data[4]["user_id"]) self.controller.management.send_command( - auth_data[4]["user_id"], server_id, self.get_remote_ip(), action + auth_data[4]["user_id"], server_id, self.get_remote_ip(), action, action_id ) self.finish_json( @@ -93,7 +93,6 @@ class ApiServersServerActionHandler(BaseApiHandler): new_server_name, new_server_id, new_server_path, - new_backup_path, new_server_command, server_data.get("executable"), new_server_log_path, diff --git a/app/frontend/templates/panel/server_backup.html b/app/frontend/templates/panel/server_backup.html index 63cfaca2..2a34902c 100644 --- a/app/frontend/templates/panel/server_backup.html +++ b/app/frontend/templates/panel/server_backup.html @@ -101,8 +101,8 @@ @@ -218,9 +218,10 @@ return r ? r[1] : undefined; } - async function backup_started() { + async function backup_started(backup_id) { const token = getCookie("_xsrf") - let res = await fetch(`/api/v2/servers/${server_id}/action/backup_server`, { + console.log(backup_id) + let res = await fetch(`/api/v2/servers/${server_id}/action/backup_server/${backup_id}/`, { method: 'POST', headers: { 'X-XSRFToken': token @@ -322,53 +323,6 @@ } $(document).ready(function () { - $("#backup-form").on("submit", async function (e) { - e.preventDefault(); - const token = getCookie("_xsrf") - let backupForm = document.getElementById("backup-form"); - - let formData = new FormData(backupForm); - //Remove checks that we don't need in form data. - formData.delete("after-check"); - formData.delete("before-check"); - //Create an object from the form data entries - let formDataObject = Object.fromEntries(formData.entries()); - //We need to make sure these are sent regardless of whether or not they're checked - formDataObject.compress = $("#compress").prop('checked'); - formDataObject.shutdown = $("#shutdown").prop('checked'); - let excluded = []; - $('input.excluded:checkbox:checked').each(function () { - excluded.push($(this).val()); - }); - if ($("#root_files_button").hasClass("clicked")) { - formDataObject.exclusions = excluded; - } - delete formDataObject.root_path - console.log(excluded); - console.log(formDataObject); - // Format the plain form data as JSON - let formDataJsonString = JSON.stringify(formDataObject, replacer); - - console.log(formDataJsonString); - - let res = await fetch(`/api/v2/servers/${server_id}/backups/`, { - method: 'PATCH', - headers: { - 'X-XSRFToken': token - }, - body: formDataJsonString, - }); - let responseData = await res.json(); - if (responseData.status === "ok") { - window.location.reload(); - } else { - - bootbox.alert({ - title: responseData.error, - message: responseData.error_data - }); - } - }); try { if ($('#backup_path').val() == '') { @@ -461,8 +415,8 @@ } }); }); - $("#backup_now_button").click(function () { - backup_started(); + $(".backup_now_button").click(function () { + backup_started($(this).data('backup')); }); });