92 lines
3.5 KiB
Python
92 lines
3.5 KiB
Python
import datetime
|
|
import os
|
|
import stat
|
|
import tarfile
|
|
from Models.NextcloudBackupException import NextcloudBackupException
|
|
|
|
|
|
class Container:
|
|
|
|
def __init__(self, name, password, backup_folder, compose_file_path) -> None:
|
|
self.__datetime = datetime.datetime.now().strftime("%Y-%m-%d_%H:%M:%S")
|
|
self.name = name
|
|
self.__password = password
|
|
self.backup_folder = backup_folder
|
|
self.compose_file_path = compose_file_path
|
|
self.__dump_file = self.name + '_' + self.__datetime + '.sql'
|
|
self.__dump_file_path = os.path.join(self.backup_folder, self.__dump_file)
|
|
self.__tar_file = self.name + '_' + self.__datetime + 'tar.gz'
|
|
self.__tar_file_path = os.path.join(self.backup_folder, self.__tar_file)
|
|
|
|
def __str__(self) -> str:
|
|
return F"name: {self.name}\npassword: {self.__password}\ncompose_file_path: {self.compose_file_path}"
|
|
|
|
# Create backup folder if it does not yet exist
|
|
def create_backup_dir(self):
|
|
if not os.path.isfile(self.backup_folder):
|
|
try:
|
|
os.makedirs(self.backup_folder)
|
|
except OSError as e:
|
|
raise OSError(e)
|
|
return True
|
|
else:
|
|
return False
|
|
|
|
# Dump database
|
|
def __dump_db(self) -> bool:
|
|
try:
|
|
os.system(F"docker exec {self.name} mysqldump --password={self.__password} --all-databases > "
|
|
F"{self.__dump_file}")
|
|
return os.path.isfile(self.__dump_file)
|
|
except Exception as e:
|
|
raise Exception(e)
|
|
|
|
# Tar config and settings folder within container and copy it into backup folder
|
|
def __export_config(self) -> bool:
|
|
try:
|
|
os.system(F"docker exec {self.name} tar -czf config_settings.tar config settings")
|
|
os.system(F"docker cp {self.name}:/var/www/html/config_settings.tar {self.__tar_file_path}")
|
|
os.system(F"docker exec {self.name} rm config_settings.tar")
|
|
return os.path.isfile(self.__tar_file_path)
|
|
except Exception as e:
|
|
raise NextcloudBackupException(e)
|
|
|
|
# Tar database with config and settings
|
|
def __tar_db(self) -> bool:
|
|
try:
|
|
with tarfile.open(self.__tar_file_path, 'w:gz') as tarball:
|
|
tarball.add(self.__dump_file_path, arcname=self.__dump_file)
|
|
return tarball.gettarinfo(self.__dump_file).isfile()
|
|
except Exception as e:
|
|
raise NextcloudBackupException(e)
|
|
|
|
# Set secure file permissions
|
|
def __set_file_permissions(self) -> bool:
|
|
try:
|
|
os.chmod(self.__tar_file_path, stat.S_IREAD)
|
|
return oct(os.stat(self.__tar_file_path).st_mode)[-3:] == 600
|
|
except Exception as e:
|
|
raise NextcloudBackupException(e)
|
|
|
|
# Create backup
|
|
def create_backup(self) -> dict:
|
|
try:
|
|
return {"database dump": self.__dump_db(),
|
|
"export config": self.__export_config(),
|
|
"include db in backup": self.__tar_db(),
|
|
"set secure backup file permissions": self.__set_file_permissions()}
|
|
except NextcloudBackupException as e:
|
|
raise NextcloudBackupException(e)
|
|
|
|
@staticmethod
|
|
def deserialize_containers(data: dict) -> list:
|
|
containers = []
|
|
for name, values in data['nextcloud_containers'].items():
|
|
containers.append(Container(
|
|
name,
|
|
values['mysql_password'],
|
|
values['backup_folder'],
|
|
values['compose_file_path'])
|
|
)
|
|
return containers
|