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

pull/2712/head
Jordi Riera 2018-08-10 13:26:05 -04:00 committed by tafaRU
parent 17da338c06
commit 507b351523
4 changed files with 70 additions and 30 deletions

View File

@ -39,6 +39,11 @@ msgstr ""
msgid "Backup Failed" msgid "Backup Failed"
msgstr "" msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup_backup_format
msgid "Backup Format"
msgstr ""
#. module: auto_backup #. module: auto_backup
#: model:ir.actions.server,name:auto_backup.ir_cron_backup_scheduler_0_ir_actions_server #: model:ir.actions.server,name:auto_backup.ir_cron_backup_scheduler_0_ir_actions_server
#: model:ir.cron,cron_name:auto_backup.ir_cron_backup_scheduler_0 #: model:ir.cron,cron_name:auto_backup.ir_cron_backup_scheduler_0
@ -66,25 +71,30 @@ msgstr ""
msgid "Cannot duplicate a configuration." msgid "Cannot duplicate a configuration."
msgstr "" msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup_backup_format
msgid "Choose the format for this backup."
msgstr ""
#. module: auto_backup #. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup_method #: model:ir.model.fields,help:auto_backup.field_db_backup_method
msgid "Choose the storage method for this backup." msgid "Choose the storage method for this backup."
msgstr "" msgstr ""
#. module: auto_backup #. module: auto_backup
#: code:addons/auto_backup/models/db_backup.py:249 #: code:addons/auto_backup/models/db_backup.py:265
#, python-format #, python-format
msgid "Cleanup of old database backups failed." msgid "Cleanup of old database backups failed."
msgstr "" msgstr ""
#. module: auto_backup #. module: auto_backup
#: code:addons/auto_backup/models/db_backup.py:128 #: code:addons/auto_backup/models/db_backup.py:137
#, python-format #, python-format
msgid "Connection Test Failed!" msgid "Connection Test Failed!"
msgstr "" msgstr ""
#. module: auto_backup #. module: auto_backup
#: code:addons/auto_backup/models/db_backup.py:123 #: code:addons/auto_backup/models/db_backup.py:132
#, python-format #, python-format
msgid "Connection Test Succeeded!" msgid "Connection Test Succeeded!"
msgstr "" msgstr ""
@ -105,14 +115,14 @@ msgid "Database Backup"
msgstr "" msgstr ""
#. module: auto_backup #. module: auto_backup
#: code:addons/auto_backup/models/db_backup.py:203 #: code:addons/auto_backup/models/db_backup.py:219
#: model:mail.message.subtype,description:auto_backup.mail_message_subtype_failure #: model:mail.message.subtype,description:auto_backup.mail_message_subtype_failure
#, python-format #, python-format
msgid "Database backup failed." msgid "Database backup failed."
msgstr "" msgstr ""
#. module: auto_backup #. module: auto_backup
#: code:addons/auto_backup/models/db_backup.py:211 #: code:addons/auto_backup/models/db_backup.py:227
#: model:mail.message.subtype,description:auto_backup.mail_message_subtype_success #: model:mail.message.subtype,description:auto_backup.mail_message_subtype_success
#, python-format #, python-format
msgid "Database backup succeeded." msgid "Database backup succeeded."
@ -129,7 +139,7 @@ msgid "Display Name"
msgstr "" msgstr ""
#. module: auto_backup #. module: auto_backup
#: code:addons/auto_backup/models/db_backup.py:114 #: code:addons/auto_backup/models/db_backup.py:123
#, python-format #, python-format
msgid "Do not save backups on your filestore, or you will backup your backups too!" msgid "Do not save backups on your filestore, or you will backup your backups too!"
msgstr "" msgstr ""
@ -294,8 +304,18 @@ msgstr ""
msgid "john" msgid "john"
msgstr "" msgstr ""
#. module: auto_backup
#: selection:db.backup,backup_format:0
msgid "pg_dump custom format (without filestore)"
msgstr ""
#. module: auto_backup #. module: auto_backup
#: model:ir.ui.view,arch_db:auto_backup.view_backup_conf_form #: model:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "sftp.example.com" msgid "sftp.example.com"
msgstr "" msgstr ""
#. module: auto_backup
#: selection:db.backup,backup_format:0
msgid "zip (includes filestore)"
msgstr ""

View File

@ -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: for rec in sftp:
cached = open(backup) filename = self.filename(datetime.now(), ext=rec.backup_format)
else: with rec.backup_log():
cached = db.dump_db(self.env.cr.dbname, None)
with cached: cached = db.dump_db(
for rec in sftp: self.env.cr.dbname,
with rec.backup_log(): 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):

View File

@ -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"))

View File

@ -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">