Commit 13540928 authored by Daniel Armbruster's avatar Daniel Armbruster Committed by thomas.forbriger
Browse files

Changes considered in ticket:157 applied.

This is a legacy commit from before 2015-05-18.
It may be incomplete as well as inconsistent.
See COPYING.legacy and README.history for details.


SVN Path:     http://gpitrsvn.gpi.uni-karlsruhe.de/repos/TFSoftware/trunk
SVN Revision: 4380
SVN UUID:     67feda4a-a26e-11df-9d6e-31afc202ad0c
parent 66217631
......@@ -34,12 +34,10 @@
# 11/09/2011 V0.1 Daniel Armbruster
# 14/09/2011 V0.8 Now multiple exclude flags in CONFIGFILE are supported
# 15/09/2011 V0.8.1 Added several improvements
# 08/01/2012 V0.9 New configuration file syntax. Complete rework.
# 08/01/2012 V0.9 New configuration file syntax. Complete rework. Make use
# of python's configparser module.
# 10/01/2012 V0.9.1 added copy section for single rsync command settings
#
# TODO
# 1) Implement a private function for Processor class to check crontab timestamp
# syntax.
#
# =============================================================================
"""
Convert a csback configuration file to a usual crontab file.
......@@ -62,7 +60,7 @@ elif sys.version_info >= (3,):
else:
sys.stderr.write("csback2cron: Incompatible python version.\n")
__version__ = "V0.1"
__version__ = "V0.9.1"
__subversion__ = "$Id$"
__license__ = "GPLv2"
__author__ = "Daniel Armbruster"
......@@ -110,7 +108,7 @@ def help():
<CRONTABFILENAME> Outputfilename of the generated crontab.
-------------------------------------------------------------------------------
Notice that csback2cron does not check any logical values e.g. pathes and/or
cronexpressions.\n"""
cron expressions.\n"""
sys.stdout.write(help_text)
# -----------------------------------------------------------------------------
......@@ -171,7 +169,7 @@ class TestConverter(Converter):
if self.sectionDict['tolerant']:
self.line += ' -t'
for regex in self.sectionDict['exclude']:
self.line += " -e '"+regex+"'"
self.line += ' -e "'+regex.strip()+'"'
self.line += ' '+self.sectionDict['srcdir']+' '+self.sectionDict['dir']
......@@ -180,11 +178,19 @@ class BackupConverter(Converter):
Class which implements a backup section dictionary converter
"""
def convertDict(self):
self.line = self.sectionDict['cronexpr']+' rsync -aq'
for regex in self.sectionDict['exclude']:
self.line += " --exclude='"+regex+"'"
self.line += ' '+self.sectionDict['srcdir']+' '+ \
self.sectionDict['targetdir']+'; csbackgen'
self.line = self.sectionDict['cronexpr']
if self.sectionDict['copy']:
if self.sectionDict['recursive']:
self.sectionDict['copy-special'].append('--recursive')
copyConv = CopyConverter({'cronexpr': self.sectionDict['cronexpr'], \
'srcdir': self.sectionDict['srcdir'], \
'targetdir': self.sectionDict['targetdir'], \
'special': self.sectionDict['copy-special'], \
'exclude': self.sectionDict['copy-exclude']})
copyConv.addCronExpr = False
copyConv.convert()
self.line += str(copyConv)+";"
self.line += ' csbackgen'
if self.sectionDict['logging']:
self.line += ' -l'
if not self.sectionDict['recursive']:
......@@ -192,7 +198,7 @@ class BackupConverter(Converter):
if self.sectionDict['followlinks']:
self.line += ' -f'
for regex in self.sectionDict['exclude']:
self.line += " -e '"+regex+"'"
self.line += ' -e "'+regex.strip()+'"'
self.line += ' -t '+self.sectionDict['targetdir']+' '+ \
self.sectionDict['srcdir']
if self.sectionDict['test']:
......@@ -208,6 +214,21 @@ class BackupConverter(Converter):
testConv.convert()
self.line += '; '+str(testConv)
class CopyConverter(Converter):
"""
Class which implements a copy section dictionary converter
"""
def convertDict(self):
if self.addCronExpr:
self.line = self.sectionDict['cronexpr']+' '
self.line +='rsync -q'
for special in self.sectionDict['special']:
self.line += ' '+special.strip()
for regex in self.sectionDict['exclude']:
self.line += " --exclude='"+regex.strip()+"'"
self.line += ' '+self.sectionDict['srcdir']+' '+self.sectionDict['targetdir']
# -----------------------------------------------------------------------------
class Processor():
"""
......@@ -220,6 +241,7 @@ class Processor():
self.config = ConfigParser(Processor.DEFAULTS)
self.__verbose = verbose
self.mail = {}
self.copies = []
self.backups = []
self.tests = []
self.result = []
......@@ -261,6 +283,38 @@ class Processor():
raise Error("Argument error in [mail] section.")
else:
self.mail = {}
# fetch copies section
try:
copyKeys = self.config.get('copies', 'keys')
copyKeys = set(copyKeys.split(","))
copyKeys = ['copy_'+key.strip() for key in copyKeys]
# fetch every copy section
for key in copyKeys:
if not self.config.has_section(key):
raise Error("Section {0} in configfile not defined.".format(key))
copy = {'id': key}
try:
copy['cronexpr'] = self.config.get(key, 'cronexpr').strip()
copy['srcdir'] = self.config.get(key, 'srcdir').strip()
copy['targetdir'] = self.config.get(key, 'targetdir').strip()
copy['exclude'] = []
if self.config.has_option(key, 'exclude'):
copy['exclude'].extend(self.config.get( \
key, 'exclude', raw=1).split(", "))
copy['special'] = []
if self.config.has_option(key, 'specialcommands'):
copy['special'].extend(self.config.get( \
key, 'specialcommands', raw=1).split(", "))
except NoOptionError as err:
raise Error("{0}".format(err.message))
except ValueError:
raise Error("Argument error in [{0}] section.".format(key))
else:
self.copies.append(copy)
except NoOptionError as err:
raise Error("{0}".format(err.message))
except NoSectionError:
self.copies = []
# fetch backups section
try:
backupKeys = self.config.get('backups', 'keys')
......@@ -275,13 +329,22 @@ class Processor():
backup['cronexpr'] = self.config.get(key, 'cronexpr').strip()
backup['srcdir'] = self.config.get(key, 'srcdir').strip()
backup['targetdir'] = self.config.get(key, 'targetdir').strip()
backup['exclude'] = []
if self.config.has_option(key, 'exclude'):
backup['exclude'] = self.config.get(key, 'exclude',raw=1).split(", ")
else:
backup['exclude'] = []
backup['recursive'] = self.config.getboolean(key, 'recursive')
backup['logging'] = self.config.getboolean(key, 'logging')
backup['followlinks'] = self.config.getboolean(key, 'followlinks')
backup['copy'] = self.config.getboolean(key, 'copy')
backup['copy-exclude'] = []
backup['copy-special'] = []
if backup['copy']:
if self.config.has_option(key, 'copy-exclude'):
backup['copy-exclude'].extend(self.config.get( \
key, 'copy-exclude',raw=1).split(", "))
if self.config.has_option(key, 'copy-special'):
backup['copy-special'].append(self.config.get( \
key, 'copy-special').strip())
backup['test'] = self.config.getboolean(key, 'test')
backup['tolerant'] = self.config.getboolean(key, 'tolerant')
except NoOptionError as err:
......@@ -293,7 +356,7 @@ class Processor():
except NoOptionError as err:
raise Error("{0}".format(err.message))
except NoSectionError:
self.backups = {}
self.backups = []
# fetch tests section
try:
testKeys = self.config.get('tests', 'keys')
......@@ -328,7 +391,7 @@ class Processor():
except NoOptionError as err:
raise Error("{0}".format(err.message))
except NoSectionError:
self.tests = {}
self.tests = []
if self.__verbose:
sys.stdout.write("csback2cron: Finished reading CONFIGFILE.\n")
......@@ -338,6 +401,13 @@ class Processor():
"""
if self.__verbose:
sys.stdout.write("csback2cron: Conversion ... \n")
#convert copy sections
if len(self.copies) and self.__verbose:
sys.stdout.write("csback2cron: Converting copy sections ...\n")
for copy in self.copies:
copyConv = CopyConverter(copy)
copyConv.convert()
self.result.append(str(copyConv)+"\n")
# convert backup sections
if len(self.backups) and self.__verbose:
sys.stdout.write("csback2cron: Converting backup sections ...\n")
......@@ -380,8 +450,8 @@ class Processor():
if self.__verbose:
sys.stdout.write("csback2cron: " + self.crontabfile + " written.\n")
DEFAULTS = {'logging': 'yes', 'recursive': 'yes', 'followlinks': 'false', \
'tolerant': 'no', 'test': 'yes'}
DEFAULTS = {'logging': 'yes', 'recursive': 'yes', 'followlinks': 'no', \
'tolerant': 'no', 'test': 'yes', 'copy': 'no'}
# -----------------------------------------------------------------------------
def main(argv=None):
......
......@@ -145,8 +145,8 @@
# targetdir Directory path to backup data.
# exclude Pattern rule to exclude files from copying. Comma seperated
# followed by a whitespace.
# specialcommands Special rsync command which will be appended as well. Rsync
# option -q always is enabled.
# specialcommands Special rsync commands which will be appended as well. Rsync
# option '-q' always is enabled.
#
# Backups:
# -------
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment