Add backup shutdown feature

Add backup notif for failed backup
This commit is contained in:
amcmanu3 2022-06-20 17:16:56 -04:00
parent 3c5c16a5e7
commit 7670b91cc6
8 changed files with 76 additions and 3 deletions

View File

@ -136,9 +136,10 @@ class ManagementController:
max_backups: int = None, max_backups: int = None,
excluded_dirs: list = None, excluded_dirs: list = None,
compress: bool = False, compress: bool = False,
shutdown: bool = False
): ):
return self.management_helper.set_backup_config( return self.management_helper.set_backup_config(
server_id, backup_path, max_backups, excluded_dirs, compress server_id, backup_path, max_backups, excluded_dirs, compress, shutdown
) )
@staticmethod @staticmethod

View File

@ -128,6 +128,7 @@ class Backups(BaseModel):
max_backups = IntegerField() max_backups = IntegerField()
server_id = ForeignKeyField(Servers, backref="backups_server") server_id = ForeignKeyField(Servers, backref="backups_server")
compress = BooleanField(default=False) compress = BooleanField(default=False)
shutdown = BooleanField(default=False)
class Meta: class Meta:
table_name = "backups" table_name = "backups"
@ -351,6 +352,7 @@ class HelpersManagement:
"max_backups": row.max_backups, "max_backups": row.max_backups,
"server_id": row.server_id_id, "server_id": row.server_id_id,
"compress": row.compress, "compress": row.compress,
"shutdown": row.shutdown,
} }
except IndexError: except IndexError:
conf = { conf = {
@ -359,6 +361,7 @@ class HelpersManagement:
"max_backups": 0, "max_backups": 0,
"server_id": server_id, "server_id": server_id,
"compress": False, "compress": False,
"shutdown": False,
} }
return conf return conf
@ -369,6 +372,7 @@ class HelpersManagement:
max_backups: int = None, max_backups: int = None,
excluded_dirs: list = None, excluded_dirs: list = None,
compress: bool = False, compress: bool = False,
shutdown: bool = False,
): ):
logger.debug(f"Updating server {server_id} backup config with {locals()}") logger.debug(f"Updating server {server_id} backup config with {locals()}")
if Backups.select().where(Backups.server_id == server_id).exists(): if Backups.select().where(Backups.server_id == server_id).exists():
@ -380,6 +384,7 @@ class HelpersManagement:
"max_backups": 0, "max_backups": 0,
"server_id": server_id, "server_id": server_id,
"compress": False, "compress": False,
"shutdown": False,
} }
new_row = True new_row = True
if max_backups is not None: if max_backups is not None:
@ -388,6 +393,7 @@ class HelpersManagement:
dirs_to_exclude = ",".join(excluded_dirs) dirs_to_exclude = ",".join(excluded_dirs)
conf["excluded_dirs"] = dirs_to_exclude conf["excluded_dirs"] = dirs_to_exclude
conf["compress"] = compress conf["compress"] = compress
conf["shutdown"] = shutdown
if not new_row: if not new_row:
with self.database.atomic(): with self.database.atomic():
if backup_path is not None: if backup_path is not None:

View File

@ -127,6 +127,7 @@ class ServerInstance:
self.stats = stats self.stats = stats
self.server_object = HelperServers.get_server_obj(self.server_id) self.server_object = HelperServers.get_server_obj(self.server_id)
self.stats_helper = HelperServerStats(self.server_id) self.stats_helper = HelperServerStats(self.server_id)
self.last_backup_failed = False
try: try:
tz = get_localzone() tz = get_localzone()
except ZoneInfoNotFoundError: except ZoneInfoNotFoundError:
@ -847,6 +848,7 @@ class ServerInstance:
"backup_reload", "backup_reload",
{"percent": 0, "total_files": 0}, {"percent": 0, "total_files": 0},
) )
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)
for user in server_users: for user in server_users:
@ -859,6 +861,15 @@ class ServerInstance:
) )
time.sleep(3) time.sleep(3)
conf = HelpersManagement.get_backup_config(self.server_id) conf = HelpersManagement.get_backup_config(self.server_id)
if conf["shutdown"]:
logger.info(
"Found shutdown preference. Delaying"
+ "backup start. Shutting down server."
)
if self.check_running():
self.stop_server()
was_server_running = True
self.helper.ensure_dir_exists(self.settings["backup_path"]) self.helper.ensure_dir_exists(self.settings["backup_path"])
try: try:
backup_filename = ( backup_filename = (
@ -924,7 +935,13 @@ class ServerInstance:
HelperUsers.get_user_lang_by_id(user), HelperUsers.get_user_lang_by_id(user),
).format(self.name), ).format(self.name),
) )
if was_server_running:
logger.info(
"Backup complete. User had shutdown preference. Starting server."
)
self.start_server(HelperUsers.get_user_id_by_name("system"))
time.sleep(3) time.sleep(3)
self.last_backup_failed = False
except: except:
logger.exception( logger.exception(
f"Failed to create backup of server {self.name} (ID {self.server_id})" f"Failed to create backup of server {self.name} (ID {self.server_id})"
@ -938,6 +955,12 @@ class ServerInstance:
results, results,
) )
self.is_backingup = False self.is_backingup = False
if was_server_running:
logger.info(
"Backup complete. User had shutdown preference. Starting server."
)
self.start_server(HelperUsers.get_user_id_by_name("system"))
self.last_backup_failed = True
def backup_status(self, source_path, dest_path): def backup_status(self, source_path, dest_path):
results = Helpers.calc_percent(source_path, dest_path) results = Helpers.calc_percent(source_path, dest_path)
@ -950,6 +973,9 @@ class ServerInstance:
results, results,
) )
def last_backup_status(self):
return self.last_backup_failed
def send_backup_status(self): def send_backup_status(self):
try: try:
return self.backup_stats return self.backup_stats

