From 94788714a2867ebc2fcc5b80ba8a0939dcb9aa48 Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Mon, 25 Jun 2012 14:36:33 -0400 Subject: unified [Single]XMLFileBacked, enabled xinclude pretty much everywhere --- src/lib/Bcfg2/Server/FileMonitor/__init__.py | 4 +- src/lib/Bcfg2/Server/Plugin.py | 72 ++++++++-------------- src/lib/Bcfg2/Server/Plugins/Bundler.py | 5 +- src/lib/Bcfg2/Server/Plugins/FileProbes.py | 14 ++--- src/lib/Bcfg2/Server/Plugins/GroupPatterns.py | 13 ++-- src/lib/Bcfg2/Server/Plugins/Metadata.py | 9 ++- src/lib/Bcfg2/Server/Plugins/NagiosGen.py | 17 ++--- .../Server/Plugins/Packages/PackagesSources.py | 13 ++-- src/lib/Bcfg2/Server/Plugins/Properties.py | 3 - src/lib/Bcfg2/Server/Plugins/PuppetENC.py | 3 - 10 files changed, 53 insertions(+), 100 deletions(-) (limited to 'src/lib/Bcfg2/Server') diff --git a/src/lib/Bcfg2/Server/FileMonitor/__init__.py b/src/lib/Bcfg2/Server/FileMonitor/__init__.py index 74b3b1560..8bd63e18d 100644 --- a/src/lib/Bcfg2/Server/FileMonitor/__init__.py +++ b/src/lib/Bcfg2/Server/FileMonitor/__init__.py @@ -77,8 +77,8 @@ class FileMonitor(object): self.handles[event.requestID].HandleEvent(event) except: err = sys.exc_info()[1] - logger.error("Error in handling of event for %s: %s" % - (event.filename, err)) + logger.error("Error in handling of event %s for %s: %s" % + (event.code2str(), event.filename, err)) def handle_event_set(self, lock=None): count = 1 diff --git a/src/lib/Bcfg2/Server/Plugin.py b/src/lib/Bcfg2/Server/Plugin.py index 8185edab1..98e6e6f51 100644 --- a/src/lib/Bcfg2/Server/Plugin.py +++ b/src/lib/Bcfg2/Server/Plugin.py @@ -395,10 +395,11 @@ class FileBacked(object): This object is meant to be used as a part of DirectoryBacked. """ - def __init__(self, name): + def __init__(self, name, fam=None): object.__init__(self) self.data = '' self.name = name + self.fam = fam def HandleEvent(self, event=None): """Read file upon update.""" @@ -416,10 +417,7 @@ class FileBacked(object): pass def __repr__(self): - return "%s: %s" % (self.__class__.__name__, str(self)) - - def __str__(self): - return "%s: %s" % (self.name, self.data) + return "%s: %s" % (self.__class__.__name__, self.name) class DirectoryBacked(object): @@ -487,7 +485,8 @@ class DirectoryBacked(object): added. """ self.entries[relative] = self.__child__(os.path.join(self.data, - relative)) + relative), + self.fam) self.entries[relative].HandleEvent(event) def HandleEvent(self, event): @@ -589,43 +588,18 @@ class XMLFileBacked(FileBacked): """ __identifier__ = 'name' - def __init__(self, filename): - self.label = "dummy" - self.entries = [] + def __init__(self, filename, fam=None, should_monitor=False): FileBacked.__init__(self, filename) - - def Index(self): - """Build local data structures.""" - try: - self.xdata = lxml.etree.XML(self.data, - parser=Bcfg2.Server.XMLParser) - except lxml.etree.XMLSyntaxError: - logger.error("Failed to parse %s" % (self.name)) - return - self.entries = self.xdata.getchildren() - if self.__identifier__ is not None: - self.label = self.xdata.attrib[self.__identifier__] - - def __iter__(self): - return iter(self.entries) - - def __str__(self): - return "%s at %s" % (self.__class__.__name__, self.name) - - -class SingleXMLFileBacked(XMLFileBacked): - """This object is a coherent cache for an independent XML file.""" - def __init__(self, filename, fam, should_monitor=True): - XMLFileBacked.__init__(self, filename) + self.label = "" + self.entries = [] self.extras = [] self.fam = fam self.should_monitor = should_monitor - if should_monitor: + if fam and should_monitor: self.fam.AddMonitor(filename, self) def _follow_xincludes(self, fname=None, xdata=None): - ''' follow xincludes, adding included files to fam and to - self.extras ''' + ''' follow xincludes, adding included files to self.extras ''' if xdata is None: if fname is None: xdata = self.xdata.getroottree() @@ -639,13 +613,8 @@ class SingleXMLFileBacked(XMLFileBacked): fpath = name else: fpath = os.path.join(os.path.dirname(self.name), name) - self.add_monitor(fpath, name) self._follow_xincludes(fname=fpath) - - def add_monitor(self, fpath, fname): - if self.should_monitor: - self.fam.AddMonitor(fpath, self) - self.extras.append(fname) + self.add_monitor(fpath, name) def Index(self): """Build local data structures.""" @@ -669,14 +638,22 @@ class SingleXMLFileBacked(XMLFileBacked): if self.__identifier__ is not None: self.label = self.xdata.attrib[self.__identifier__] + def add_monitor(self, fpath, fname): + self.extras.append(fname) + if self.fam: + self.fam.AddMonitor(fpath, self) + + def __iter__(self): + return iter(self.entries) + + def __str__(self): + return "%s at %s" % (self.__class__.__name__, self.name) + class StructFile(XMLFileBacked): """This file contains a set of structure file formatting logic.""" __identifier__ = None - def __init__(self, name): - XMLFileBacked.__init__(self, name) - def _include_element(self, item, metadata): """ determine if an XML element matches the metadata """ if item.tag == 'Group': @@ -827,8 +804,8 @@ class XMLSrc(XMLFileBacked): __node__ = INode __cacheobj__ = dict - def __init__(self, filename, noprio=False): - XMLFileBacked.__init__(self, filename) + def __init__(self, filename, fam=None, should_monitor=False, noprio=False): + XMLFileBacked.__init__(self, filename, fam, should_monitor) self.items = {} self.cache = None self.pnode = None @@ -880,6 +857,7 @@ class InfoXML(XMLSrc): class XMLDirectoryBacked(DirectoryBacked): """Directorybacked for *.xml.""" patterns = re.compile('.*\.xml') + __child__ = XMLFileBacked class PrioDir(Plugin, Generator, XMLDirectoryBacked): diff --git a/src/lib/Bcfg2/Server/Plugins/Bundler.py b/src/lib/Bcfg2/Server/Plugins/Bundler.py index 6289439c6..a7b5dccde 100644 --- a/src/lib/Bcfg2/Server/Plugins/Bundler.py +++ b/src/lib/Bcfg2/Server/Plugins/Bundler.py @@ -19,7 +19,6 @@ except: class BundleFile(Bcfg2.Server.Plugin.StructFile): - def get_xml_value(self, metadata): bundlename = os.path.splitext(os.path.basename(self.name))[0] bundle = lxml.etree.Element('Bundle', name=bundlename) @@ -50,7 +49,7 @@ class Bundler(Bcfg2.Server.Plugin.Plugin, self.logger.error("Failed to load Bundle repository") raise Bcfg2.Server.Plugin.PluginInitError - def template_dispatch(self, name): + def template_dispatch(self, name, _): bundle = lxml.etree.parse(name, parser=Bcfg2.Server.XMLParser) nsmap = bundle.getroot().nsmap @@ -63,7 +62,7 @@ class Bundler(Bcfg2.Server.Plugin.Plugin, else: raise Bcfg2.Server.Plugin.PluginExecutionError("Genshi not available: %s" % name) else: - return BundleFile(name) + return BundleFile(name, self.fam) def BuildStructures(self, metadata): """Build all structures for client (metadata).""" diff --git a/src/lib/Bcfg2/Server/Plugins/FileProbes.py b/src/lib/Bcfg2/Server/Plugins/FileProbes.py index 556965fca..f95c05d42 100644 --- a/src/lib/Bcfg2/Server/Plugins/FileProbes.py +++ b/src/lib/Bcfg2/Server/Plugins/FileProbes.py @@ -37,14 +37,6 @@ data.text = binascii.b2a_base64(open(path).read()) print lxml.etree.tostring(data) """ -class FileProbesConfig(Bcfg2.Server.Plugin.SingleXMLFileBacked, - Bcfg2.Server.Plugin.StructFile): - """ Config file handler for FileProbes """ - def __init__(self, filename, fam): - Bcfg2.Server.Plugin.SingleXMLFileBacked.__init__(self, filename, fam) - Bcfg2.Server.Plugin.StructFile.__init__(self, filename) - - class FileProbes(Bcfg2.Server.Plugin.Plugin, Bcfg2.Server.Plugin.Probing): """ This module allows you to probe a client for a file, which is then @@ -60,8 +52,10 @@ class FileProbes(Bcfg2.Server.Plugin.Plugin, def __init__(self, core, datastore): Bcfg2.Server.Plugin.Plugin.__init__(self, core, datastore) Bcfg2.Server.Plugin.Probing.__init__(self) - self.config = FileProbesConfig(os.path.join(self.data, 'config.xml'), - core.fam) + self.config = Bcfg2.Server.Plugin.StructFile(os.path.join(self.data, + 'config.xml'), + fam=core.fam, + should_monitor=True) self.entries = dict() self.probes = dict() diff --git a/src/lib/Bcfg2/Server/Plugins/GroupPatterns.py b/src/lib/Bcfg2/Server/Plugins/GroupPatterns.py index e883143ec..bea3baee3 100644 --- a/src/lib/Bcfg2/Server/Plugins/GroupPatterns.py +++ b/src/lib/Bcfg2/Server/Plugins/GroupPatterns.py @@ -73,16 +73,17 @@ class PatternMap(object): return ret -class PatternFile(Bcfg2.Server.Plugin.SingleXMLFileBacked): +class PatternFile(Bcfg2.Server.Plugin.XMLFileBacked): __identifier__ = None - def __init__(self, filename, fam): - Bcfg2.Server.Plugin.SingleXMLFileBacked.__init__(self, filename, fam) + def __init__(self, filename, fam=None): + Bcfg2.Server.Plugin.XMLFileBacked.__init__(self, filename, fam=fam, + should_monitor=True) self.patterns = [] self.logger = logging.getLogger(self.__class__.__name__) def Index(self): - Bcfg2.Server.Plugin.SingleXMLFileBacked.Index(self) + Bcfg2.Server.Plugin.XMLFileBacked.Index(self) self.patterns = [] for entry in self.xdata.xpath('//GroupPattern'): try: @@ -119,8 +120,8 @@ class GroupPatterns(Bcfg2.Server.Plugin.Plugin, def __init__(self, core, datastore): Bcfg2.Server.Plugin.Plugin.__init__(self, core, datastore) Bcfg2.Server.Plugin.Connector.__init__(self) - self.config = PatternFile(self.data + '/config.xml', - core.fam) + self.config = PatternFile(os.path.join(self.data, 'config.xml'), + fam=core.fam) def get_additional_groups(self, metadata): return self.config.process_patterns(metadata.hostname) diff --git a/src/lib/Bcfg2/Server/Plugins/Metadata.py b/src/lib/Bcfg2/Server/Plugins/Metadata.py index 50604f5cb..9786466bc 100644 --- a/src/lib/Bcfg2/Server/Plugins/Metadata.py +++ b/src/lib/Bcfg2/Server/Plugins/Metadata.py @@ -35,17 +35,16 @@ class MetadataRuntimeError(Exception): pass -class XMLMetadataConfig(Bcfg2.Server.Plugin.SingleXMLFileBacked): +class XMLMetadataConfig(Bcfg2.Server.Plugin.XMLFileBacked): """Handles xml config files and all XInclude statements""" def __init__(self, metadata, watch_clients, basefile): - # we tell SingleXMLFileBacked _not_ to add a monitor for this + # we tell XMLFileBacked _not_ to add a monitor for this # file, because the main Metadata plugin has already added # one. then we immediately set should_monitor to the proper # value, so that XIinclude'd files get properly watched fpath = os.path.join(metadata.data, basefile) - Bcfg2.Server.Plugin.SingleXMLFileBacked.__init__(self, fpath, - metadata.core.fam, - should_monitor=False) + Bcfg2.Server.Plugin.XMLFileBacked.__init__(self, fpath, + fam=metadata.core.fam) self.should_monitor = watch_clients self.metadata = metadata self.fam = metadata.core.fam diff --git a/src/lib/Bcfg2/Server/Plugins/NagiosGen.py b/src/lib/Bcfg2/Server/Plugins/NagiosGen.py index 4e8b09f30..f2b8336e0 100644 --- a/src/lib/Bcfg2/Server/Plugins/NagiosGen.py +++ b/src/lib/Bcfg2/Server/Plugins/NagiosGen.py @@ -14,25 +14,16 @@ LOGGER = logging.getLogger('Bcfg2.Plugins.NagiosGen') line_fmt = '\t%-32s %s' -class NagiosGenConfig(Bcfg2.Server.Plugin.SingleXMLFileBacked, - Bcfg2.Server.Plugin.StructFile): +class NagiosGenConfig(Bcfg2.Server.Plugin.StructFile): def __init__(self, filename, fam): # create config.xml if missing if not os.path.exists(filename): LOGGER.warning("NagiosGen: %s missing. " "Creating empty one for you." % filename) - f = open(filename, "w") - f.write("") - f.close() + open(filename, "w").write("") - try: - Bcfg2.Server.Plugin.SingleXMLFileBacked.__init__(self, - filename, - fam) - except OSError: - LOGGER.error("NagiosGen: Failed to read configuration file: %s" % err) - raise Bcfg2.Server.Plugin.PluginInitError(msg) - Bcfg2.Server.Plugin.StructFile.__init__(self, filename) + Bcfg2.Server.Plugin.StructFile.__init__(self, filename, fam=fam, + should_monitor=True) class NagiosGen(Bcfg2.Server.Plugin.Plugin, diff --git a/src/lib/Bcfg2/Server/Plugins/Packages/PackagesSources.py b/src/lib/Bcfg2/Server/Plugins/Packages/PackagesSources.py index e2af287db..3ca96c0a4 100644 --- a/src/lib/Bcfg2/Server/Plugins/Packages/PackagesSources.py +++ b/src/lib/Bcfg2/Server/Plugins/Packages/PackagesSources.py @@ -4,17 +4,15 @@ import lxml.etree import Bcfg2.Server.Plugin from Bcfg2.Server.Plugins.Packages.Source import SourceInitError -class PackagesSources(Bcfg2.Server.Plugin.SingleXMLFileBacked, - Bcfg2.Server.Plugin.StructFile, +class PackagesSources(Bcfg2.Server.Plugin.StructFile, Bcfg2.Server.Plugin.Debuggable): __identifier__ = None def __init__(self, filename, cachepath, fam, packages, setup): Bcfg2.Server.Plugin.Debuggable.__init__(self) try: - Bcfg2.Server.Plugin.SingleXMLFileBacked.__init__(self, - filename, - fam) + Bcfg2.Server.Plugin.StructFile.__init__(self, filename, fam=fam, + should_monitor=True) except OSError: err = sys.exc_info()[1] msg = "Packages: Failed to read configuration file: %s" % err @@ -22,7 +20,6 @@ class PackagesSources(Bcfg2.Server.Plugin.SingleXMLFileBacked, msg += " Have you created it?" self.logger.error(msg) raise Bcfg2.Server.Plugin.PluginInitError(msg) - Bcfg2.Server.Plugin.StructFile.__init__(self, filename) self.cachepath = cachepath self.setup = setup if not os.path.exists(self.cachepath): @@ -42,7 +39,7 @@ class PackagesSources(Bcfg2.Server.Plugin.SingleXMLFileBacked, source.toggle_debug() def HandleEvent(self, event=None): - Bcfg2.Server.Plugin.SingleXMLFileBacked.HandleEvent(self, event=event) + Bcfg2.Server.Plugin.XMLFileBacked.HandleEvent(self, event=event) if event and event.filename != self.name: for fname in self.extras: fpath = None @@ -65,7 +62,7 @@ class PackagesSources(Bcfg2.Server.Plugin.SingleXMLFileBacked, return sorted(list(self.parsed)) == sorted(self.extras) def Index(self): - Bcfg2.Server.Plugin.SingleXMLFileBacked.Index(self) + Bcfg2.Server.Plugin.XMLFileBacked.Index(self) self.entries = [] for xsource in self.xdata.findall('.//Source'): source = self.source_from_xml(xsource) diff --git a/src/lib/Bcfg2/Server/Plugins/Properties.py b/src/lib/Bcfg2/Server/Plugins/Properties.py index 6d1c21328..a879b064f 100644 --- a/src/lib/Bcfg2/Server/Plugins/Properties.py +++ b/src/lib/Bcfg2/Server/Plugins/Properties.py @@ -26,9 +26,6 @@ def passphrases(): class PropertyFile(Bcfg2.Server.Plugin.StructFile): """Class for properties files.""" - def __init__(self, name): - Bcfg2.Server.Plugin.StructFile.__init__(self, name) - def write(self): """ Write the data in this data structure back to the property file """ diff --git a/src/lib/Bcfg2/Server/Plugins/PuppetENC.py b/src/lib/Bcfg2/Server/Plugins/PuppetENC.py index c75c0b076..46182e9a2 100644 --- a/src/lib/Bcfg2/Server/Plugins/PuppetENC.py +++ b/src/lib/Bcfg2/Server/Plugins/PuppetENC.py @@ -15,9 +15,6 @@ class PuppetENCFile(Bcfg2.Server.Plugin.FileBacked): def HandleEvent(self, event=None): return - def __str__(self): - return "%s: %s" % (self.__class__.__name__, self.name) - class PuppetENC(Bcfg2.Server.Plugin.Plugin, Bcfg2.Server.Plugin.Connector, -- cgit v1.2.3-1-g7c22