From 8cba8ccce5be7094afd25037863f6819fa13ee7f Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Wed, 19 Sep 2012 13:36:55 -0400 Subject: documented PackagesSources --- .../Server/Plugins/Packages/PackagesSources.py | 94 +++++++++++++++++++--- 1 file changed, 82 insertions(+), 12 deletions(-) (limited to 'src/lib/Bcfg2/Server/Plugins/Packages/PackagesSources.py') diff --git a/src/lib/Bcfg2/Server/Plugins/Packages/PackagesSources.py b/src/lib/Bcfg2/Server/Plugins/Packages/PackagesSources.py index 0d565be31..329dfc394 100644 --- a/src/lib/Bcfg2/Server/Plugins/Packages/PackagesSources.py +++ b/src/lib/Bcfg2/Server/Plugins/Packages/PackagesSources.py @@ -1,14 +1,40 @@ import os import sys -import lxml.etree import Bcfg2.Server.Plugin from Bcfg2.Server.Plugins.Packages.Source import SourceInitError + class PackagesSources(Bcfg2.Server.Plugin.StructFile, Bcfg2.Server.Plugin.Debuggable): + """ PackagesSources handles parsing of the + :mod:`Bcfg2.Server.Plugins.Packages` ``sources.xml`` file, and the + creation of the appropriate + :class:`Bcfg2.Server.Plugins.Packages.Source.Source` object for + each ``Source`` tag. """ + __identifier__ = None def __init__(self, filename, cachepath, fam, packages, setup): + """ + :param filename: The full path to ``sources.xml`` + :type filename: string + :param cachepath: The full path to the directory where + :class:`Bcfg2.Server.Plugins.Packages.Source.Source` + data will be cached + :type cachepath: string + :param fam: The file access monitor to use to create watches + on ``sources.xml`` and any XIncluded files. + :type fam: Bcfg2.Server.FileMonitor.FileMonitor + :param packages: The Packages plugin object ``sources.xml`` is + being parsed on behalf of (i.e., the calling + object) + :type packages: Bcfg2.Server.Plugins.Packages.Packages + :param setup: A Bcfg2 options dict + :type setup: dict + + :raises: :class:`Bcfg2.Server.Plugin.exceptions.PluginInitError` - + If ``sources.xml`` cannot be read + """ Bcfg2.Server.Plugin.Debuggable.__init__(self) try: Bcfg2.Server.Plugin.StructFile.__init__(self, filename, fam=fam, @@ -16,12 +42,14 @@ class PackagesSources(Bcfg2.Server.Plugin.StructFile, except OSError: err = sys.exc_info()[1] msg = "Packages: Failed to read configuration file: %s" % err - if not os.path.exists(self.name): - msg += " Have you created it?" self.logger.error(msg) raise Bcfg2.Server.Plugin.PluginInitError(msg) + + #: The full path to the directory where + #: :class:`Bcfg2.Server.Plugins.Packages.Source.Source` data + #: will be cached self.cachepath = cachepath - self.setup = setup + if not os.path.exists(self.cachepath): # create cache directory if needed try: @@ -30,16 +58,38 @@ class PackagesSources(Bcfg2.Server.Plugin.StructFile, err = sys.exc_info()[1] self.logger.error("Could not create Packages cache at %s: %s" % (self.cachepath, err)) + #: The Bcfg2 options dict + self.setup = setup + + #: The :class:`Bcfg2.Server.Plugins.Packages.Packages` that + #: instantiated this ``PackagesSources`` object self.pkg_obj = packages + + #: The set of all XML files that have been successfully + #: parsed. This is used by :attr:`loaded` to determine if the + #: sources have been fully parsed and the + #: :class:`Bcfg2.Server.Plugins.Packages.Packages` plugin + #: should be told to reload its data. self.parsed = set() def toggle_debug(self): Bcfg2.Server.Plugin.Debuggable.toggle_debug(self) for source in self.entries: source.toggle_debug() + toggle_debug.__doc__ = Bcfg2.Server.Plugin.Plugin.toggle_debug.__doc__ def HandleEvent(self, event=None): - Bcfg2.Server.Plugin.XMLFileBacked.HandleEvent(self, event=event) + """ HandleEvent is called whenever the FAM registers an event. + + When :attr:`loaded` becomes True, + :func:`Bcfg2.Server.Plugins.Packages.Packages.Reload` is + called to reload all plugin data from the configured sources. + + :param event: The event object + :type event: Bcfg2.Server.FileMonitor.Event + :returns: None + """ + Bcfg2.Server.Plugin.StructFile.HandleEvent(self, event=event) if event and event.filename != self.name: for fpath in self.extras: if fpath == os.path.abspath(event.filename): @@ -52,23 +102,42 @@ class PackagesSources(Bcfg2.Server.Plugin.StructFile, @property def loaded(self): + """ Whether or not all XML files (``sources.xml`` and + everything XIncluded in it) have been parsed. This flag is + used to determine if the Packages plugin should be told to + load its data. """ return sorted(list(self.parsed)) == sorted(self.extras) def Index(self): - Bcfg2.Server.Plugin.XMLFileBacked.Index(self) + Bcfg2.Server.Plugin.StructFile.Index(self) self.entries = [] for xsource in self.xdata.findall('.//Source'): source = self.source_from_xml(xsource) if source is not None: self.entries.append(source) + Index.__doc__ = Bcfg2.Server.Plugin.StructFile.Index.__doc__ + """ + +``Index`` is responsible for calling :func:`source_from_xml` for each +``Source`` tag in each file. """ def source_from_xml(self, xsource): - """ create a *Source object from its XML representation in - sources.xml """ + """ Create a + :class:`Bcfg2.Server.Plugins.Packages.Source.Source` subclass + object from XML representation of a source in ``sources.xml``. + ``source_from-xml`` determines the appropriate subclass of + ``Source`` to instantiate according to the ``type`` attribute + of the ``Source`` tag. + + :param xsource: The XML tag representing the source + :type xsource: lxml.etree._Element + :returns: :class:`Bcfg2.Server.Plugins.Packages.Source.Source` + subclass, or None on error + """ stype = xsource.get("type") if stype is None: - self.logger.error("Packages: No type specified for source, " - "skipping") + self.logger.error("Packages: No type specified for source at %s, " + "skipping" % (xsource.get("rawurl", + xsource.get("url")))) return None try: @@ -77,8 +146,9 @@ class PackagesSources(Bcfg2.Server.Plugin.StructFile, stype.title()) cls = getattr(module, "%sSource" % stype.title()) except (ImportError, AttributeError): - ex = sys.exc_info()[1] - self.logger.error("Packages: Unknown source type %s (%s)" % (stype, ex)) + err = sys.exc_info()[1] + self.logger.error("Packages: Unknown source type %s (%s)" % (stype, + err)) return None try: -- cgit v1.2.3-1-g7c22