View File

@ -497,6 +497,10 @@ class PanelHandler(BaseHandler):
if server_id is None: if server_id is None:
return return
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 = [ valid_subpages = [
"term", "term",
"logs", "logs",
@ -1435,6 +1439,7 @@ class PanelHandler(BaseHandler):
server_obj = self.controller.servers.get_server_obj(server_id) server_obj = self.controller.servers.get_server_obj(server_id)
compress = self.get_argument("compress", False) compress = self.get_argument("compress", False)
shutdown = self.get_argument("shutdown", False)
check_changed = self.get_argument("changed") check_changed = self.get_argument("changed")
if str(check_changed) == str(1): if str(check_changed) == str(1):
checked = self.get_body_arguments("root_path") checked = self.get_body_arguments("root_path")
@ -1457,6 +1462,7 @@ class PanelHandler(BaseHandler):
max_backups=max_backups, max_backups=max_backups,
excluded_dirs=checked, excluded_dirs=checked,
compress=bool(compress), compress=bool(compress),
shutdown=bool(shutdown),
) )
self.controller.management.add_to_audit_log( self.controller.management.add_to_audit_log(

View File

@ -19,11 +19,18 @@
</li> </li>
{% end %} {% end %}
{% if data['permissions']['Backup'] in data['user_permissions'] %} {% if data['permissions']['Backup'] in data['user_permissions'] %}
{% if data['backup_failed'] %}
<li class="nav-item term-nav-item">
<a style="color: red !important;" class="nav-link {% if data['active_link'] == 'backup' %}active{% end %}" href="/panel/server_detail?id={{ data['server_stats']['server_id']['server_id'] }}&subpage=backup" role="tab" aria-selected="false">
<i class="fas fa-save"></i>{{ translate('serverDetails', 'backup', data['lang']) }}&nbsp; <i class="fas fa-exclamation-triangle"> </i></a>
</li>
{% else %}
<li class="nav-item term-nav-item"> <li class="nav-item term-nav-item">
<a class="nav-link {% if data['active_link'] == 'backup' %}active{% end %}" href="/panel/server_detail?id={{ data['server_stats']['server_id']['server_id'] }}&subpage=backup" role="tab" aria-selected="false"> <a class="nav-link {% if data['active_link'] == 'backup' %}active{% end %}" href="/panel/server_detail?id={{ data['server_stats']['server_id']['server_id'] }}&subpage=backup" role="tab" aria-selected="false">
<i class="fas fa-save"></i>{{ translate('serverDetails', 'backup', data['lang']) }}</a> <i class="fas fa-save"></i>{{ translate('serverDetails', 'backup', data['lang']) }}</a>
</li> </li>
{% end %} {% end %}
{% end %}
{% if data['permissions']['Files'] in data['user_permissions'] %} {% if data['permissions']['Files'] in data['user_permissions'] %}
<li class="nav-item term-nav-item"> <li class="nav-item term-nav-item">
<a class="nav-link {% if data['active_link'] == 'files' %}active{% end %}" href="/panel/server_detail?id={{ data['server_stats']['server_id']['server_id'] }}&subpage=files" role="tab" aria-selected="false"> <a class="nav-link {% if data['active_link'] == 'files' %}active{% end %}" href="/panel/server_detail?id={{ data['server_stats']['server_id']['server_id'] }}&subpage=files" role="tab" aria-selected="false">

View File

@ -97,6 +97,16 @@
translate('serverBackups', 'compress', data['lang']) }} translate('serverBackups', 'compress', data['lang']) }}
{% end %} {% end %}
</div> </div>
<div class="form-group">
<label for="shutdown" class="form-check-label ml-4 mb-4"></label>
{% if data['backup_config']['shutdown'] %}
<input type="checkbox" class="form-check-input" id="shutdown" name="shutdown" checked=""
value="True">{{ translate('serverBackups', 'shutdown', data['lang']) }}
{% else %}
<input type="checkbox" class="form-check-input" id="shutdown" name="shutdown" value="True">{{
translate('serverBackups', 'shutdown', data['lang']) }}
{% end %}
</div>
<div class="form-group"> <div class="form-group">
<label for="server">{{ translate('serverBackups', 'exclusionsTitle', data['lang']) }} <small> - {{ <label for="server">{{ translate('serverBackups', 'exclusionsTitle', data['lang']) }} <small> - {{
translate('serverBackups', 'excludedChoose', data['lang']) }}</small></label> translate('serverBackups', 'excludedChoose', data['lang']) }}</small></label>

View File

@ -0,0 +1,16 @@
# Generated by database migrator
import peewee
def migrate(migrator, database, **kwargs):
migrator.add_columns("backups", shutdown=peewee.BooleanField(default=False))
"""
Write your migrations here.
"""
def rollback(migrator, database, **kwargs):
migrator.drop_columns("backups", ["shutdown"])
"""
Write your rollback migrations here.
"""

View File

@ -271,7 +271,8 @@
"save": "Save", "save": "Save",
"size": "Size", "size": "Size",
"storageLocation": "Storage Location", "storageLocation": "Storage Location",
"storageLocationDesc": "Where do you want to store backups?" "storageLocationDesc": "Where do you want to store backups?",
"shutdown": "Shutdown server for duration of backup"
}, },
"serverConfig": { "serverConfig": {
"bePatientDelete": "Please be patient while we remove your server from the Crafty panel. This screen will close in a few moments.", "bePatientDelete": "Please be patient while we remove your server from the Crafty panel. This screen will close in a few moments.",