Merge branch 'dev' into feature/bedrock-creation

This commit is contained in:
Zedifus 2022-09-04 21:12:47 +01:00
commit 7f95f7085d
9 changed files with 145 additions and 78 deletions

View File

@ -30,6 +30,11 @@ win-dev-build:
--collect-all tzdata --collect-all tzdata
--collect-all pytz --collect-all pytz
--collect-all six --collect-all six
- |
echo "Retrieving 'latest' updater from crafty-controller/crafty-4-windows-updater"
$src = 'https://gitlab.com/crafty-controller/crafty-4-windows-updater/-/jobs/artifacts/dev/raw/crafty_updater.exe?job=win-dev-build'
$dest = 'crafty_updater.exe'
Invoke-WebRequest -Uri $src -OutFile $dest
# Download latest: # Download latest:
# | https://gitlab.com/crafty-controller/crafty-4/-/jobs/artifacts/dev/download?job=win-dev-build # | https://gitlab.com/crafty-controller/crafty-4/-/jobs/artifacts/dev/download?job=win-dev-build
@ -38,6 +43,7 @@ win-dev-build:
paths: paths:
- app\ - app\
- .\crafty.exe - .\crafty.exe
- .\crafty_updater.exe
exclude: exclude:
- app\classes\**\* - app\classes\**\*
@ -72,6 +78,11 @@ win-prod-build:
--collect-all tzdata --collect-all tzdata
--collect-all pytz --collect-all pytz
--collect-all six --collect-all six
- |
echo "Retrieving 'latest' updater from crafty-controller/crafty-4-windows-updater"
$src = 'https://gitlab.com/crafty-controller/crafty-4-windows-updater/-/jobs/artifacts/master/raw/crafty_updater.exe?job=win-prod-build'
$dest = 'crafty_updater.exe'
Invoke-WebRequest -Uri $src -OutFile $dest
after_script: after_script:
- Add-Content -Path job.env -Value "JOB_ID=$CI_JOB_ID" - Add-Content -Path job.env -Value "JOB_ID=$CI_JOB_ID"
@ -82,6 +93,7 @@ win-prod-build:
paths: paths:
- app\ - app\
- .\crafty.exe - .\crafty.exe
- .\crafty_updater.exe
expire_in: never expire_in: never
exclude: exclude:
- app\classes\**\* - app\classes\**\*

View File

@ -1,9 +1,11 @@
# Changelog # Changelog
## --- [4.0.12] - 2022/TBD ## --- [4.0.12] - 2022/09/04
### New features ### New features
TBD - Win Portable Updater will now be included in Windows Package ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/446))
### Bug fixes ### Bug fixes
TBD - Fix performance issues on server metrics panels (Temporarily setting to 24hr query) ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/440))
- Fix no id on import3 servers ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/442))
- Fix functionality of bedrock update ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/441))
### Tweaks ### Tweaks
TBD TBD
### Lang ### Lang

View File

@ -106,11 +106,9 @@ class ServersController(metaclass=Singleton):
return ret return ret
def get_history_stats(self, server_id): def get_history_stats(self, server_id):
max_age = self.helper.get_setting("history_max_age")
now = datetime.datetime.now() now = datetime.datetime.now()
minimum_to_exist = now - datetime.timedelta(days=max_age)
srv = ServersController().get_server_instance_by_id(server_id) srv = ServersController().get_server_instance_by_id(server_id)
return srv.stats_helper.get_history_stats(server_id, minimum_to_exist) return srv.stats_helper.get_history_stats(server_id)
@staticmethod @staticmethod
def update_unloaded_server(server_obj): def update_unloaded_server(server_obj):

View File

