mirror of
https://gitlab.com/crafty-controller/crafty-4.git
synced 2024-08-30 18:23:09 +00:00
Merge branch 'bugfix/backups' into 'dev'
Fix Backup Restore/Schedules, Backup button See merge request crafty-controller/crafty-4!634
This commit is contained in:
commit
d04a5dbb82
@ -11,6 +11,7 @@
|
|||||||
- Fix select installs failing to start, returning missing python package `packaging` ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/629))
|
- Fix select installs failing to start, returning missing python package `packaging` ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/629))
|
||||||
- Fix public status page not updating #255 ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/615))
|
- Fix public status page not updating #255 ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/615))
|
||||||
- Fix service worker vulrn and CQ raised by SonarQ ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/631))
|
- Fix service worker vulrn and CQ raised by SonarQ ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/631))
|
||||||
|
- Fix Backup Restore/Schedules, Backup button function on `remote-comms2` ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/634))
|
||||||
### Refactor
|
### Refactor
|
||||||
- Consolidate remaining frontend functions into API V2, and remove ajax internal API ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/585))
|
- Consolidate remaining frontend functions into API V2, and remove ajax internal API ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/585))
|
||||||
- Replace bleach with nh3 ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/628))
|
- Replace bleach with nh3 ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/628))
|
||||||
|
@ -594,6 +594,66 @@ class Controller:
|
|||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def restore_java_zip_server(
|
||||||
|
self,
|
||||||
|
server_name: str,
|
||||||
|
zip_path: str,
|
||||||
|
server_jar: str,
|
||||||
|
min_mem: int,
|
||||||
|
max_mem: int,
|
||||||
|
port: int,
|
||||||
|
user_id: int,
|
||||||
|
):
|
||||||
|
server_id = Helpers.create_uuid()
|
||||||
|
new_server_dir = os.path.join(self.helper.servers_dir, server_id)
|
||||||
|
backup_path = os.path.join(self.helper.backup_path, server_id)
|
||||||
|
if Helpers.is_os_windows():
|
||||||
|
new_server_dir = Helpers.wtol_path(new_server_dir)
|
||||||
|
backup_path = Helpers.wtol_path(backup_path)
|
||||||
|
new_server_dir.replace(" ", "^ ")
|
||||||
|
backup_path.replace(" ", "^ ")
|
||||||
|
|
||||||
|
temp_dir = Helpers.get_os_understandable_path(zip_path)
|
||||||
|
Helpers.ensure_dir_exists(new_server_dir)
|
||||||
|
Helpers.ensure_dir_exists(backup_path)
|
||||||
|
|
||||||
|
full_jar_path = os.path.join(new_server_dir, server_jar)
|
||||||
|
|
||||||
|
if Helpers.is_os_windows():
|
||||||
|
server_command = (
|
||||||
|
f"java -Xms{Helpers.float_to_string(min_mem)}M "
|
||||||
|
f"-Xmx{Helpers.float_to_string(max_mem)}M "
|
||||||
|
f'-jar "{full_jar_path}" nogui'
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
server_command = (
|
||||||
|
f"java -Xms{Helpers.float_to_string(min_mem)}M "
|
||||||
|
f"-Xmx{Helpers.float_to_string(max_mem)}M "
|
||||||
|
f"-jar {full_jar_path} nogui"
|
||||||
|
)
|
||||||
|
logger.debug("command: " + server_command)
|
||||||
|
server_log_file = "./logs/latest.log"
|
||||||
|
server_stop = "stop"
|
||||||
|
|
||||||
|
new_id = self.register_server(
|
||||||
|
server_name,
|
||||||
|
server_id,
|
||||||
|
new_server_dir,
|
||||||
|
backup_path,
|
||||||
|
server_command,
|
||||||
|
server_jar,
|
||||||
|
server_log_file,
|
||||||
|
server_stop,
|
||||||
|
port,
|
||||||
|
user_id,
|
||||||
|
server_type="minecraft-java",
|
||||||
|
)
|
||||||
|
ServersController.set_import(new_id)
|
||||||
|
self.import_helper.import_java_zip_server(
|
||||||
|
temp_dir, new_server_dir, port, new_id
|
||||||
|
)
|
||||||
|
return new_id
|
||||||
|
|
||||||
# **********************************************************************************
|
# **********************************************************************************
|
||||||
# BEDROCK IMPORTS
|
# BEDROCK IMPORTS
|
||||||
# **********************************************************************************
|
# **********************************************************************************
|
||||||
@ -691,7 +751,7 @@ class Controller:
|
|||||||
self.import_helper.download_bedrock_server(new_server_dir, new_id)
|
self.import_helper.download_bedrock_server(new_server_dir, new_id)
|
||||||
return new_id
|
return new_id
|
||||||
|
|
||||||
def import_bedrock_zip_server(
|
def restore_bedrock_zip_server(
|
||||||
self,
|
self,
|
||||||
server_name: str,
|
server_name: str,
|
||||||
zip_path: str,
|
zip_path: str,
|
||||||
@ -836,6 +896,7 @@ class Controller:
|
|||||||
|
|
||||||
srv_obj = server["server_obj"]
|
srv_obj = server["server_obj"]
|
||||||
srv_obj.server_scheduler.shutdown()
|
srv_obj.server_scheduler.shutdown()
|
||||||
|
srv_obj.dir_scheduler.shutdown()
|
||||||
running = srv_obj.check_running()
|
running = srv_obj.check_running()
|
||||||
|
|
||||||
if running:
|
if running:
|
||||||
|
@ -1047,13 +1047,6 @@ class ServerInstance:
|
|||||||
logger.info(f"Backup Thread started for server {self.settings['server_name']}.")
|
logger.info(f"Backup Thread started for server {self.settings['server_name']}.")
|
||||||
|
|
||||||
def a_backup_server(self):
|
def a_backup_server(self):
|
||||||
if len(WebSocketManager().clients) > 0:
|
|
||||||
WebSocketManager().broadcast_page_params(
|
|
||||||
"/panel/server_detail",
|
|
||||||
{"id": str(self.server_id)},
|
|
||||||
"backup_reload",
|
|
||||||
{"percent": 0, "total_files": 0},
|
|
||||||
)
|
|
||||||
was_server_running = None
|
was_server_running = None
|
||||||
logger.info(f"Starting server {self.name} (ID {self.server_id}) backup")
|
logger.info(f"Starting server {self.name} (ID {self.server_id}) backup")
|
||||||
server_users = PermissionsServers.get_server_user_list(self.server_id)
|
server_users = PermissionsServers.get_server_user_list(self.server_id)
|
||||||
@ -1566,7 +1559,6 @@ class ServerInstance:
|
|||||||
|
|
||||||
# process stats
|
# process stats
|
||||||
p_stats = Stats._try_get_process_stats(self.process, self.check_running())
|
p_stats = Stats._try_get_process_stats(self.process, self.check_running())
|
||||||
|
|
||||||
internal_ip = server["server_ip"]
|
internal_ip = server["server_ip"]
|
||||||
server_port = server["server_port"]
|
server_port = server["server_port"]
|
||||||
server_name = server.get("server_name", f"ID#{server_id}")
|
server_name = server.get("server_name", f"ID#{server_id}")
|
||||||
|
@ -102,7 +102,7 @@ class TasksManager:
|
|||||||
)
|
)
|
||||||
except:
|
except:
|
||||||
logger.error(
|
logger.error(
|
||||||
"Server value requested does not exist! "
|
f"Server value {cmd['server_id']} requested does not exist! "
|
||||||
"Purging item from waiting commands."
|
"Purging item from waiting commands."
|
||||||
)
|
)
|
||||||
continue
|
continue
|
||||||
|
@ -121,11 +121,11 @@ class ApiServersServerBackupsBackupIndexHandler(BaseApiHandler):
|
|||||||
server_data = self.controller.servers.get_server_data_by_id(server_id)
|
server_data = self.controller.servers.get_server_data_by_id(server_id)
|
||||||
zip_name = data["filename"]
|
zip_name = data["filename"]
|
||||||
# import the server again based on zipfile
|
# import the server again based on zipfile
|
||||||
if server_data["type"] == "minecraft-java":
|
backup_path = svr_obj.backup_path
|
||||||
backup_path = svr_obj.backup_path
|
if Helpers.validate_traversal(backup_path, zip_name):
|
||||||
if Helpers.validate_traversal(backup_path, zip_name):
|
temp_dir = Helpers.unzip_backup_archive(backup_path, zip_name)
|
||||||
temp_dir = Helpers.unzip_backup_archive(backup_path, zip_name)
|
if server_data["type"] == "minecraft-java":
|
||||||
new_server = self.controller.import_zip_server(
|
new_server = self.controller.restore_java_zip_server(
|
||||||
svr_obj.server_name,
|
svr_obj.server_name,
|
||||||
temp_dir,
|
temp_dir,
|
||||||
server_data["executable"],
|
server_data["executable"],
|
||||||
@ -134,71 +134,78 @@ class ApiServersServerBackupsBackupIndexHandler(BaseApiHandler):
|
|||||||
server_data["server_port"],
|
server_data["server_port"],
|
||||||
server_data["created_by"],
|
server_data["created_by"],
|
||||||
)
|
)
|
||||||
new_server_id = new_server
|
elif server_data["type"] == "minecraft-bedrock":
|
||||||
new_server = self.controller.servers.get_server_data(new_server)
|
new_server = self.controller.restore_bedrock_zip_server(
|
||||||
self.controller.rename_backup_dir(
|
svr_obj.server_name,
|
||||||
server_id, new_server_id, new_server["server_uuid"]
|
temp_dir,
|
||||||
|
server_data["executable"],
|
||||||
|
server_data["server_port"],
|
||||||
|
server_data["created_by"],
|
||||||
)
|
)
|
||||||
# preserve current schedules
|
new_server_id = new_server
|
||||||
for schedule in self.controller.management.get_schedules_by_server(
|
new_server = self.controller.servers.get_server_data(new_server)
|
||||||
server_id
|
self.controller.rename_backup_dir(
|
||||||
):
|
server_id, new_server_id, new_server["server_uuid"]
|
||||||
self.tasks_manager.update_job(
|
)
|
||||||
schedule.schedule_id, {"server_id": new_server_id}
|
# preserve current schedules
|
||||||
)
|
for schedule in self.controller.management.get_schedules_by_server(
|
||||||
# preserve execution command
|
server_id
|
||||||
new_server_obj = self.controller.servers.get_server_obj(
|
):
|
||||||
new_server_id
|
job_data = self.controller.management.get_scheduled_task(
|
||||||
|
schedule.schedule_id
|
||||||
)
|
)
|
||||||
new_server_obj.execution_command = server_data["execution_command"]
|
job_data["server_id"] = new_server_id
|
||||||
# reset executable path
|
del job_data["schedule_id"]
|
||||||
if svr_obj.path in svr_obj.executable:
|
self.tasks_manager.update_job(schedule.schedule_id, job_data)
|
||||||
new_server_obj.executable = str(svr_obj.executable).replace(
|
# preserve execution command
|
||||||
svr_obj.path, new_server_obj.path
|
new_server_obj = self.controller.servers.get_server_obj(new_server_id)
|
||||||
)
|
new_server_obj.execution_command = server_data["execution_command"]
|
||||||
# reset run command path
|
# reset executable path
|
||||||
if svr_obj.path in svr_obj.execution_command:
|
if svr_obj.path in svr_obj.executable:
|
||||||
new_server_obj.execution_command = str(
|
new_server_obj.executable = str(svr_obj.executable).replace(
|
||||||
svr_obj.execution_command
|
svr_obj.path, new_server_obj.path
|
||||||
).replace(svr_obj.path, new_server_obj.path)
|
)
|
||||||
# reset log path
|
# reset run command path
|
||||||
if svr_obj.path in svr_obj.log_path:
|
if svr_obj.path in svr_obj.execution_command:
|
||||||
new_server_obj.log_path = str(svr_obj.log_path).replace(
|
new_server_obj.execution_command = str(
|
||||||
svr_obj.path, new_server_obj.path
|
svr_obj.execution_command
|
||||||
)
|
).replace(svr_obj.path, new_server_obj.path)
|
||||||
self.controller.servers.update_server(new_server_obj)
|
# reset log path
|
||||||
|
if svr_obj.path in svr_obj.log_path:
|
||||||
|
new_server_obj.log_path = str(svr_obj.log_path).replace(
|
||||||
|
svr_obj.path, new_server_obj.path
|
||||||
|
)
|
||||||
|
self.controller.servers.update_server(new_server_obj)
|
||||||
|
|
||||||
# preserve backup config
|
# preserve backup config
|
||||||
backup_config = self.controller.management.get_backup_config(
|
backup_config = self.controller.management.get_backup_config(server_id)
|
||||||
server_id
|
excluded_dirs = []
|
||||||
)
|
server_obj = self.controller.servers.get_server_obj(server_id)
|
||||||
excluded_dirs = []
|
loop_backup_path = self.helper.wtol_path(server_obj.path)
|
||||||
server_obj = self.controller.servers.get_server_obj(server_id)
|
for item in self.controller.management.get_excluded_backup_dirs(
|
||||||
loop_backup_path = self.helper.wtol_path(server_obj.path)
|
server_id
|
||||||
for item in self.controller.management.get_excluded_backup_dirs(
|
):
|
||||||
server_id
|
item_path = self.helper.wtol_path(item)
|
||||||
):
|
bu_path = os.path.relpath(item_path, loop_backup_path)
|
||||||
item_path = self.helper.wtol_path(item)
|
bu_path = os.path.join(new_server_obj.path, bu_path)
|
||||||
bu_path = os.path.relpath(item_path, loop_backup_path)
|
excluded_dirs.append(bu_path)
|
||||||
bu_path = os.path.join(new_server_obj.path, bu_path)
|
self.controller.management.set_backup_config(
|
||||||
excluded_dirs.append(bu_path)
|
new_server_id,
|
||||||
self.controller.management.set_backup_config(
|
new_server_obj.backup_path,
|
||||||
new_server_id,
|
backup_config["max_backups"],
|
||||||
new_server_obj.backup_path,
|
excluded_dirs,
|
||||||
backup_config["max_backups"],
|
backup_config["compress"],
|
||||||
excluded_dirs,
|
backup_config["shutdown"],
|
||||||
backup_config["compress"],
|
)
|
||||||
backup_config["shutdown"],
|
# remove old server's tasks
|
||||||
)
|
try:
|
||||||
# remove old server's tasks
|
self.tasks_manager.remove_all_server_tasks(server_id)
|
||||||
try:
|
except JobLookupError as e:
|
||||||
self.tasks_manager.remove_all_server_tasks(server_id)
|
logger.info("No active tasks found for server: {e}")
|
||||||
except JobLookupError as e:
|
self.controller.remove_server(server_id, True)
|
||||||
logger.info("No active tasks found for server: {e}")
|
except Exception as e:
|
||||||
self.controller.remove_server(server_id, True)
|
|
||||||
except Exception:
|
|
||||||
return self.finish_json(
|
return self.finish_json(
|
||||||
400, {"status": "error", "error": "NO BACKUP FOUND"}
|
400, {"status": "error", "error": f"NO BACKUP FOUND {e}"}
|
||||||
)
|
)
|
||||||
self.controller.management.add_to_audit_log(
|
self.controller.management.add_to_audit_log(
|
||||||
auth_data[4]["user_id"],
|
auth_data[4]["user_id"],
|
||||||
|
@ -44,25 +44,25 @@
|
|||||||
<div class="col-md-6 col-sm-12">
|
<div class="col-md-6 col-sm-12">
|
||||||
<br>
|
<br>
|
||||||
<br>
|
<br>
|
||||||
<form id="backup-form" class="forms-sample">
|
{% if data['backing_up'] %}
|
||||||
{% if data['backing_up'] %}
|
<div class="progress" style="height: 15px;">
|
||||||
<div class="progress" style="height: 15px;">
|
<div class="progress-bar progress-bar-striped progress-bar-animated" id="backup_progress_bar"
|
||||||
<div class="progress-bar progress-bar-striped progress-bar-animated" id="backup_progress_bar"
|
role="progressbar" style="width:{{data['backup_stats']['percent']}}%;"
|
||||||
role="progressbar" style="width:{{data['backup_stats']['percent']}}%;"
|
aria-valuenow="{{data['backup_stats']['percent']}}" aria-valuemin="0" aria-valuemax="100">{{
|
||||||
aria-valuenow="{{data['backup_stats']['percent']}}" aria-valuemin="0" aria-valuemax="100">{{
|
data['backup_stats']['percent'] }}%</div>
|
||||||
data['backup_stats']['percent'] }}%</div>
|
</div>
|
||||||
</div>
|
<p>Backing up <i class="fas fa-spin fa-spinner"></i> <span
|
||||||
<p>Backing up <i class="fas fa-spin fa-spinner"></i> <span
|
id="total_files">{{data['server_stats']['world_size']}}</span></p>
|
||||||
id="total_files">{{data['server_stats']['world_size']}}</span></p>
|
{% end %}
|
||||||
{% end %}
|
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
{% if not data['backing_up'] %}
|
{% if not data['backing_up'] %}
|
||||||
<div id="backup_button" class="form-group">
|
<div id="backup_button" class="form-group">
|
||||||
<button class="btn btn-primary" id="backup_now_button">{{ translate('serverBackups', 'backupNow',
|
<button class="btn btn-primary" id="backup_now_button">{{ translate('serverBackups', 'backupNow',
|
||||||
data['lang']) }}</button>
|
data['lang']) }}</button>
|
||||||
</div>
|
</div>
|
||||||
{% end %}
|
{% end %}
|
||||||
|
<form id="backup-form" class="forms-sample">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
{% if data['super_user'] %}
|
{% if data['super_user'] %}
|
||||||
<label for="server_name">{{ translate('serverBackups', 'storageLocation', data['lang']) }} <small
|
<label for="server_name">{{ translate('serverBackups', 'storageLocation', data['lang']) }} <small
|
||||||
@ -309,11 +309,6 @@
|
|||||||
|
|
||||||
async function backup_started() {
|
async function backup_started() {
|
||||||
const token = getCookie("_xsrf")
|
const token = getCookie("_xsrf")
|
||||||
document.getElementById('backup_button').style.visibility = 'hidden';
|
|
||||||
var dialog = bootbox.dialog({
|
|
||||||
message: "{{ translate('serverBackups', 'backupTask', data['lang']) }}",
|
|
||||||
closeButton: false
|
|
||||||
});
|
|
||||||
let res = await fetch(`/api/v2/servers/${server_id}/action/backup_server`, {
|
let res = await fetch(`/api/v2/servers/${server_id}/action/backup_server`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
@ -323,8 +318,14 @@
|
|||||||
let responseData = await res.json();
|
let responseData = await res.json();
|
||||||
if (responseData.status === "ok") {
|
if (responseData.status === "ok") {
|
||||||
console.log(responseData);
|
console.log(responseData);
|
||||||
process_tree_response(responseData);
|
$("#backup_button").html(`<div class="progress" style="height: 15px;">
|
||||||
|
<div class="progress-bar progress-bar-striped progress-bar-animated" id="backup_progress_bar"
|
||||||
|
role="progressbar" style="width:{{data['backup_stats']['percent']}}%;"
|
||||||
|
aria-valuenow="{{data['backup_stats']['percent']}}" aria-valuemin="0" aria-valuemax="100">{{
|
||||||
|
data['backup_stats']['percent'] }}%</div>
|
||||||
|
</div>
|
||||||
|
<p>Backing up <i class="fas fa-spin fa-spinner"></i> <span
|
||||||
|
id="total_files">{{data['server_stats']['world_size']}}</span></p>`);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
bootbox.alert({
|
bootbox.alert({
|
||||||
|
Loading…
Reference in New Issue
Block a user