Working default backup

This commit is contained in:
amcmanu3 2024-05-25 14:40:14 -04:00
parent f8626633cf
commit 60d3ee1aa8
6 changed files with 49 additions and 104 deletions

View File

@ -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):

View File

@ -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"],
}

View File

@ -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()

View File

@ -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,
),

View File

@ -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,

View File

@ -101,8 +101,8 @@
</button>
<button data-backup={{ backup.backup_id }} data-toggle="tooltip"
title="{{ translate('serverBackups', 'run', data['lang']) }}"
class="btn btn-outline-warning test-socket">
<i class="fa-solid fa-vial"></i>
class="btn btn-outline-warning run-backup backup_now_button">
<i class="fa-solid fa-forward"></i>
</button>
</td>
</tr>
@ -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'));
});
});