diff --git a/CHANGELOG.md b/CHANGELOG.md
index 42e06868..d6f380ac 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,11 +3,12 @@
## --- [4.0.4] - 2022/TBD
### New features
-None
+- Add shutdown on backup feature ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/373))
### Bug fixes
-Backup/Config.json rework for API key hardening ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/369))
+- Backup/Config.json rework for API key hardening ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/369))
### Tweaks
-Spelling mistake fixed in German lang file ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/370))
+- Spelling mistake fixed in German lang file ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/370))
+- Backup failure warning (Tab text goes red) ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/373))
## --- [4.0.3] - 2022/06/18
diff --git a/app/classes/controllers/management_controller.py b/app/classes/controllers/management_controller.py
index fdbdcced..b0b1f10a 100644
--- a/app/classes/controllers/management_controller.py
+++ b/app/classes/controllers/management_controller.py
@@ -136,9 +136,10 @@ class ManagementController:
max_backups: int = None,
excluded_dirs: list = None,
compress: bool = False,
+ shutdown: bool = False,
):
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
diff --git a/app/classes/models/management.py b/app/classes/models/management.py
index ef9fab0a..085bdd37 100644
--- a/app/classes/models/management.py
+++ b/app/classes/models/management.py
@@ -128,6 +128,7 @@ class Backups(BaseModel):
max_backups = IntegerField()
server_id = ForeignKeyField(Servers, backref="backups_server")
compress = BooleanField(default=False)
+ shutdown = BooleanField(default=False)
class Meta:
table_name = "backups"
@@ -351,6 +352,7 @@ class HelpersManagement:
"max_backups": row.max_backups,
"server_id": row.server_id_id,
"compress": row.compress,
+ "shutdown": row.shutdown,
}
except IndexError:
conf = {
@@ -359,6 +361,7 @@ class HelpersManagement:
"max_backups": 0,
"server_id": server_id,
"compress": False,
+ "shutdown": False,
}
return conf
@@ -369,6 +372,7 @@ class HelpersManagement:
max_backups: int = None,
excluded_dirs: list = None,
compress: bool = False,
+ shutdown: bool = False,
):
logger.debug(f"Updating server {server_id} backup config with {locals()}")
if Backups.select().where(Backups.server_id == server_id).exists():
@@ -380,6 +384,7 @@ class HelpersManagement:
"max_backups": 0,
"server_id": server_id,
"compress": False,
+ "shutdown": False,
}
new_row = True
if max_backups is not None:
@@ -388,6 +393,7 @@ class HelpersManagement:
dirs_to_exclude = ",".join(excluded_dirs)
conf["excluded_dirs"] = dirs_to_exclude
conf["compress"] = compress
+ conf["shutdown"] = shutdown
if not new_row:
with self.database.atomic():
if backup_path is not None:
diff --git a/app/classes/shared/server.py b/app/classes/shared/server.py
index 230cd3ba..74b4c63a 100644
--- a/app/classes/shared/server.py
+++ b/app/classes/shared/server.py
@@ -127,6 +127,7 @@ class ServerInstance:
self.stats = stats
self.server_object = HelperServers.get_server_obj(self.server_id)
self.stats_helper = HelperServerStats(self.server_id)
+ self.last_backup_failed = False
try:
tz = get_localzone()
except ZoneInfoNotFoundError:
@@ -847,6 +848,7 @@ class ServerInstance:
"backup_reload",
{"percent": 0, "total_files": 0},
)
+ 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)
for user in server_users:
@@ -859,6 +861,15 @@ class ServerInstance:
)
time.sleep(3)
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"])
try:
backup_filename = (
@@ -924,7 +935,13 @@ class ServerInstance:
HelperUsers.get_user_lang_by_id(user),
).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)
+ self.last_backup_failed = False
except:
logger.exception(
f"Failed to create backup of server {self.name} (ID {self.server_id})"
@@ -938,6 +955,12 @@ class ServerInstance:
results,
)
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):
results = Helpers.calc_percent(source_path, dest_path)
@@ -950,6 +973,9 @@ class ServerInstance:
results,
)
+ def last_backup_status(self):
+ return self.last_backup_failed
+
def send_backup_status(self):
try:
return self.backup_stats
diff --git a/app/classes/web/panel_handler.py b/app/classes/web/panel_handler.py
index 26456c19..07553704 100644
--- a/app/classes/web/panel_handler.py
+++ b/app/classes/web/panel_handler.py
@@ -497,6 +497,10 @@ class PanelHandler(BaseHandler):
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()
+ server_obj = None
+
valid_subpages = [
"term",
"logs",
@@ -1435,6 +1439,7 @@ class PanelHandler(BaseHandler):
server_obj = self.controller.servers.get_server_obj(server_id)
compress = self.get_argument("compress", False)
+ shutdown = self.get_argument("shutdown", False)
check_changed = self.get_argument("changed")
if str(check_changed) == str(1):
checked = self.get_body_arguments("root_path")
@@ -1457,6 +1462,7 @@ class PanelHandler(BaseHandler):
max_backups=max_backups,
excluded_dirs=checked,
compress=bool(compress),
+ shutdown=bool(shutdown),
)
self.controller.management.add_to_audit_log(
diff --git a/app/frontend/templates/panel/parts/server_controls_list.html b/app/frontend/templates/panel/parts/server_controls_list.html
index a232f022..8e40e7ec 100644
--- a/app/frontend/templates/panel/parts/server_controls_list.html
+++ b/app/frontend/templates/panel/parts/server_controls_list.html
@@ -19,11 +19,18 @@
{% end %}
{% if data['permissions']['Backup'] in data['user_permissions'] %}
+ {% if data['backup_failed'] %}
+