Merge pull request #25873 from akhilnarang/delete-failed-backup

feat: delete failed backups
This commit is contained in:
Akhil Narang 2024-04-10 13:07:35 +05:30 committed by GitHub
commit 50fe31ca48
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 39 additions and 14 deletions

View file

@ -924,11 +924,13 @@ def backup(
verbose = verbose or context.verbose
exit_code = 0
rollback_callback = None
for site in context.sites:
try:
frappe.init(site=site)
frappe.connect()
rollback_callback = CallbackManager()
odb = scheduled_backup(
ignore_files=not with_files,
backup_path=backup_path,
@ -943,12 +945,16 @@ def backup(
verbose=verbose,
force=True,
old_backup_metadata=old_backup_metadata,
rollback_callback=rollback_callback,
)
except Exception:
click.secho(
f"Backup failed for Site {site}. Database or site_config.json may be corrupted",
fg="red",
)
if rollback_callback:
rollback_callback.run()
rollback_callback = None
if verbose:
print(frappe.get_traceback(with_context=True))
exit_code = 1

View file

@ -7,6 +7,7 @@ import gzip
import os
import sys
from calendar import timegm
from collections.abc import Callable
from datetime import datetime
from glob import glob
from shutil import which
@ -58,6 +59,7 @@ class BackupGenerator:
exclude_doctypes="",
verbose=False,
old_backup_metadata=False,
rollback_callback=None,
):
global _verbose
self.compress_files = compress_files or compress
@ -78,6 +80,7 @@ class BackupGenerator:
self.exclude_doctypes = exclude_doctypes
self.partial = False
self.old_backup_metadata = old_backup_metadata
self.rollback_callback = rollback_callback
site = frappe.local.site or frappe.generate_hash(length=8)
self.site_slug = site.replace(".", "_")
@ -186,9 +189,13 @@ class BackupGenerator:
if not (last_db and last_file and last_private_file and site_config_backup_path):
self.take_dump()
self.add_to_rollback(lambda: os.remove(self.backup_path_db))
self.copy_site_config()
self.add_to_rollback(lambda: os.remove(self.backup_path_conf))
if not ignore_files:
self.backup_files()
self.add_to_rollback(lambda: os.remove(self.backup_path_files))
self.add_to_rollback(lambda: os.remove(self.backup_path_private_files))
if frappe.get_system_settings("encrypt_backup"):
self.backup_encryption()
@ -248,21 +255,19 @@ class BackupGenerator:
def get_recent_backup(self, older_than, partial=False):
backup_path = get_backup_path()
separator = suffix = ""
if partial:
separator = "*"
if not frappe.get_system_settings("encrypt_backup"):
file_type_slugs = {
"database": "*-{{}}-{}database.sql.gz".format("*" if partial else ""),
"public": "*-{}-files.tar",
"private": "*-{}-private-files.tar",
"config": "*-{}-site_config_backup.json",
}
else:
file_type_slugs = {
"database": "*-{{}}-{}database.enc.sql.gz".format("*" if partial else ""),
"public": "*-{}-files.enc.tar",
"private": "*-{}-private-files.enc.tar",
"config": "*-{}-site_config_backup.json",
}
if frappe.get_system_settings("encrypt_backup"):
suffix = "-enc"
file_type_slugs = {
"database": f"*-{{}}-{separator}database{suffix}.sql.gz",
"public": f"*-{{}}-files{suffix}.tar",
"private": f"*-{{}}-private-files{suffix}.tar",
"config": f"*-{{}}-site_config_backup{suffix}.json",
}
def backup_time(file_path):
file_name = file_path.split(os.sep)[-1]
@ -477,6 +482,16 @@ download only after 24 hours."""
frappe.sendmail(recipients=recipient_list, message=msg, subject=subject)
return recipient_list
def add_to_rollback(self, func: Callable) -> None:
"""
Adds the given callable to the rollback CallbackManager stack
:param func: The callable to add to the rollback stack
:return: Nothing
"""
if self.rollback_callback:
self.rollback_callback.add(func)
def _get_tables(doctypes: list[str], existing_tables: list[str]) -> list[str]:
"""Return a list of tables for the given doctypes that exist in the database."""
@ -529,6 +544,7 @@ def scheduled_backup(
force=False,
verbose=False,
old_backup_metadata=False,
rollback_callback=None,
):
"""this function is called from scheduler
deletes backups older than 7 days
@ -548,6 +564,7 @@ def scheduled_backup(
force=force,
verbose=verbose,
old_backup_metadata=old_backup_metadata,
rollback_callback=rollback_callback,
)
@ -566,6 +583,7 @@ def new_backup(
force=False,
verbose=False,
old_backup_metadata=False,
rollback_callback=None,
):
delete_temp_backups()
odb = BackupGenerator(
@ -587,6 +605,7 @@ def new_backup(
verbose=verbose,
compress_files=compress,
old_backup_metadata=old_backup_metadata,
rollback_callback=rollback_callback,
)
odb.get_backup(older_than, ignore_files, force=force)
return odb