Browse Source

auto_backup: allow to change the format of backup (#1333)

pull/1384/head
Jordi Riera 6 years ago
committed by Aitor Bouzas
parent
commit
121d660697
  1. 39
      auto_backup/models/db_backup.py
  2. 26
      auto_backup/tests/test_db_backup.py
  3. 1
      auto_backup/view/db_backup_view.xml

39
auto_backup/models/db_backup.py

@ -83,6 +83,15 @@ class DbBackup(models.Model):
"read permissions for that file.", "read permissions for that file.",
) )
backup_format = fields.Selection(
[
("zip", "zip (includes filestore)"),
("dump", "pg_dump custom format (without filestore)")
],
default='zip',
help="Choose the format for this backup."
)
@api.model @api.model
def _default_folder(self): def _default_folder(self):
"""Default to ``backups`` folder inside current server datadir.""" """Default to ``backups`` folder inside current server datadir."""
@ -131,11 +140,11 @@ class DbBackup(models.Model):
def action_backup(self): def action_backup(self):
"""Run selected backups.""" """Run selected backups."""
backup = None backup = None
filename = self.filename(datetime.now())
successful = self.browse() successful = self.browse()
# Start with local storage # Start with local storage
for rec in self.filtered(lambda r: r.method == "local"): for rec in self.filtered(lambda r: r.method == "local"):
filename = self.filename(datetime.now(), ext=rec.backup_format)
with rec.backup_log(): with rec.backup_log():
# Directory must exist # Directory must exist
try: try:
@ -151,21 +160,28 @@ class DbBackup(models.Model):
shutil.copyfileobj(cached, destiny) shutil.copyfileobj(cached, destiny)
# Generate new backup # Generate new backup
else: else:
db.dump_db(self.env.cr.dbname, destiny)
db.dump_db(
self.env.cr.dbname,
destiny,
backup_format=rec.backup_format
)
backup = backup or destiny.name backup = backup or destiny.name
successful |= rec successful |= rec
# Ensure a local backup exists if we are going to write it remotely # Ensure a local backup exists if we are going to write it remotely
sftp = self.filtered(lambda r: r.method == "sftp") sftp = self.filtered(lambda r: r.method == "sftp")
if sftp: if sftp:
if backup:
cached = open(backup)
else:
cached = db.dump_db(self.env.cr.dbname, None)
with cached:
for rec in sftp: for rec in sftp:
filename = self.filename(datetime.now(), ext=rec.backup_format)
with rec.backup_log(): with rec.backup_log():
cached = db.dump_db(
self.env.cr.dbname,
None,
backup_format=rec.backup_format
)
with cached:
with rec.sftp_connection() as remote: with rec.sftp_connection() as remote:
# Directory must exist # Directory must exist
try: try:
@ -255,13 +271,16 @@ class DbBackup(models.Model):
self.name) self.name)
@staticmethod @staticmethod
def filename(when):
def filename(when, ext='zip'):
"""Generate a file name for a backup. """Generate a file name for a backup.
:param datetime.datetime when: :param datetime.datetime when:
Use this datetime instead of :meth:`datetime.datetime.now`. Use this datetime instead of :meth:`datetime.datetime.now`.
:param str ext: Extension of the file. Default: dump.zip
""" """
return "{:%Y_%m_%d_%H_%M_%S}.dump.zip".format(when)
return "{:%Y_%m_%d_%H_%M_%S}.{ext}".format(
when, ext='dump.zip' if ext == 'zip' else ext
)
@api.multi @api.multi
def sftp_connection(self): def sftp_connection(self):

26
auto_backup/tests/test_db_backup.py

@ -175,18 +175,6 @@ class TestDbBackup(common.TransactionCase):
'wb' 'wb'
) )
def test_action_backup_sftp_remote_open(self):
""" It should open remote file w/ proper args """
rec_id = self.new_record()
with self.mock_assets() as assets:
with self.patch_filtered_sftp(rec_id):
conn = rec_id.sftp_connection().__enter__()
rec_id.action_backup()
conn.open.assert_called_once_with(
assets['os'].path.join(),
'wb'
)
def test_action_backup_all_search(self): def test_action_backup_all_search(self):
""" It should search all records """ """ It should search all records """
rec_id = self.new_record() rec_id = self.new_record()
@ -241,8 +229,20 @@ class TestDbBackup(common.TransactionCase):
pysftp.Connection(), res, pysftp.Connection(), res,
) )
def test_filename(self):
def test_filename_default(self):
""" It should not error and should return a .dump.zip file str """ """ It should not error and should return a .dump.zip file str """
now = datetime.now() now = datetime.now()
res = self.Model.filename(now) res = self.Model.filename(now)
self.assertTrue(res.endswith(".dump.zip")) self.assertTrue(res.endswith(".dump.zip"))
def test_filename_zip(self):
""" It should return a dump.zip filename"""
now = datetime.now()
res = self.Model.filename(now, ext='zip')
self.assertTrue(res.endswith(".dump.zip"))
def test_filename_dump(self):
""" It should return a dump filename"""
now = datetime.now()
res = self.Model.filename(now, ext='dump')
self.assertTrue(res.endswith(".dump"))

1
auto_backup/view/db_backup_view.xml

@ -15,6 +15,7 @@
<field name="folder"/> <field name="folder"/>
<field name="days_to_keep"/> <field name="days_to_keep"/>
<field name="method"/> <field name="method"/>
<field name="backup_format"/>
</group> </group>
<div attrs="{'invisible': [('method', '!=', 'sftp')]}"> <div attrs="{'invisible': [('method', '!=', 'sftp')]}">
<div class="bg-warning text-warning"> <div class="bg-warning text-warning">

Loading…
Cancel
Save