[bin] backup.py new mode 'copy' thatdoes not use repozo for backup but a simple copy of Data.fs. [gen] Bugfix in pod.py.

This commit is contained in:
Gaetan Delannay 2014-03-11 15:29:59 +01:00
parent 059828b319
commit d956c1f17a
2 changed files with 89 additions and 69 deletions

View file

@ -199,25 +199,54 @@ class ZodbBackuper:
def run(self): def run(self):
w = self.log w = self.log
startTime = time.time() startTime = time.time()
w('\n****** Backup launched at %s ******' % str(time.asctime())) mode = self.options.mode
w('\n****** Backup launched at %s (mode: %s) ******' % \
(str(time.asctime()), mode))
# Shutdown the Zope instance # Shutdown the Zope instance
w('> Shutting down Zope instance...') w('> Shutting down Zope instance...')
self.executeCommand('%s stop' % self.zopectl) self.executeCommand('%s stop' % self.zopectl)
# If we are on the "full backup day", let's pack the ZODB first # Check if we are on the "full backup day"
if time.asctime().startswith(self.options.dayFullBackup): dayFull = self.options.dayFullBackup
# As a preamble to packing the ZODB, remove Data.fs.old if present. if time.asctime().startswith(dayFull):
self.removeDataFsOld() # If mode 'zodb', let's pack the ZODB first. Afterwards it will
w('> Day is "%s", packing the ZODB...' % self.options.dayFullBackup) # trigger a full backup.
self.packZodb() if mode == 'zodb':
# As a preamble to packing the ZODB, remove Data.fs.old if
# present.
self.removeDataFsOld()
w('> Day is "%s", packing the ZODB...' % dayFull)
self.packZodb()
w('Pack done.')
elif mode == 'copy':
dest = os.path.join(self.backupFolder, 'Data.fs.new')
w('> Day is "%s", copying %s to %s...' % \
(dayFull, self.storageLocation, dest))
# Perform a copy of Data.fs to the backup folder.
shutil.copyfile(self.storageLocation, dest)
# The copy has succeeded. Remove the previous copy and rename
# this one.
oldDest = os.path.join(self.backupFolder, 'Data.fs')
w('> Copy successful. Renaming %s to %s...' % (dest, oldDest))
if os.path.exists(oldDest):
os.remove(oldDest)
w('> (Old existing backup %s was removed).' % oldDest)
os.rename(dest, oldDest)
w('Done.')
# Make a backup of the log files...
w('> Make a backup of log files...') w('> Make a backup of log files...')
self.backupLogs() self.backupLogs()
w('Done.') w('Log files copied.')
else:
if mode == 'copy':
w('Copy mode: nothing to copy: day is not %s.' % dayFull)
# Do the backup with repozo # Do the backup with repozo
w('> Performing backup...') if mode == 'zodb':
self.executeCommand('%s %s -BvzQ -r %s -f %s' % (self.options.python, w('> Performing backup...')
self.repozo, self.backupFolder, self.storageLocation)) self.executeCommand('%s %s -BvzQ -r %s -f %s' % \
# Remove previous full backups. (self.options.python, self.repozo, self.backupFolder,
self.removeOldBackups() self.storageLocation))
# Remove previous full backups.
self.removeOldBackups()
# If a command is specified, run Zope to execute this command # If a command is specified, run Zope to execute this command
if self.options.command: if self.options.command:
w('> Executing command "%s"...' % self.options.command) w('> Executing command "%s"...' % self.options.command)
@ -290,75 +319,65 @@ class ZodbBackupScript:
def run(self): def run(self):
optParser = OptionParser(usage=ZodbBackupScript.__doc__) optParser = OptionParser(usage=ZodbBackupScript.__doc__)
optParser.add_option("-p", "--python", dest="python", optParser.add_option("-p", "--python", dest="python",
help="The path to the Python interpreter running "\ help="The path to the Python interpreter running Zope",
"Zope", default='python2.4',metavar="PYTHON",type='string')
default='python2.4',metavar="PYTHON",type='string')
optParser.add_option("-r", "--repozo", dest="repozo", optParser.add_option("-r", "--repozo", dest="repozo",
help="The path to repozo.py", help="The path to repozo.py", default='', metavar="REPOZO",
default='', metavar="REPOZO", type='string') type='string')
optParser.add_option("-z", "--zopectl", dest="zopectl", optParser.add_option("-z", "--zopectl", dest="zopectl",
help="The path to Zope instance's zopectl script", help="The path to Zope instance's zopectl script", default='',
default='', metavar="ZOPECTL", type='string') metavar="ZOPECTL", type='string')
optParser.add_option("-l", "--logfile", dest="logFile", optParser.add_option("-l", "--logfile", dest="logFile",
help="Log file where this script will append " \ help="Log file where this script will append output (defaults to " \
"output (defaults to ./backup.log)", "./backup.log)", default='./backup.log', metavar="LOGFILE",
default='./backup.log', metavar="LOGFILE", type='string')
type='string')
optParser.add_option("-d", "--day-full-backup", dest="dayFullBackup", optParser.add_option("-d", "--day-full-backup", dest="dayFullBackup",
help="Day of the week where the full backup " \ help="Day of the week where the full backup must be performed " \
"must be performed (defaults to 'Sun'). " \ "(defaults to 'Sun'). Must be one of %s" % str(self.weekDays),
"Must be one of %s" % str(self.weekDays), default='Sun', metavar="DAYFULLBACKUP", type='string')
default='Sun', metavar="DAYFULLBACKUP",
type='string')
optParser.add_option("-e", "--emails", dest="emails", optParser.add_option("-e", "--emails", dest="emails",
help="Comma-separated list of emails that will " \ help="Comma-separated list of emails that will receive the log " \
"receive the log of this script.", "of this script.", default='', metavar="EMAILS", type='string')
default='', metavar="EMAILS", type='string')
optParser.add_option("-f", "--from-address", dest="fromAddress", optParser.add_option("-f", "--from-address", dest="fromAddress",
help="From address for the sent mails", help="From address for the sent mails", default='',
default='', metavar="FROMADDRESS", type='string') metavar="FROMADDRESS", type='string')
optParser.add_option("-s", "--smtp-server", dest="smtpServer", optParser.add_option("-s", "--smtp-server", dest="smtpServer",
help="SMTP server and port (ie: localhost:25) " \ help="SMTP server and port (ie: localhost:25) for sending mails. " \
"for sending mails. You can also embed " \ "You can also embed username and password if the SMTP " \
"username and password if the SMTP server " \ "server requires authentication, ie localhost:25:myLogin:" \
"requires authentication, ie " \ "myPassword", default='localhost:25', metavar="SMTPSERVER",
"localhost:25:myLogin:myPassword", type='string')
default='localhost:25', metavar="SMTPSERVER",
type='string')
optParser.add_option("-t", "--tempFolder", dest="tempFolder", optParser.add_option("-t", "--tempFolder", dest="tempFolder",
help="Folder used by OO for producing temp " \ help="Folder used by LibreOffice for producing temp files. " \
"files. Defaults to /tmp.", "Defaults to /tmp.", default='/tmp', metavar="TEMP",
default='/tmp', metavar="TEMP", type='string') type='string')
optParser.add_option("-g", "--logsFolder",dest="logsFolder", optParser.add_option("-g", "--logsFolder",dest="logsFolder",
help="Folder where Zope log files are " \ help="Folder where Zope log files are (typically: event.log and " \
"(typically: event.log and Z2.log). If no " \ "Z2.log). If no folder is provided, we will consider to " \
"folder is provided, we will consider to " \ "work on a standard Zope instance and decide that the log " \
"work on a standard Zope instance and " \ "folder is, from 'storageLocation', located at ../log",
"decide that the log folder is, from " \ metavar="LOGSFOLDER", type='string')
"'storageLocation', located at ../log",
metavar="LOGSFOLDER", type='string')
optParser.add_option("-b", "--logsBackupFolder",dest="logsBackupFolder", optParser.add_option("-b", "--logsBackupFolder",dest="logsBackupFolder",
help="Folder where backups of log files " \ help="Folder where backups of log files (event.log and Z2.log) " \
"(event.log and Z2.log) will be stored.", "will be stored.", default='./logsbackup',
default='./logsbackup', metavar="LOGSBACKUPFOLDER", metavar="LOGSBACKUPFOLDER", type='string')
type='string')
optParser.add_option("-u", "--user", dest="zopeUser", optParser.add_option("-u", "--user", dest="zopeUser",
help="User and group that must own Data.fs. " \ help="User and group that must own Data.fs. Defaults to " \
"Defaults to zope:www-data. If " \ "zope:www-data. If this script is launched by root, for " \
"this script is launched by root, for " \ "example, when packing the ZODB this script may produce a " \
"example, when packing the ZODB this script "\ "new Data.fs that the user running Zope may not be able to " \
"may produce a new Data.fs that the user " \ "read anymore. After packing, this script makes a 'chmod' " \
"running Zope may not be able to read " \ "on Data.fs.", default='zope:www-data', metavar="USER",
"anymore. After packing, this script makes " \ type='string')
"a 'chmod' on Data.fs.",
default='zope:www-data', metavar="USER",
type='string')
optParser.add_option("-k", "--keep-seconds", dest="keepSeconds", optParser.add_option("-k", "--keep-seconds", dest="keepSeconds",
help="Number of seconds to leave in the ZODB " \ help="Number of seconds to leave in the ZODB history when the " \
"history when the ZODB is packed.", "ZODB is packed.", default='86400', metavar="KEEPSECONDS",
default='86400', metavar="KEEPSECONDS", type='string')
type='string') optParser.add_option("-m", "--mode", dest="mode", help="Default mode, "\
"'zodb', uses repozo for performing backups. Mode 'copy' simply " \
"performs a copy of the database to the specified backup folder.",
default='zodb', metavar="MODE", type='string')
optParser.add_option("-c", "--command", dest="command", optParser.add_option("-c", "--command", dest="command",
help="Command to execute while Zope is running. It must have the " \ help="Command to execute while Zope is running. It must have the " \
"following format: <ZopeAdmin>:<PloneInstancePath>:" \ "following format: <ZopeAdmin>:<PloneInstancePath>:" \

View file

@ -72,6 +72,7 @@ class Pod(Field):
# A global styles mapping that would apply to the whole template # A global styles mapping that would apply to the whole template
self.stylesMapping = stylesMapping self.stylesMapping = stylesMapping
# What are the output formats when generating documents from this pod ? # What are the output formats when generating documents from this pod ?
self.formats = formats
if not formats: if not formats:
# Compute default ones # Compute default ones
if template.endswith('.ods'): if template.endswith('.ods'):