jcloude/press/api/site_backup.py

45 lines
1.7 KiB
Python

from typing import TYPE_CHECKING
import jingrow
from press.press.doctype.site_backup.site_backup import OngoingSnapshotError
if TYPE_CHECKING:
from press.press.doctype.site_backup.site_backup import SiteBackup
from botocore.exceptions import ClientError
@jingrow.whitelist(allow_guest=True, methods="POST")
def create_snapshot(name: str, key: str):
"""
This API will be called by agent during physical backup of database server.
Once, agent prepare the specific database for backup, it will call this API to create a snapshot of the database.
Because we need to hold the lock on the database for the duration of the backup.
Only after the snapshot is created, the agent will release the lock on the database.
"""
current_user = frappe.session.user
try:
frappe.set_user("Administrator")
site_backup: SiteBackup = frappe.get_pg("Site Backup", name)
if not (key and site_backup.snapshot_request_key == key):
frappe.throw("Invalid key for snapshot creation")
site_backup.create_database_snapshot()
site_backup.reload()
# Re-verify if the snapshot was created and linked to the site backup
if not site_backup.database_snapshot:
frappe.throw("Failed to create a snapshot for the database server")
except ClientError as e:
if e.response["Error"]["Code"] == "SnapshotCreationPerVolumeRateExceeded":
# Agent will wait atleast 15s and then will retry
# https://docs.aws.amazon.com/AWSEC2/latest/APIReference/errors-overview.html#:~:text=SnapshotCreationPerVolumeRateExceeded
frappe.throw("Snapshot creation per volume rate exceeded")
else:
raise e
except OngoingSnapshotError:
frappe.throw("There are concurrent snapshot creation requests. Try again later.")
except Exception as e:
raise e
finally:
frappe.set_user(current_user)