feat: backup and restore postgres site

This commit is contained in:
Revant Nandgaonkar 2020-06-27 16:01:30 +05:30
parent d39da928d7
commit 1bfa56cd0c
3 changed files with 48 additions and 13 deletions

View file

@ -136,7 +136,7 @@ def restore(context, sql_file_path, mariadb_root_username=None, mariadb_root_pas
_new_site(frappe.conf.db_name, site, mariadb_root_username=mariadb_root_username,
mariadb_root_password=mariadb_root_password, admin_password=admin_password,
verbose=context.verbose, install_apps=install_app, source_sql=decompressed_file_name,
force=True)
force=True, db_type=frappe.conf.db_type)
# Extract public and/or private files to the restored site, if user has given the path
if with_public_files:

View file

@ -1,7 +1,7 @@
import frappe, subprocess, os
from six.moves import input
def setup_database(force, source_sql, verbose):
def setup_database(force, source_sql=None, verbose=False):
root_conn = get_root_connection()
root_conn.commit()
root_conn.sql("DROP DATABASE IF EXISTS `{0}`".format(frappe.conf.db_name))
@ -16,10 +16,12 @@ def setup_database(force, source_sql, verbose):
subprocess_env = os.environ.copy()
subprocess_env['PGPASSWORD'] = str(frappe.conf.db_password)
# bootstrap db
if not source_sql:
source_sql = os.path.join(os.path.dirname(__file__), 'framework_postgres.sql')
subprocess.check_output([
'psql', frappe.conf.db_name, '-h', frappe.conf.db_host or 'localhost', '-U',
frappe.conf.db_name, '-f',
os.path.join(os.path.dirname(__file__), 'framework_postgres.sql')
frappe.conf.db_name, '-f', source_sql
], env=subprocess_env)
frappe.connect()

View file

@ -26,17 +26,24 @@ class BackupGenerator:
If specifying db_file_name, also append ".sql.gz"
"""
def __init__(self, db_name, user, password, backup_path_db=None, backup_path_files=None,
backup_path_private_files=None, db_host="localhost", db_port=3306, verbose=False):
backup_path_private_files=None, db_host="localhost", db_port=None, verbose=False,
db_type='mariadb'):
global _verbose
self.db_host = db_host
self.db_port = db_port or 3306
self.db_port = db_port
self.db_name = db_name
self.db_type = db_type
self.user = user
self.password = password
self.backup_path_files = backup_path_files
self.backup_path_db = backup_path_db
self.backup_path_private_files = backup_path_private_files
if not self.db_port and self.db_type == 'mariadb':
self.db_port = 3306
elif not self.db_port and self.db_type == 'postgres':
self.db_port = 5432
site = frappe.local.site or frappe.generate_hash(length=8)
self.site_slug = site.replace('.', '_')
@ -141,6 +148,17 @@ class BackupGenerator:
for item in self.__dict__.copy().items())
cmd_string = """mysqldump --single-transaction --quick --lock-tables=false -u %(user)s -p%(password)s %(db_name)s -h %(db_host)s -P %(db_port)s | gzip > %(backup_path_db)s """ % args
if self.db_type == 'postgres':
cmd_string = "pg_dump postgres://{user}:{password}@{db_host}:{db_port}/{db_name} | gzip > {backup_path_db}".format(
user=args.get('user'),
password=args.get('password'),
db_host=args.get('db_host'),
db_port=args.get('db_port'),
db_name=args.get('db_name'),
backup_path_db=args.get('backup_path_db')
)
err, out = frappe.utils.execute_in_shell(cmd_string)
def send_email(self):
@ -181,7 +199,8 @@ def get_backup():
"""
delete_temp_backups()
odb = BackupGenerator(frappe.conf.db_name, frappe.conf.db_name,\
frappe.conf.db_password, db_host = frappe.db.host)
frappe.conf.db_password, db_host = frappe.db.host,\
db_type=frappe.conf.db_type, db_port=frappe.conf.db_port)
odb.get_backup()
recipient_list = odb.send_email()
frappe.msgprint(_("Download link for your backup will be emailed on the following email address: {0}").format(', '.join(recipient_list)))
@ -201,6 +220,7 @@ def new_backup(older_than=6, ignore_files=False, backup_path_db=None, backup_pat
backup_path_private_files=backup_path_private_files,
db_host = frappe.db.host,
db_port = frappe.db.port,
db_type = frappe.conf.db_type,
verbose=verbose)
odb.get_backup(older_than, ignore_files, force=force)
return odb
@ -258,25 +278,38 @@ def backup(with_files=False, backup_path_db=None, backup_path_files=None, quiet=
if __name__ == "__main__":
"""
is_file_old db_name user password db_host
get_backup db_name user password db_host
is_file_old db_name user password db_host db_type db_port
get_backup db_name user password db_host db_type db_port
"""
import sys
cmd = sys.argv[1]
db_type = 'mariadb'
try:
db_type = sys.argv[6]
except IndexError as error:
pass
db_port = 3306
try:
db_port = int(sys.argv[7])
except IndexError as error:
pass
if cmd == "is_file_old":
odb = BackupGenerator(sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5] or "localhost")
odb = BackupGenerator(sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5] or "localhost", db_type=db_type, db_port=db_port)
is_file_old(odb.db_file_name)
if cmd == "get_backup":
odb = BackupGenerator(sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5] or "localhost")
odb = BackupGenerator(sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5] or "localhost", db_type=db_type, db_port=db_port)
odb.get_backup()
if cmd == "take_dump":
odb = BackupGenerator(sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5] or "localhost")
odb = BackupGenerator(sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5] or "localhost", db_type=db_type, db_port=db_port)
odb.take_dump()
if cmd == "send_email":
odb = BackupGenerator(sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5] or "localhost")
odb = BackupGenerator(sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5] or "localhost", db_type=db_type, db_port=db_port)
odb.send_email("abc.sql.gz")
if cmd == "delete_temp_backups":