From dd28e90f183972cc2a395094ce3e3f72e861953f Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Fri, 21 Sep 2012 13:55:05 -0400 Subject: run pylint for errors on almost everything, full runs on some selected stuff --- .../Server/Plugins/Cfg/CfgCheetahGenerator.py | 13 ++- src/lib/Bcfg2/Server/Plugins/Cfg/CfgDiffFilter.py | 14 +-- .../Plugins/Cfg/CfgEncryptedGenshiGenerator.py | 2 +- .../Plugins/Cfg/CfgExternalCommandVerifier.py | 11 ++- .../Bcfg2/Server/Plugins/Cfg/CfgGenshiGenerator.py | 107 +++++++++++---------- src/lib/Bcfg2/Server/Plugins/Cfg/CfgInfoXML.py | 5 +- src/lib/Bcfg2/Server/Plugins/Cfg/CfgLegacyInfo.py | 11 ++- src/lib/Bcfg2/Server/Plugins/Cfg/__init__.py | 97 ++++++++++--------- 8 files changed, 144 insertions(+), 116 deletions(-) (limited to 'src/lib/Bcfg2/Server/Plugins/Cfg') diff --git a/src/lib/Bcfg2/Server/Plugins/Cfg/CfgCheetahGenerator.py b/src/lib/Bcfg2/Server/Plugins/Cfg/CfgCheetahGenerator.py index a0e999847..7f02d4a05 100644 --- a/src/lib/Bcfg2/Server/Plugins/Cfg/CfgCheetahGenerator.py +++ b/src/lib/Bcfg2/Server/Plugins/Cfg/CfgCheetahGenerator.py @@ -2,18 +2,17 @@ `_ templating system to generate :ref:`server-plugins-generators-cfg` files. """ -import copy import logging import Bcfg2.Server.Plugin from Bcfg2.Server.Plugins.Cfg import CfgGenerator -logger = logging.getLogger(__name__) +LOGGER = logging.getLogger(__name__) try: from Cheetah.Template import Template - have_cheetah = True + HAS_CHEETAH = True except ImportError: - have_cheetah = False + HAS_CHEETAH = False class CfgCheetahGenerator(CfgGenerator): @@ -29,9 +28,9 @@ class CfgCheetahGenerator(CfgGenerator): def __init__(self, fname, spec, encoding): CfgGenerator.__init__(self, fname, spec, encoding) - if not have_cheetah: - msg = "Cfg: Cheetah is not available: %s" % entry.get("name") - logger.error(msg) + if not HAS_CHEETAH: + msg = "Cfg: Cheetah is not available: %s" % self.name + LOGGER.error(msg) raise Bcfg2.Server.Plugin.PluginExecutionError(msg) __init__.__doc__ = CfgGenerator.__init__.__doc__ diff --git a/src/lib/Bcfg2/Server/Plugins/Cfg/CfgDiffFilter.py b/src/lib/Bcfg2/Server/Plugins/Cfg/CfgDiffFilter.py index 409d2cbf6..00b95c970 100644 --- a/src/lib/Bcfg2/Server/Plugins/Cfg/CfgDiffFilter.py +++ b/src/lib/Bcfg2/Server/Plugins/Cfg/CfgDiffFilter.py @@ -7,7 +7,8 @@ import Bcfg2.Server.Plugin from subprocess import Popen, PIPE from Bcfg2.Server.Plugins.Cfg import CfgFilter -logger = logging.getLogger(__name__) +LOGGER = logging.getLogger(__name__) + class CfgDiffFilter(CfgFilter): """ CfgDiffFilter applies diffs to plaintext @@ -24,14 +25,15 @@ class CfgDiffFilter(CfgFilter): open(basename, 'w').write(data) os.close(basehandle) - cmd = ["patch", "-u", "-f", basefile.name] + cmd = ["patch", "-u", "-f", basename] patch = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE) stderr = patch.communicate(input=self.data)[1] ret = patch.wait() - output = open(basefile.name, 'r').read() - os.unlink(basefile.name) + output = open(basename, 'r').read() + os.unlink(basename) if ret != 0: - logger.error("Error applying diff %s: %s" % (delta.name, stderr)) - raise Bcfg2.Server.Plugin.PluginExecutionError('delta', delta) + msg = "Error applying diff %s: %s" % (self.name, stderr) + LOGGER.error(msg) + raise Bcfg2.Server.Plugin.PluginExecutionError(msg) return output modify_data.__doc__ = CfgFilter.modify_data.__doc__ diff --git a/src/lib/Bcfg2/Server/Plugins/Cfg/CfgEncryptedGenshiGenerator.py b/src/lib/Bcfg2/Server/Plugins/Cfg/CfgEncryptedGenshiGenerator.py index 6fd70e69f..31c3d79b0 100644 --- a/src/lib/Bcfg2/Server/Plugins/Cfg/CfgEncryptedGenshiGenerator.py +++ b/src/lib/Bcfg2/Server/Plugins/Cfg/CfgEncryptedGenshiGenerator.py @@ -17,7 +17,7 @@ try: from genshi.template import TemplateLoader except ImportError: # CfgGenshiGenerator will raise errors if genshi doesn't exist - TemplateLoader = object + TemplateLoader = object # pylint: disable=C0103 LOGGER = logging.getLogger(__name__) diff --git a/src/lib/Bcfg2/Server/Plugins/Cfg/CfgExternalCommandVerifier.py b/src/lib/Bcfg2/Server/Plugins/Cfg/CfgExternalCommandVerifier.py index 87e11ab6d..fb66ca8bf 100644 --- a/src/lib/Bcfg2/Server/Plugins/Cfg/CfgExternalCommandVerifier.py +++ b/src/lib/Bcfg2/Server/Plugins/Cfg/CfgExternalCommandVerifier.py @@ -7,7 +7,8 @@ import Bcfg2.Server.Plugin from subprocess import Popen, PIPE from Bcfg2.Server.Plugins.Cfg import CfgVerifier, CfgVerificationError -logger = logging.getLogger(__name__) +LOGGER = logging.getLogger(__name__) + class CfgExternalCommandVerifier(CfgVerifier): """ Invoke an external script to verify @@ -16,6 +17,11 @@ class CfgExternalCommandVerifier(CfgVerifier): #: Handle :file:`:test` files __basenames__ = [':test'] + def __init__(self, name, specific, encoding): + CfgVerifier.__init__(self, name, specific, encoding) + self.cmd = [] + __init__.__doc__ = CfgVerifier.__init__.__doc__ + def verify_entry(self, entry, metadata, data): proc = Popen(self.cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE) err = proc.communicate(input=data)[1] @@ -34,8 +40,7 @@ class CfgExternalCommandVerifier(CfgVerifier): self.cmd.extend(shlex.split(bangpath[2:].strip())) else: msg = "Cannot execute %s" % self.name - logger.error(msg) + LOGGER.error(msg) raise Bcfg2.Server.Plugin.PluginExecutionError(msg) self.cmd.append(self.name) handle_event.__doc__ = CfgVerifier.handle_event.__doc__ - diff --git a/src/lib/Bcfg2/Server/Plugins/Cfg/CfgGenshiGenerator.py b/src/lib/Bcfg2/Server/Plugins/Cfg/CfgGenshiGenerator.py index dc128bbe9..21662a984 100644 --- a/src/lib/Bcfg2/Server/Plugins/Cfg/CfgGenshiGenerator.py +++ b/src/lib/Bcfg2/Server/Plugins/Cfg/CfgGenshiGenerator.py @@ -9,16 +9,17 @@ import traceback import Bcfg2.Server.Plugin from Bcfg2.Server.Plugins.Cfg import CfgGenerator -logger = logging.getLogger(__name__) +LOGGER = logging.getLogger(__name__) try: import genshi.core from genshi.template import TemplateLoader, NewTextTemplate from genshi.template.eval import UndefinedError - have_genshi = True + HAS_GENSHI = True except ImportError: - TemplateLoader = None - have_genshi = False + TemplateLoader = None # pylint: disable=C0103 + HAS_GENSHI = False + def removecomment(stream): """ A Genshi filter that removes comments from the stream. This @@ -42,7 +43,7 @@ class CfgGenshiGenerator(CfgGenerator): #: Handle .genshi files __extensions__ = ['genshi'] - + #: ``__loader_cls__`` is the class that will be instantiated to #: load the template files. It must implement one public function, #: ``load()``, as :class:`genshi.template.TemplateLoader`. @@ -61,9 +62,9 @@ class CfgGenshiGenerator(CfgGenerator): def __init__(self, fname, spec, encoding): CfgGenerator.__init__(self, fname, spec, encoding) - if not have_genshi: + if not HAS_GENSHI: msg = "Cfg: Genshi is not available: %s" % fname - logger.error(msg) + LOGGER.error(msg) raise Bcfg2.Server.Plugin.PluginExecutionError(msg) self.loader = self.__loader_cls__() self.template = None @@ -87,55 +88,59 @@ class CfgGenshiGenerator(CfgGenerator): stack = traceback.extract_tb(sys.exc_info()[2]) for quad in stack: if quad[0] == self.name: - logger.error("Cfg: Error rendering %s at '%s': %s: %s" % + LOGGER.error("Cfg: Error rendering %s at '%s': %s: %s" % (fname, quad[2], err.__class__.__name__, err)) break raise except: - # a failure in a %{ python ... %} block -- the snippet in - # the traceback is just the beginning of the block. - err = sys.exc_info()[1] - stack = traceback.extract_tb(sys.exc_info()[2]) - (filename, lineno, func, text) = stack[-1] - # this is horrible, and I deeply apologize to whoever gets - # to maintain this after I go to the Great Beer Garden in - # the Sky. genshi is incredibly opaque about what's being - # executed, so the only way I can find to determine which - # {% python %} block is being executed -- if there are - # multiples -- is to iterate through them and match the - # snippet of the first line that's in the traceback with - # the first non-empty line of the block. - execs = [contents - for etype, contents, loc in self.template.stream - if etype == self.template.EXEC] - contents = None - if len(execs) == 1: - contents = execs[0] - elif len(execs) > 1: - match = pyerror_re.match(func) - if match: - firstline = match.group(0) - for pyblock in execs: - if pyblock.startswith(firstline): - contents = pyblock - break - # else, no EXEC blocks -- WTF? - if contents: - # we now have the bogus block, but we need to get the - # offending line. To get there, we do (line number - # given in the exception) - (firstlineno from the - # internal genshi code object of the snippet) + 1 = - # (line number of the line with an error within the - # block, with all multiple line breaks elided to a - # single line break) - real_lineno = lineno - contents.code.co_firstlineno - src = re.sub(r'\n\n+', '\n', contents.source).splitlines() - logger.error("Cfg: Error rendering %s at '%s': %s: %s" % - (fname, src[real_lineno], err.__class__.__name__, - err)) - raise + self._handle_genshi_exception(fname, sys.exc_info()) get_data.__doc__ = CfgGenerator.get_data.__doc__ + def _handle_genshi_exception(self, fname, exc): + """ this is horrible, and I deeply apologize to whoever gets + to maintain this after I go to the Great Beer Garden in the + Sky. genshi is incredibly opaque about what's being executed, + so the only way I can find to determine which {% python %} + block is being executed -- if there are multiples -- is to + iterate through them and match the snippet of the first line + that's in the traceback with the first non-empty line of the + block. """ + + # a failure in a %{ python ... %} block -- the snippet in + # the traceback is just the beginning of the block. + err = [1] + stack = traceback.extract_tb(exc[2]) + lineno, func = stack[-1][1:3] + execs = [contents + for etype, contents in self.template.stream[:2] + if etype == self.template.EXEC] + contents = None + if len(execs) == 1: + contents = execs[0] + elif len(execs) > 1: + match = self.pyerror_re.match(func) + if match: + firstline = match.group(0) + for pyblock in execs: + if pyblock.startswith(firstline): + contents = pyblock + break + # else, no EXEC blocks -- WTF? + if contents: + # we now have the bogus block, but we need to get the + # offending line. To get there, we do (line number + # given in the exception) - (firstlineno from the + # internal genshi code object of the snippet) + 1 = + # (line number of the line with an error within the + # block, with all multiple line breaks elided to a + # single line break) + real_lineno = lineno - contents.code.co_firstlineno + src = re.sub(r'\n\n+', '\n', contents.source).splitlines() + LOGGER.error("Cfg: Error rendering %s at '%s': %s: %s" % + (fname, src[real_lineno], err.__class__.__name__, + err)) + raise + def handle_event(self, event): if event.code2str() == 'deleted': return @@ -146,6 +151,6 @@ class CfgGenshiGenerator(CfgGenerator): except Exception: msg = "Cfg: Could not load template %s: %s" % (self.name, sys.exc_info()[1]) - logger.error(msg) + LOGGER.error(msg) raise Bcfg2.Server.Plugin.PluginExecutionError(msg) handle_event.__doc__ = CfgGenerator.handle_event.__doc__ diff --git a/src/lib/Bcfg2/Server/Plugins/Cfg/CfgInfoXML.py b/src/lib/Bcfg2/Server/Plugins/Cfg/CfgInfoXML.py index 472a7dba3..2396d6eb6 100644 --- a/src/lib/Bcfg2/Server/Plugins/Cfg/CfgInfoXML.py +++ b/src/lib/Bcfg2/Server/Plugins/Cfg/CfgInfoXML.py @@ -4,7 +4,8 @@ import logging import Bcfg2.Server.Plugin from Bcfg2.Server.Plugins.Cfg import CfgInfo -logger = logging.getLogger(__name__) +LOGGER = logging.getLogger(__name__) + class CfgInfoXML(CfgInfo): """ CfgInfoXML handles :file:`info.xml` files for @@ -22,7 +23,7 @@ class CfgInfoXML(CfgInfo): mdata = dict() self.infoxml.pnode.Match(metadata, mdata, entry=entry) if 'Info' not in mdata: - logger.error("Failed to set metadata for file %s" % + LOGGER.error("Failed to set metadata for file %s" % entry.get('name')) raise Bcfg2.Server.Plugin.PluginExecutionError self._set_info(entry, mdata['Info'][None]) diff --git a/src/lib/Bcfg2/Server/Plugins/Cfg/CfgLegacyInfo.py b/src/lib/Bcfg2/Server/Plugins/Cfg/CfgLegacyInfo.py index a47663904..8f71c45c8 100644 --- a/src/lib/Bcfg2/Server/Plugins/Cfg/CfgLegacyInfo.py +++ b/src/lib/Bcfg2/Server/Plugins/Cfg/CfgLegacyInfo.py @@ -4,7 +4,8 @@ import logging import Bcfg2.Server.Plugin from Bcfg2.Server.Plugins.Cfg import CfgInfo -logger = logging.getLogger(__name__) +LOGGER = logging.getLogger(__name__) + class CfgLegacyInfo(CfgInfo): """ CfgLegacyInfo handles :file:`info` and :file:`:info` files for @@ -20,6 +21,9 @@ class CfgLegacyInfo(CfgInfo): def __init__(self, path): CfgInfo.__init__(self, path) self.path = path + + #: The set of info metadata stored in the file + self.metadata = None __init__.__doc__ = CfgInfo.__init__.__doc__ def bind_info_to_entry(self, entry, metadata): @@ -30,9 +34,10 @@ class CfgLegacyInfo(CfgInfo): if event.code2str() == 'deleted': return for line in open(self.path).readlines(): - match = Bcfg2.Server.Plugin.info_regex.match(line) + match = Bcfg2.Server.Plugin.INFO_REGEX.match(line) if not match: - logger.warning("Failed to parse line in %s: %s" % (fpath, line)) + LOGGER.warning("Failed to parse line in %s: %s" % + (event.filename, line)) continue else: self.metadata = \ diff --git a/src/lib/Bcfg2/Server/Plugins/Cfg/__init__.py b/src/lib/Bcfg2/Server/Plugins/Cfg/__init__.py index e2832cd26..c34cad30e 100644 --- a/src/lib/Bcfg2/Server/Plugins/Cfg/__init__.py +++ b/src/lib/Bcfg2/Server/Plugins/Cfg/__init__.py @@ -8,10 +8,12 @@ import logging import lxml.etree import Bcfg2.Options import Bcfg2.Server.Plugin -from Bcfg2.Compat import u_str, unicode, b64encode, walk_packages import Bcfg2.Server.Lint +# pylint: disable=W0622 +from Bcfg2.Compat import u_str, unicode, b64encode, walk_packages +# pylint: enable=W0622 -logger = logging.getLogger(__name__) +LOGGER = logging.getLogger(__name__) #: SETUP contains a reference to the #: :class:`Bcfg2.Options.OptionParser` created by the Bcfg2 core for @@ -24,6 +26,7 @@ logger = logging.getLogger(__name__) #: the EntrySet children. SETUP = None + class CfgBaseFileMatcher(Bcfg2.Server.Plugin.SpecificData): """ CfgBaseFileMatcher is the parent class for all Cfg handler objects. """ @@ -93,12 +96,13 @@ class CfgBaseFileMatcher(Bcfg2.Server.Plugin.SpecificData): components = ['^(?P%s)' % basename] if cls.__specific__: - components.append('(|\\.H_(?P\S+?)|.G(?P\d+)_(?P\S+?))') + components.append('(|\\.H_(?P\S+?)|' + + '.G(?P\d+)_(?P\S+?))') if extensions: components.append('\\.(?P%s)' % '|'.join(extensions)) components.append('$') return re.compile("".join(components)) - + @classmethod def handles(cls, event, basename=None): """ Return True if this handler handles the file described by @@ -129,7 +133,8 @@ class CfgBaseFileMatcher(Bcfg2.Server.Plugin.SpecificData): match = True break return (match and - cls.get_regex(basename=os.path.basename(basename)).match(event.filename)) + cls.get_regex( + basename=os.path.basename(basename)).match(event.filename)) @classmethod def ignore(cls, event, basename=None): @@ -166,13 +171,10 @@ class CfgBaseFileMatcher(Bcfg2.Server.Plugin.SpecificData): return (match and cls.get_regex(basename=os.path.basename(basename), extensions=cls.__ignore__).match(event.filename)) - + def __str__(self): return "%s(%s)" % (self.__class__.__name__, self.name) - def match(self, fname): - return self.regex.match(fname) - class CfgGenerator(CfgBaseFileMatcher): """ CfgGenerators generate the initial content of a file. Every @@ -193,7 +195,7 @@ class CfgGenerator(CfgBaseFileMatcher): CfgBaseFileMatcher.__init__(self, name, specific, encoding) __init__.__doc__ = CfgBaseFileMatcher.__init__.__doc__.split(".. -----")[0] - def get_data(self, entry, metadata): + def get_data(self, entry, metadata): # pylint: disable=W0613 """ get_data() returns the initial data of a file. :param entry: The entry to generate data for. ``entry`` should @@ -335,13 +337,17 @@ class CfgDefaultInfo(CfgInfo): bind_info_to_entry.__doc__ = CfgInfo.bind_info_to_entry.__doc__ #: A :class:`CfgDefaultInfo` object instantiated with -#: :attr:`Bcfg2.Server.Plugin.helper.default_file_metadata` as its +#: :attr:`Bcfg2.Server.Plugin.helper.DEFAULT_FILE_METADATA` as its #: default metadata. This is used to set a default file metadata set #: on an entry before a "real" :class:`CfgInfo` handler applies its #: metadata to the entry. -DEFAULT_INFO = CfgDefaultInfo(Bcfg2.Server.Plugin.default_file_metadata) +DEFAULT_INFO = CfgDefaultInfo(Bcfg2.Server.Plugin.DEFAULT_FILE_METADATA) + class CfgEntrySet(Bcfg2.Server.Plugin.EntrySet): + """ Handle a collection of host- and group-specific Cfg files with + multiple different Cfg handlers in a single directory. """ + def __init__(self, basename, path, entry_type, encoding): Bcfg2.Server.Plugin.EntrySet.__init__(self, basename, path, entry_type, encoding) @@ -377,18 +383,18 @@ class CfgEntrySet(Bcfg2.Server.Plugin.EntrySet): :returns: None """ action = event.code2str() - + if event.filename not in self.entries: if action not in ['exists', 'created', 'changed']: # process a bogus changed event like a created return - + for hdlr in self.handlers: if hdlr.handles(event, basename=self.path): if action == 'changed': # warn about a bogus 'changed' event, but # handle it like a 'created' - logger.warning("Got %s event for unknown file %s" % + LOGGER.warning("Got %s event for unknown file %s" % (action, event.filename)) self.debug_log("%s handling %s event on %s" % (hdlr.__name__, action, event.filename)) @@ -403,7 +409,7 @@ class CfgEntrySet(Bcfg2.Server.Plugin.EntrySet): del self.entries[event.filename] return - logger.error("Could not process event %s for %s; ignoring" % + LOGGER.error("Could not process event %s for %s; ignoring" % (action, event.filename)) def get_matching(self, metadata): @@ -412,7 +418,7 @@ class CfgEntrySet(Bcfg2.Server.Plugin.EntrySet): item.specific.matches(metadata))] get_matching.__doc__ = Bcfg2.Server.Plugin.EntrySet.get_matching.__doc__ - def entry_init(self, event, hdlr): + def entry_init(self, event, hdlr): # pylint: disable=W0221 """ Handle the creation of a file on the filesystem and the creation of a Cfg handler object in this CfgEntrySet to track it. @@ -432,13 +438,13 @@ class CfgEntrySet(Bcfg2.Server.Plugin.EntrySet): specific=hdlr.get_regex(os.path.basename(self.path))) else: if event.filename in self.entries: - logger.warn("Got duplicate add for %s" % event.filename) + LOGGER.warn("Got duplicate add for %s" % event.filename) else: fpath = os.path.join(self.path, event.filename) self.entries[event.filename] = hdlr(fpath) self.entries[event.filename].handle_event(event) - def bind_entry(self, entry, metadata): + def bind_entry(self, entry, metadata): # pylint: disable=R0912,R0915 info_handlers = [] generators = [] filters = [] @@ -459,12 +465,12 @@ class CfgEntrySet(Bcfg2.Server.Plugin.EntrySet): fdesc = "/".join(ent.__basenames__) elif ent.__extensions__: fdesc = "." + "/.".join(ent.__extensions__) - logger.warning("Cfg: %s: Use of %s files is deprecated" % + LOGGER.warning("Cfg: %s: Use of %s files is deprecated" % (ent.name, fdesc)) DEFAULT_INFO.bind_info_to_entry(entry, metadata) if len(info_handlers) > 1: - logger.error("More than one info supplier found for %s: %s" % + LOGGER.error("More than one info supplier found for %s: %s" % (entry.get("name"), info_handlers)) if len(info_handlers): info_handlers[0].bind_info_to_entry(entry, metadata) @@ -482,7 +488,7 @@ class CfgEntrySet(Bcfg2.Server.Plugin.EntrySet): except: msg = "Cfg: exception rendering %s with %s: %s" % \ (entry.get("name"), generator, sys.exc_info()[1]) - logger.error(msg) + LOGGER.error(msg) raise Bcfg2.Server.Plugin.PluginExecutionError(msg) for fltr in filters: @@ -506,9 +512,9 @@ class CfgEntrySet(Bcfg2.Server.Plugin.EntrySet): msg = "Data for %s for %s failed to verify: %s" % \ (entry.get('name'), metadata.hostname, sys.exc_info()[1]) - logger.error(msg) + LOGGER.error(msg) raise Bcfg2.Server.Plugin.PluginExecutionError(msg) - + if entry.get('encoding') == 'base64': data = b64encode(data) else: @@ -518,14 +524,14 @@ class CfgEntrySet(Bcfg2.Server.Plugin.EntrySet): except UnicodeDecodeError: msg = "Failed to decode %s: %s" % (entry.get('name'), sys.exc_info()[1]) - logger.error(msg) - logger.error("Please verify you are using the proper encoding.") + LOGGER.error(msg) + LOGGER.error("Please verify you are using the proper encoding") raise Bcfg2.Server.Plugin.PluginExecutionError(msg) except ValueError: msg = "Error in specification for %s: %s" % (entry.get('name'), sys.exc_info()[1]) - logger.error(msg) - logger.error("You need to specify base64 encoding for %s." % + LOGGER.error(msg) + LOGGER.error("You need to specify base64 encoding for %s." % entry.get('name')) raise Bcfg2.Server.Plugin.PluginExecutionError(msg) except TypeError: @@ -547,21 +553,23 @@ class CfgEntrySet(Bcfg2.Server.Plugin.EntrySet): ent.specific.matches(metadata))] if not generators: msg = "No base file found for %s" % entry.get('name') - logger.error(msg) + LOGGER.error(msg) raise Bcfg2.Server.Plugin.PluginExecutionError(msg) - + rv = [] try: best = self.best_matching(metadata, generators) rv.append(best.specific) - except: + except: # pylint: disable=W0702 pass if not rv or not rv[0].hostname: - rv.append(Bcfg2.Server.Plugin.Specificity(hostname=metadata.hostname)) + rv.append(Bcfg2.Server.Plugin.Specificity( + hostname=metadata.hostname)) return rv def build_filename(self, specific): + """ Create a filename for pulled file data """ bfname = self.path + '/' + self.path.split('/')[-1] if specific.all: return bfname @@ -571,22 +579,23 @@ class CfgEntrySet(Bcfg2.Server.Plugin.EntrySet): return "%s.H_%s" % (bfname, specific.hostname) def write_update(self, specific, new_entry, log): + """ Write pulled data to the filesystem """ if 'text' in new_entry: name = self.build_filename(specific) if os.path.exists("%s.genshi" % name): msg = "Cfg: Unable to pull data for genshi types" - logger.error(msg) + LOGGER.error(msg) raise Bcfg2.Server.Plugin.PluginExecutionError(msg) elif os.path.exists("%s.cheetah" % name): msg = "Cfg: Unable to pull data for cheetah types" - logger.error(msg) + LOGGER.error(msg) raise Bcfg2.Server.Plugin.PluginExecutionError(msg) try: etext = new_entry['text'].encode(self.encoding) except: - msg = "Cfg: Cannot encode content of %s as %s" % (name, - self.encoding) - logger.error(msg) + msg = "Cfg: Cannot encode content of %s as %s" % \ + (name, self.encoding) + LOGGER.error(msg) raise Bcfg2.Server.Plugin.PluginExecutionError(msg) open(name, 'w').write(etext) self.debug_log("Wrote file %s" % name, flag=log) @@ -597,7 +606,7 @@ class CfgEntrySet(Bcfg2.Server.Plugin.EntrySet): for ifile in ['info', ':info']: info = os.path.join(self.path, ifile) if os.path.exists(info): - logger.info("Removing %s and replacing with info.xml" % + LOGGER.info("Removing %s and replacing with info.xml" % info) os.remove(info) metadata_updates = {} @@ -606,8 +615,8 @@ class CfgEntrySet(Bcfg2.Server.Plugin.EntrySet): metadata_updates[attr] = new_entry.get(attr) infoxml = lxml.etree.Element('FileInfo') infotag = lxml.etree.SubElement(infoxml, 'Info') - [infotag.attrib.__setitem__(attr, metadata_updates[attr]) - for attr in metadata_updates] + for attr in metadata_updates: + infotag.attrib.__setitem__(attr, metadata_updates[attr]) ofile = open(self.path + "/info.xml", "w") ofile.write(lxml.etree.tostring(infoxml, xml_declaration=False, pretty_print=True).decode('UTF-8')) @@ -629,10 +638,10 @@ class Cfg(Bcfg2.Server.Plugin.GroupSpool, es_child_cls = Bcfg2.Server.Plugin.SpecificData def __init__(self, core, datastore): - global SETUP + global SETUP # pylint: disable=W0603 Bcfg2.Server.Plugin.GroupSpool.__init__(self, core, datastore) Bcfg2.Server.Plugin.PullTarget.__init__(self) - + SETUP = core.setup if 'validate' not in SETUP: SETUP.add_option('validate', Bcfg2.Options.CFG_VALIDATION) @@ -665,7 +674,8 @@ class Cfg(Bcfg2.Server.Plugin.GroupSpool, def AcceptChoices(self, entry, metadata): return self.entries[entry.get('name')].list_accept_choices(entry, metadata) - AcceptChoices.__doc__ = Bcfg2.Server.Plugin.PullTarget.AcceptChoices.__doc__ + AcceptChoices.__doc__ = \ + Bcfg2.Server.Plugin.PullTarget.AcceptChoices.__doc__ def AcceptPullData(self, specific, new_entry, log): return self.entries[new_entry.get('name')].write_update(specific, @@ -689,6 +699,7 @@ class CfgLint(Bcfg2.Server.Lint.ServerPlugin): "diff-file-used":"warning"} def check_entry(self, basename, entry): + """ check that no .cat or .diff files are in use """ cfg = self.core.plugins['Cfg'] for basename, entry in list(cfg.entries.items()): for fname, handler in entry.entries.items(): -- cgit v1.2.3-1-g7c22