@ -1,6 +1,7 @@
import os import os
import logging import logging
import datetime import datetime
from datetime import timedelta
from app.classes.models.servers import Servers, HelperServers from app.classes.models.servers import Servers, HelperServers
from app.classes.shared.helpers import Helpers from app.classes.shared.helpers import Helpers
@ -137,7 +138,8 @@ class HelperServerStats:
) )
return server_data return server_data
def get_history_stats(self, server_id, max_age): def get_history_stats(self, server_id):
max_age = datetime.datetime.now() - timedelta(days=1)
return ( return (
ServerStats.select() ServerStats.select()
.where(ServerStats.created > max_age) .where(ServerStats.created > max_age)

View File

@ -74,6 +74,7 @@ class Import3:
min_mem=(int(server["memory_min"]) / 1000), min_mem=(int(server["memory_min"]) / 1000),
max_mem=(int(server["memory_max"]) / 1000), max_mem=(int(server["memory_max"]) / 1000),
port=server["server_port"], port=server["server_port"],
user_id=HelperUsers.get_user_id_by_name("system"),
) )
Console.info( Console.info(
f"Imported server {server['server_name']}[{server['id']}] " f"Imported server {server['server_name']}[{server['id']}] "
@ -91,6 +92,7 @@ class Import3:
min_mem=(int(json_data["memory_min"]) / 1000), min_mem=(int(json_data["memory_min"]) / 1000),
max_mem=(int(json_data["memory_max"]) / 1000), max_mem=(int(json_data["memory_max"]) / 1000),
port=json_data["server_port"], port=json_data["server_port"],
user_id=HelperUsers.get_user_id_by_name("system"),
) )
Console.info( Console.info(
f"Imported server {json_data['server_name']}[{json_data['id']}] " f"Imported server {json_data['server_name']}[{json_data['id']}] "

View File

@ -1108,6 +1108,22 @@ class ServerInstance:
except FileNotFoundError: except FileNotFoundError:
logger.error("Could not create backup of jarfile. File not found.") logger.error("Could not create backup of jarfile. File not found.")
# wait for backup
while self.is_backingup:
time.sleep(10)
# check if backup was successful
if self.last_backup_failed:
server_users = PermissionsServers.get_server_user_list(self.server_id)
for user in server_users:
self.helper.websocket_helper.broadcast_user(
user,
"notification",
"Backup failed for " + self.name + ". canceling update.",
)
return False
# lets download the files
if HelperServers.get_server_type_by_id(self.server_id) != "minecraft-bedrock": if HelperServers.get_server_type_by_id(self.server_id) != "minecraft-bedrock":
# boolean returns true for false for success # boolean returns true for false for success
downloaded = Helpers.download_file( downloaded = Helpers.download_file(
@ -1115,55 +1131,39 @@ class ServerInstance:
) )
else: else:
# downloads zip from remote url # downloads zip from remote url
bedrock_url = Helpers.get_latest_bedrock_url() try:
if bedrock_url.lower().startswith("https"): bedrock_url = Helpers.get_latest_bedrock_url()
urllib.request.urlretrieve( if bedrock_url.lower().startswith("https"):
bedrock_url, urllib.request.urlretrieve(
os.path.join(self.settings["path"], "bedrock_server.zip"), bedrock_url,
os.path.join(self.settings["path"], "bedrock_server.zip"),
)
unzip_path = os.path.join(self.settings["path"], "bedrock_server.zip")
unzip_path = self.helper.wtol_path(unzip_path)
# unzips archive that was downloaded.
FileHelpers.unzip_file(unzip_path)
# adjusts permissions for execution if os is not windows
if not self.helper.is_os_windows():
os.chmod(
os.path.join(self.settings["path"], "bedrock_server"), 0o0744
)
# we'll delete the zip we downloaded now
os.remove(os.path.join(self.settings["path"], "bedrock_server.zip"))
downloaded = True
except Exception as e:
logger.critical(
f"Failed to download bedrock executable for update \n{e}"
) )
unzip_path = os.path.join(self.settings["path"], "bedrock_server.zip") if downloaded:
unzip_path = self.helper.wtol_path(unzip_path) logger.info("Executable updated successfully. Starting Server")
# unzips archive that was downloaded.
FileHelpers.unzip_file(unzip_path)
# adjusts permissions for execution if os is not windows
if not self.helper.is_os_windows():
os.chmod(os.path.join(self.settings["path"], "bedrock_server"), 0o0744)
# we'll delete the zip we downloaded now self.stats_helper.set_update(False)
os.remove(os.path.join(self.settings["path"], "bedrock_server.zip")) if len(self.helper.websocket_helper.clients) > 0:
downloaded = True # There are clients
self.check_update()
while self.stats_helper.get_server_stats()["updating"]:
if downloaded and not self.is_backingup:
logger.info("Executable updated successfully. Starting Server")
self.stats_helper.set_update(False)
if len(self.helper.websocket_helper.clients) > 0:
# There are clients
self.check_update()
server_users = PermissionsServers.get_server_user_list(
self.server_id
)
for user in server_users:
self.helper.websocket_helper.broadcast_user(
user,
"notification",
"Executable update finished for " + self.name,
)
time.sleep(3)
self.helper.websocket_helper.broadcast_page(
"/panel/server_detail",
"update_button_status",
{
"isUpdating": self.check_update(),
"server_id": self.server_id,
"wasRunning": was_started,
},
)
self.helper.websocket_helper.broadcast_page(
"/panel/dashboard", "send_start_reload", {}
)
server_users = PermissionsServers.get_server_user_list(self.server_id) server_users = PermissionsServers.get_server_user_list(self.server_id)
for user in server_users: for user in server_users:
self.helper.websocket_helper.broadcast_user( self.helper.websocket_helper.broadcast_user(
@ -1171,29 +1171,52 @@ class ServerInstance:
"notification", "notification",
"Executable update finished for " + self.name, "Executable update finished for " + self.name,
) )
# sleep so first notif can completely run
self.management_helper.add_to_audit_log_raw( time.sleep(3)
"Alert", self.helper.websocket_helper.broadcast_page(
"-1", "/panel/server_detail",
self.server_id, "update_button_status",
"Executable update finished for " + self.name, {
self.settings["server_ip"], "isUpdating": self.check_update(),
"server_id": self.server_id,
"wasRunning": was_started,
},
) )
if was_started: self.helper.websocket_helper.broadcast_page(
self.start_server() "/panel/dashboard", "send_start_reload", {}
elif not downloaded and not self.is_backingup: )
time.sleep(5) self.helper.websocket_helper.broadcast_page(
server_users = PermissionsServers.get_server_user_list(self.server_id) "/panel/server_detail", "remove_spinner", {}
for user in server_users: )
self.helper.websocket_helper.broadcast_user( server_users = PermissionsServers.get_server_user_list(self.server_id)
user, for user in server_users:
"notification", self.helper.websocket_helper.broadcast_user(
"Executable update failed for " user,
+ self.name "notification",
+ ". Check log file for details.", "Executable update finished for " + self.name,
) )
logger.error("Executable download failed.")
self.stats_helper.set_update(False) self.management_helper.add_to_audit_log_raw(
"Alert",
"-1",
self.server_id,
"Executable update finished for " + self.name,
self.settings["server_ip"],
)
if was_started:
self.start_server()
else:
server_users = PermissionsServers.get_server_user_list(self.server_id)
for user in server_users:
self.helper.websocket_helper.broadcast_user(
user,
"notification",
"Executable update failed for "
+ self.name
+ ". Check log file for details.",
)
logger.error("Executable download failed.")
self.stats_helper.set_update(False)
# ********************************************************************************** # **********************************************************************************
# Minecraft Servers Statistics # Minecraft Servers Statistics

View File

@ -186,7 +186,8 @@
{% elif server['stats']['updating']%} {% elif server['stats']['updating']%}
<!-- WHAT HAPPENED HERE --> <!-- WHAT HAPPENED HERE -->
<a data-id="{{server['server_data']['server_id']}}" class="">{{ translate('serverTerm', 'updating', <a data-id="{{server['server_data']['server_id']}}" class=""><i
class="fa fa-spinner fa-spin"></i>&nbsp;{{ translate('serverTerm', 'updating',
data['lang']) }}</i></a> data['lang']) }}</i></a>
{% elif server['stats']['waiting_start']%} {% elif server['stats']['waiting_start']%}
<!-- WHAT HAPPENED HERE --> <!-- WHAT HAPPENED HERE -->

View File

@ -253,14 +253,31 @@
<button onclick="send_command(serverId, 'update_executable');" id="update_executable" <button onclick="send_command(serverId, 'update_executable');" id="update_executable"
style="max-width: 7rem;" class="btn btn-warning m-1 flex-grow-1 disabled">{{ translate('serverConfig', style="max-width: 7rem;" class="btn btn-warning m-1 flex-grow-1 disabled">{{ translate('serverConfig',
'update', data['lang']) }}</button> 'update', data['lang']) }}</button>
{% if data['server_stats']['updating'] %}
<button onclick="send_command(serverId, 'update_executable');" id="update_executable"
style="max-width: 7rem;" class="btn btn-warning m-1 flex-grow-1 disabled">{{ translate('serverConfig',
'update', data['lang']) }}&nbsp;<i id="update-spinner" class="fa fa-spinner fa-spin"></i></button>
{% else %}
<button onclick="send_command(serverId, 'update_executable');" id="update_executable"
style="max-width: 7rem;" class="btn btn-warning m-1 flex-grow-1 disabled">{{ translate('serverConfig',
'update', data['lang']) }}&nbsp;<i style="visibility: hidden;" id="update-spinner"
class="fa fa-spinner fa-spin"></i></button>
{% end %}
<a class="btn btn-sm btn-danger disabled">{{ translate('serverConfig', 'deleteServer', data['lang']) <a class="btn btn-sm btn-danger disabled">{{ translate('serverConfig', 'deleteServer', data['lang'])
}}</a><br /> }}</a><br />
<small>{{ translate('serverConfig', 'stopBeforeDeleting', data['lang']) }}</small> <small>{{ translate('serverConfig', 'stopBeforeDeleting', data['lang']) }}</small>
{% else %} {% else %}
{% if not data['failed'] %} {% if not data['failed'] %}
{% if data['server_stats']['updating'] %}
<button onclick="send_command(serverId, 'update_executable');" id="update_executable" <button onclick="send_command(serverId, 'update_executable');" id="update_executable"
style="max-width: 7rem;" class="btn btn-warning m-1 flex-grow-1">{{ translate('serverConfig', style="max-width: 7rem;" class="btn btn-warning m-1 flex-grow-1">{{ translate('serverConfig',
'update', data['lang']) }}</button> 'update', data['lang']) }}&nbsp;<i id="update-spinner" class="fa fa-spinner fa-spin"></i></button>
{% else %}
<button onclick="send_command(serverId, 'update_executable');" id="update_executable"
style="max-width: 7rem;" class="btn btn-warning m-1 flex-grow-1">{{ translate('serverConfig',
'update', data['lang']) }}&nbsp;<i style="visibility: hidden;" id="update-spinner"
class="fa fa-spinner fa-spin"></i></button>
{% end %}
{% end %} {% end %}
{% if not data['failed'] %} {% if not data['failed'] %}
<button onclick="deleteConfirm()" class="btn btn-sm btn-danger">{{ translate('serverConfig', <button onclick="deleteConfirm()" class="btn btn-sm btn-danger">{{ translate('serverConfig',
@ -356,6 +373,9 @@
function send_command(serverId, command) { function send_command(serverId, command) {
//<!-- this getCookie function is in base.html--> //<!-- this getCookie function is in base.html-->
var token = getCookie("_xsrf"); var token = getCookie("_xsrf");
if (command == "update_executable") {
document.getElementById("update-spinner").style.visibility = "visible";
}
$.ajax({ $.ajax({
type: "POST", type: "POST",
@ -508,6 +528,12 @@
}); });
} }
$(document).ready(function () {
webSocket.on('remove_spinner', function () {
document.getElementById("update-spinner").style.visibility = "hidden";
});
});
</script> </script>
{% end %} {% end %}

View File

@ -55,7 +55,8 @@
{% if data['permissions']['Commands'] in data['user_permissions'] %} {% if data['permissions']['Commands'] in data['user_permissions'] %}
{% if data['server_stats']['updating']%} {% if data['server_stats']['updating']%}
<div id="update_control_buttons" class="mt-4 flex-wrap d-flex justify-content-between justify-content-md-center align-items-center px-5 px-md-0" style="visibility: visible"> <div id="update_control_buttons" class="mt-4 flex-wrap d-flex justify-content-between justify-content-md-center align-items-center px-5 px-md-0" style="visibility: visible">
<button onclick="" id="start-btn" style="max-width: 7rem;" class="btn btn-warning m-1 flex-grow-1 disabled">{{ translate('serverTerm', 'updating', data['lang']) }}</button> <button onclick="" id="start-btn" style="max-width: 7rem;" class="btn btn-warning m-1 flex-grow-1 disabled"><i
class="fa fa-spinner fa-spin"></i>&nbsp;{{ translate('serverTerm', 'updating', data['lang']) }}</button>
<button onclick="" id="restart-btn" style="max-width: 7rem;" class="btn btn-outline-primary m-1 flex-grow-1 disabled">{% raw translate('serverTerm', 'restart', data['lang']) %}</button> <button onclick="" id="restart-btn" style="max-width: 7rem;" class="btn btn-outline-primary m-1 flex-grow-1 disabled">{% raw translate('serverTerm', 'restart', data['lang']) %}</button>
<button onclick="" id="stop-btn" style="max-width: 7rem;" class="btn btn-danger m-1 flex-grow-1 disabled">{{ translate('serverTerm', 'stop', data['lang']) }}</button> <button onclick="" id="stop-btn" style="max-width: 7rem;" class="btn btn-danger m-1 flex-grow-1 disabled">{{ translate('serverTerm', 'stop', data['lang']) }}</button>
</div> </div>