diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a7b3e5b..68ff2c30 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,9 @@ # Changelog ## --- [4.0.9] - 2022/08/06 -### New features -TBD ### Bug fixes - Fix Schedules Traceback Bug ([Merge Request |](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/419) [Commit |](https://gitlab.com/crafty-controller/crafty-4/-/commit/f69d79b7023d6c26fccb5caeae9e47b40ebe5af2) [Commit](https://gitlab.com/crafty-controller/crafty-4/-/commit/ad318296dc93beb5533fcd13066440df9f9e799a)) +- Fix handling of missing servers ([Merge Request🎉](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/420)) ### Tweaks - credits-v2| Translator status ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/421)) - Use Names in Schedules ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/419)) diff --git a/app/classes/controllers/servers_controller.py b/app/classes/controllers/servers_controller.py index 0e5f3f5f..650a16b0 100644 --- a/app/classes/controllers/servers_controller.py +++ b/app/classes/controllers/servers_controller.py @@ -102,6 +102,11 @@ class ServersController(metaclass=Singleton): server_instance.update_server_instance() return ret + @staticmethod + def update_unloaded_server(server_obj): + ret = HelperServers.update_server(server_obj) + return ret + @staticmethod def set_download(server_id): srv = ServersController().get_server_instance_by_id(server_id) @@ -146,6 +151,7 @@ class ServersController(metaclass=Singleton): def init_all_servers(self): servers = self.get_all_defined_servers() + self.failed_servers = [] for server in servers: server_id = server.get("server_id") @@ -169,6 +175,8 @@ class ServersController(metaclass=Singleton): f"{server['server_name']} at path {server['path']}. " f"Skipping this server" ) + if server not in self.failed_servers: + self.failed_servers.append(server) continue temp_server_dict = { diff --git a/app/classes/shared/main_controller.py b/app/classes/shared/main_controller.py index 393aa475..bca24fe8 100644 --- a/app/classes/shared/main_controller.py +++ b/app/classes/shared/main_controller.py @@ -934,6 +934,14 @@ class Controller: counter += 1 + def remove_unloaded_server(self, server_id): + try: + HelpersManagement.delete_scheduled_task_by_server(server_id) + except DoesNotExist: + logger.info("No scheduled jobs exist. Continuing.") + # remove the server from the DB + self.servers.remove_server(server_id) + @staticmethod def clear_unexecuted_commands(): HelpersManagement.clear_unexecuted_commands() diff --git a/app/classes/web/ajax_handler.py b/app/classes/web/ajax_handler.py index 42dc4275..9aa41d28 100644 --- a/app/classes/web/ajax_handler.py +++ b/app/classes/web/ajax_handler.py @@ -573,9 +573,39 @@ class AjaxHandler(BaseHandler): self.get_remote_ip(), ) + for server in self.controller.servers.failed_servers: + if server["server_id"] == int(server_id): + return self.tasks_manager.remove_all_server_tasks(server_id) self.controller.remove_server(server_id, True) + elif page == "delete_unloaded_server": + if not permissions["Config"] in user_perms: + if not superuser: + self.redirect("/panel/error?error=Unauthorized access to Config") + return + server_id = self.get_argument("id", None) + logger.info( + f"Removing server and all associated files for server: " + f"{self.controller.servers.get_server_friendly_name(server_id)}" + ) + + server_data = self.controller.servers.get_server_data_by_id(server_id) + server_name = server_data["server_name"] + + self.controller.management.add_to_audit_log( + exec_user["user_id"], + f"Deleted server {server_id} named {server_name}", + server_id, + self.get_remote_ip(), + ) + + self.tasks_manager.remove_all_server_tasks(server_id) + for item in self.controller.servers.failed_servers[:]: + if item["server_id"] == int(server_id): + self.controller.servers.failed_servers.remove(item) + self.controller.remove_unloaded_server(server_id) + def check_server_id(self, server_id, page_name): if server_id is None: logger.warning( diff --git a/app/classes/web/panel_handler.py b/app/classes/web/panel_handler.py index 40d11904..2334c862 100644 --- a/app/classes/web/panel_handler.py +++ b/app/classes/web/panel_handler.py @@ -157,6 +157,10 @@ class PanelHandler(BaseHandler): if server_id is None: self.redirect("/panel/error?error=Invalid Server ID") return None + for server in self.controller.servers.failed_servers: + if int(server_id) == server["server_id"]: + self.failed_server = True + return server_id # Does this server exist? if not self.controller.servers.server_id_exists(server_id): self.redirect("/panel/error?error=Invalid Server ID") @@ -207,6 +211,7 @@ class PanelHandler(BaseHandler): @tornado.web.authenticated async def get(self, page): + self.failed_server = False error = self.get_argument("error", "WTF Error!") template = "panel/denied.html" @@ -287,6 +292,7 @@ class PanelHandler(BaseHandler): "update_available": self.helper.update_available, "serverTZ": tz, "version_data": self.helper.get_version_string(), + "failed_servers": self.controller.servers.failed_servers, "user_data": exec_user, "user_role": exec_user_role, "user_crafty_permissions": exec_user_crafty_permissions, @@ -503,9 +509,11 @@ class PanelHandler(BaseHandler): server_id = self.check_server_id() if server_id is None: return - - server_obj = self.controller.servers.get_server_instance_by_id(server_id) - page_data["backup_failed"] = server_obj.last_backup_status() + if not self.failed_server: + server_obj = self.controller.servers.get_server_instance_by_id( + server_id + ) + page_data["backup_failed"] = server_obj.last_backup_status() server_obj = None valid_subpages = [ @@ -517,18 +525,57 @@ class PanelHandler(BaseHandler): "admin_controls", "schedules", ] - - server = self.controller.servers.get_server_instance_by_id(server_id) + if not self.failed_server: + server = self.controller.servers.get_server_instance_by_id(server_id) # server_data isn't needed since the server_stats also pulls server data page_data["server_data"] = self.controller.servers.get_server_data_by_id( server_id ) - page_data["server_stats"] = self.controller.servers.get_server_stats_by_id( - server_id - ) - page_data["downloading"] = self.controller.servers.get_download_status( - server_id - ) + if not self.failed_server: + page_data[ + "server_stats" + ] = self.controller.servers.get_server_stats_by_id(server_id) + else: + server_temp_obj = self.controller.servers.get_server_data_by_id( + server_id + ) + page_data["server_stats"] = { + "server_id": { + "server_id": server_id, + "server_name": server_temp_obj["server_name"], + "server_uuid": server_temp_obj["server_uuid"], + "path": server_temp_obj["path"], + "log_path": server_temp_obj["log_path"], + "executable": server_temp_obj["executable"], + "execution_command": server_temp_obj["execution_command"], + "stop_command": server_temp_obj["stop_command"], + "executable_update_url": server_temp_obj[ + "executable_update_url" + ], + "auto_start_delay": server_temp_obj["auto_start_delay"], + "server_ip": server_temp_obj["server_ip"], + "server_port": server_temp_obj["server_port"], + "logs_delete_after": server_temp_obj["logs_delete_after"], + "auto_start": server_temp_obj["auto_start"], + "crash_detection": server_temp_obj["crash_detection"], + "show_status": server_temp_obj["show_status"], + }, + "running": False, + "crashed": False, + "server_type": "N/A", + "cpu": "N/A", + "mem": "N/A", + "int_ping_results": [], + "version": "N/A", + "desc": "N/A", + "started": "False", + } + if not self.failed_server: + page_data["downloading"] = self.controller.servers.get_download_status( + server_id + ) + else: + page_data["downloading"] = False page_data["server_id"] = server_id try: page_data["waiting_start"] = self.controller.servers.get_waiting_start( @@ -537,7 +584,10 @@ class PanelHandler(BaseHandler): except Exception as e: logger.error(f"Failed to get server waiting to start: {e}") page_data["waiting_start"] = False - page_data["get_players"] = server.get_server_players() + if not self.failed_server: + page_data["get_players"] = server.get_server_players() + else: + page_data["get_players"] = [] page_data["active_link"] = subpage page_data["permissions"] = { "Commands": EnumPermissionsServer.COMMANDS, @@ -554,12 +604,14 @@ class PanelHandler(BaseHandler): ] = self.controller.server_perms.get_user_id_permissions_list( exec_user["user_id"], server_id ) - page_data["server_stats"]["crashed"] = self.controller.servers.is_crashed( - server_id - ) - page_data["server_stats"][ - "server_type" - ] = self.controller.servers.get_server_type_by_id(server_id) + if not self.failed_server: + page_data["server_stats"][ + "crashed" + ] = self.controller.servers.is_crashed(server_id) + if not self.failed_server: + page_data["server_stats"][ + "server_type" + ] = self.controller.servers.get_server_type_by_id(server_id) if subpage not in valid_subpages: logger.debug("not a valid subpage") if not subpage: @@ -639,6 +691,7 @@ class PanelHandler(BaseHandler): return page_data["java_versions"] = Helpers.find_java_installs() server_obj: Servers = self.controller.servers.get_server_obj(server_id) + page_data["failed"] = self.failed_server page_java = [] page_data["java_versions"].append("java") for version in page_data["java_versions"]: @@ -1471,7 +1524,15 @@ class PanelHandler(BaseHandler): server_obj.auto_start = auto_start server_obj.crash_detection = crash_detection server_obj.logs_delete_after = logs_delete_after - self.controller.servers.update_server(server_obj) + failed = False + for servers in self.controller.servers.failed_servers: + if servers["server_id"] == int(server_id): + failed = True + if not failed: + self.controller.servers.update_server(server_obj) + else: + self.controller.servers.update_unloaded_server(server_obj) + self.controller.servers.init_all_servers() self.controller.servers.crash_detection(server_obj) self.controller.servers.refresh_server_settings(server_id) diff --git a/app/frontend/templates/panel/dashboard.html b/app/frontend/templates/panel/dashboard.html index 00aee7e1..ec5a21db 100644 --- a/app/frontend/templates/panel/dashboard.html +++ b/app/frontend/templates/panel/dashboard.html @@ -60,12 +60,12 @@
+ title="{% raw translate('dashboard', 'cpuCores', data['lang']) %}: {{ data.get('hosts_data').get('cpu_cores') }}
{% raw translate('dashboard', 'cpuCurFreq', data['lang']) %}: {{ data.get('hosts_data').get('cpu_cur_freq') }}
{% raw translate('dashboard', 'cpuMaxFreq', data['lang']) %}: {{ data.get('hosts_data').get('cpu_max_freq') }}">
{{ translate('dashboard', 'cpuUsage', data['lang']) }}: {{
data.get('hosts_data').get('cpu_usage') }}
+ title="{{ translate('dashboard', 'memUsage', data['lang']) }}: {{ data.get('hosts_data').get('mem_usage') }}"> {{ translate('dashboard', 'memUsage', data['lang']) }}: {{ data.get('hosts_data').get('mem_percent') }}%
@@ -116,8 +116,8 @@ {% if len(data['servers']) > 0 %} {% if data['user_data']['hints'] %} + data-content="{{ translate('dashboard', 'cannotSeeOnMobile2', data['lang']) }}" , + data-placement="top"> {% end %} {% end %}
+ title="{{server['stats']['cpu']}}">
+ aria-valuemin="0" aria-valuemax="100">
{{server['stats']['cpu']}}%
|
+ title="{{server['stats']['mem']}}">
+ aria-valuemin="0" aria-valuemax="100">
{{server['stats']['mem_percent']}}% -
@@ -263,7 +263,7 @@
{% if server['stats']['desc'] != 'False' %}
{{
+ style="overflow-wrap: break-word !important; max-width: 85px !important; overflow: scroll;">{{
server['stats']['desc'] }} {% end %} @@ -287,7 +287,20 @@ {% end %} |
+ data-players="{{ server['stats']['online']}}" data-max="{{ server['stats']['max'] }}">
+
+ {% end %}
+ {% for server in data['failed_servers'] %}
+ |||||
{{server['server_name']}} + | ++ | + | + | + | + | Unloaded |