mirror of
https://gitlab.com/crafty-controller/crafty-4.git
synced 2025-01-18 17:15:13 +01:00
Setup new backup manager
ToDo: Add legacy backups to new manager to make them more module
This commit is contained in:
parent
a4256b66e8
commit
bd55cdce16
@ -2,20 +2,24 @@ import base64
|
||||
import hashlib
|
||||
import pathlib
|
||||
import shutil
|
||||
import uuid
|
||||
import zlib
|
||||
import datetime
|
||||
|
||||
from app.classes.shared.crypto_helper import CryptoHelper
|
||||
|
||||
# Set byte constants
|
||||
BYTE_FALSE = bytes.fromhex("00")
|
||||
BYTE_TRUE = bytes.fromhex("01")
|
||||
|
||||
|
||||
class BackupManager:
|
||||
def __init__(self, server_instance):
|
||||
self.server_instance = server_instance
|
||||
self.crypto_helper = CryptoHelper()
|
||||
|
||||
# Set byte constants
|
||||
BYTE_FALSE = bytes.fromhex("00")
|
||||
BYTE_TRUE = bytes.fromhex("01")
|
||||
####################################################################################
|
||||
########################## SNAPSHOT METHODS ######################################
|
||||
####################################################################################
|
||||
|
||||
@staticmethod
|
||||
def blake2_hash_bytes(bytes_to_hash: bytes) -> bytes:
|
||||
@ -211,12 +215,12 @@ class BackupManager:
|
||||
# Compress bytes if set to true
|
||||
if use_compression:
|
||||
file_chunk = self.compress_bytes(file_chunk)
|
||||
compression = self.BYTE_TRUE
|
||||
compression = BYTE_TRUE
|
||||
else:
|
||||
compression = self.BYTE_FALSE
|
||||
compression = BYTE_FALSE
|
||||
|
||||
# Placeholder for encryption
|
||||
encryption = self.BYTE_FALSE
|
||||
encryption = BYTE_FALSE
|
||||
nonce = bytes.fromhex("000000000000000000000000")
|
||||
|
||||
# Create Chunk
|
||||
@ -321,16 +325,21 @@ class BackupManager:
|
||||
"""
|
||||
return self.b64_to_bytes(input_b64).decode("utf-8")
|
||||
|
||||
def backup(self) -> uuid.UUID:
|
||||
def backup(self, conf: dict) -> None:
|
||||
"""
|
||||
Perform the backup.
|
||||
Iterate over files in source dir. Apply save function. Save file information to manifest.
|
||||
Iterate over files in source dir. Apply save function.
|
||||
Save file information to manifest.
|
||||
:return: UUID of backup.
|
||||
"""
|
||||
# Initialize backup stuff.
|
||||
backup_id = uuid.uuid4()
|
||||
source_path = pathlib.Path(__file__).parent / "source_files"
|
||||
repo_path = pathlib.Path(__file__).parent / "backup_repository"
|
||||
# Initialize backup stuff.\
|
||||
backup_id = str(
|
||||
datetime.datetime.now()
|
||||
.astimezone(self.server_instance.tz)
|
||||
.strftime("%Y-%m-%d_%H-%M-%S")
|
||||
)
|
||||
source_path = pathlib.Path(self.server_instance.server_path)
|
||||
repo_path = pathlib.Path(conf["backup_location"]) / "snapshots"
|
||||
manifest_path = repo_path / "manifests" / f"{str(backup_id)}.manifest"
|
||||
|
||||
# Get list of files to backup.
|
||||
@ -373,7 +382,6 @@ class BackupManager:
|
||||
|
||||
# Backup complete
|
||||
manifest_file.close()
|
||||
return backup_id
|
||||
|
||||
def recover(
|
||||
self,
|
||||
@ -505,10 +513,14 @@ class BackupManager:
|
||||
# Read use compression byte
|
||||
use_compression_byte = chunk_file.read(1)
|
||||
|
||||
if use_compression_byte == self.BYTE_TRUE:
|
||||
if use_compression_byte == BYTE_TRUE:
|
||||
try:
|
||||
return self.decompress_bytes(chunk_file.read())
|
||||
except zlib.error as why:
|
||||
raise RuntimeError(f"Unable to decompress file {chunk_path}.") from why
|
||||
else:
|
||||
return chunk_file.read()
|
||||
|
||||
####################################################################################
|
||||
########################## LEGACY BACKUP METHODS #################################
|
||||
####################################################################################
|
||||
|
@ -1,2 +1,3 @@
|
||||
class CryptoHelper:
|
||||
print("hi")
|
||||
def __init__(self):
|
||||
return
|
||||
|
@ -1185,108 +1185,112 @@ class ServerInstance:
|
||||
|
||||
self.helper.ensure_dir_exists(backup_location)
|
||||
|
||||
try:
|
||||
backup_filename = (
|
||||
f"{backup_location}/"
|
||||
f"{datetime.datetime.now().astimezone(self.tz).strftime('%Y-%m-%d_%H-%M-%S')}" # pylint: disable=line-too-long
|
||||
)
|
||||
logger.info(
|
||||
f"Creating backup of server '{self.settings['server_name']}'"
|
||||
f" (ID#{self.server_id}, path={self.server_path}) "
|
||||
f"at '{backup_filename}'"
|
||||
)
|
||||
excluded_dirs = HelpersManagement.get_excluded_backup_dirs(backup_id)
|
||||
server_dir = Helpers.get_os_understandable_path(self.settings["path"])
|
||||
if conf["snapshot"]:
|
||||
self.backup_manager.backup(conf)
|
||||
else:
|
||||
|
||||
self.file_helper.make_backup(
|
||||
Helpers.get_os_understandable_path(backup_filename),
|
||||
server_dir,
|
||||
excluded_dirs,
|
||||
self.server_id,
|
||||
backup_id,
|
||||
conf["backup_name"],
|
||||
conf["compress"],
|
||||
)
|
||||
|
||||
while (
|
||||
len(self.list_backups(conf)) > conf["max_backups"]
|
||||
and conf["max_backups"] > 0
|
||||
):
|
||||
backup_list = self.list_backups(conf)
|
||||
oldfile = backup_list[0]
|
||||
oldfile_path = f"{backup_location}/{oldfile['path']}"
|
||||
logger.info(f"Removing old backup '{oldfile['path']}'")
|
||||
os.remove(Helpers.get_os_understandable_path(oldfile_path))
|
||||
|
||||
logger.info(f"Backup of server: {self.name} completed")
|
||||
results = {
|
||||
"percent": 100,
|
||||
"total_files": 0,
|
||||
"current_file": 0,
|
||||
"backup_id": backup_id,
|
||||
}
|
||||
if len(WebSocketManager().clients) > 0:
|
||||
WebSocketManager().broadcast_page_params(
|
||||
"/panel/server_detail",
|
||||
{"id": str(self.server_id)},
|
||||
"backup_status",
|
||||
results,
|
||||
try:
|
||||
backup_filename = (
|
||||
f"{backup_location}/"
|
||||
f"{datetime.datetime.now().astimezone(self.tz).strftime('%Y-%m-%d_%H-%M-%S')}" # pylint: disable=line-too-long
|
||||
)
|
||||
server_users = PermissionsServers.get_server_user_list(self.server_id)
|
||||
for user in server_users:
|
||||
WebSocketManager().broadcast_user(
|
||||
user,
|
||||
"notification",
|
||||
self.helper.translation.translate(
|
||||
"notify",
|
||||
"backupComplete",
|
||||
HelperUsers.get_user_lang_by_id(user),
|
||||
).format(self.name),
|
||||
)
|
||||
if was_server_running:
|
||||
logger.info(
|
||||
"Backup complete. User had shutdown preference. Starting server."
|
||||
f"Creating backup of server '{self.settings['server_name']}'"
|
||||
f" (ID#{self.server_id}, path={self.server_path}) "
|
||||
f"at '{backup_filename}'"
|
||||
)
|
||||
self.run_threaded_server(HelperUsers.get_user_id_by_name("system"))
|
||||
time.sleep(3)
|
||||
if conf["after"]:
|
||||
if self.check_running():
|
||||
logger.debug(
|
||||
"Found running server and send command option. Sending command"
|
||||
excluded_dirs = HelpersManagement.get_excluded_backup_dirs(backup_id)
|
||||
server_dir = Helpers.get_os_understandable_path(self.settings["path"])
|
||||
|
||||
self.file_helper.make_backup(
|
||||
Helpers.get_os_understandable_path(backup_filename),
|
||||
server_dir,
|
||||
excluded_dirs,
|
||||
self.server_id,
|
||||
backup_id,
|
||||
conf["backup_name"],
|
||||
conf["compress"],
|
||||
)
|
||||
|
||||
while (
|
||||
len(self.list_backups(conf)) > conf["max_backups"]
|
||||
and conf["max_backups"] > 0
|
||||
):
|
||||
backup_list = self.list_backups(conf)
|
||||
oldfile = backup_list[0]
|
||||
oldfile_path = f"{backup_location}/{oldfile['path']}"
|
||||
logger.info(f"Removing old backup '{oldfile['path']}'")
|
||||
os.remove(Helpers.get_os_understandable_path(oldfile_path))
|
||||
|
||||
logger.info(f"Backup of server: {self.name} completed")
|
||||
results = {
|
||||
"percent": 100,
|
||||
"total_files": 0,
|
||||
"current_file": 0,
|
||||
"backup_id": backup_id,
|
||||
}
|
||||
if len(WebSocketManager().clients) > 0:
|
||||
WebSocketManager().broadcast_page_params(
|
||||
"/panel/server_detail",
|
||||
{"id": str(self.server_id)},
|
||||
"backup_status",
|
||||
results,
|
||||
)
|
||||
self.send_command(conf["after"])
|
||||
# pause to let people read message.
|
||||
HelpersManagement.update_backup_config(
|
||||
backup_id,
|
||||
{"status": json.dumps({"status": "Standby", "message": ""})},
|
||||
)
|
||||
time.sleep(5)
|
||||
except Exception as e:
|
||||
logger.exception(
|
||||
f"Failed to create backup of server {self.name} (ID {self.server_id})"
|
||||
)
|
||||
results = {
|
||||
"percent": 100,
|
||||
"total_files": 0,
|
||||
"current_file": 0,
|
||||
"backup_id": backup_id,
|
||||
}
|
||||
if len(WebSocketManager().clients) > 0:
|
||||
WebSocketManager().broadcast_page_params(
|
||||
"/panel/server_detail",
|
||||
{"id": str(self.server_id)},
|
||||
"backup_status",
|
||||
results,
|
||||
server_users = PermissionsServers.get_server_user_list(self.server_id)
|
||||
for user in server_users:
|
||||
WebSocketManager().broadcast_user(
|
||||
user,
|
||||
"notification",
|
||||
self.helper.translation.translate(
|
||||
"notify",
|
||||
"backupComplete",
|
||||
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.run_threaded_server(HelperUsers.get_user_id_by_name("system"))
|
||||
time.sleep(3)
|
||||
if conf["after"]:
|
||||
if self.check_running():
|
||||
logger.debug(
|
||||
"Found running server and send command option. Sending command"
|
||||
)
|
||||
self.send_command(conf["after"])
|
||||
# pause to let people read message.
|
||||
HelpersManagement.update_backup_config(
|
||||
backup_id,
|
||||
{"status": json.dumps({"status": "Standby", "message": ""})},
|
||||
)
|
||||
if was_server_running:
|
||||
logger.info(
|
||||
"Backup complete. User had shutdown preference. Starting server."
|
||||
time.sleep(5)
|
||||
except Exception as e:
|
||||
logger.exception(
|
||||
f"Failed to create backup of server {self.name} (ID {self.server_id})"
|
||||
)
|
||||
results = {
|
||||
"percent": 100,
|
||||
"total_files": 0,
|
||||
"current_file": 0,
|
||||
"backup_id": backup_id,
|
||||
}
|
||||
if len(WebSocketManager().clients) > 0:
|
||||
WebSocketManager().broadcast_page_params(
|
||||
"/panel/server_detail",
|
||||
{"id": str(self.server_id)},
|
||||
"backup_status",
|
||||
results,
|
||||
)
|
||||
if was_server_running:
|
||||
logger.info(
|
||||
"Backup complete. User had shutdown preference. Starting server."
|
||||
)
|
||||
self.run_threaded_server(HelperUsers.get_user_id_by_name("system"))
|
||||
HelpersManagement.update_backup_config(
|
||||
backup_id,
|
||||
{"status": json.dumps({"status": "Failed", "message": f"{e}"})},
|
||||
)
|
||||
self.run_threaded_server(HelperUsers.get_user_id_by_name("system"))
|
||||
HelpersManagement.update_backup_config(
|
||||
backup_id,
|
||||
{"status": json.dumps({"status": "Failed", "message": f"{e}"})},
|
||||
)
|
||||
self.set_backup_status()
|
||||
|
||||
def last_backup_status(self):
|
||||
|
Loading…
x
Reference in New Issue
Block a user