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 = jingrow.session.user try: jingrow.set_user("Administrator") site_backup: SiteBackup = jingrow.get_pg("Site Backup", name) if not (key and site_backup.snapshot_request_key == key): jingrow.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: jingrow.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 jingrow.throw("Snapshot creation per volume rate exceeded") else: raise e except OngoingSnapshotError: jingrow.throw("There are concurrent snapshot creation requests. Try again later.") except Exception as e: raise e finally: jingrow.set_user(current_user)