<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Bcfg2.Server.Core — Bcfg2 1.3.0 documentation</title> <link rel="stylesheet" href="../../../_static/default.css" type="text/css" /> <link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" /> <script type="text/javascript"> var DOCUMENTATION_OPTIONS = { URL_ROOT: '../../../', VERSION: '1.3.0', COLLAPSE_INDEX: false, FILE_SUFFIX: '.html', HAS_SOURCE: true }; </script> <script type="text/javascript" src="../../../_static/jquery.js"></script> <script type="text/javascript" src="../../../_static/underscore.js"></script> <script type="text/javascript" src="../../../_static/doctools.js"></script> <script type="text/javascript" src="../../../_static/sidebar.js"></script> <link rel="shortcut icon" href="../../../_static/favicon.ico"/> <link rel="top" title="Bcfg2 1.3.0 documentation" href="../../../index.html" /> <link rel="up" title="Module code" href="../../index.html" /> <link rel="stylesheet" href="../../../_static/bcfg2.css" type=""/> </head> <body> <div style="text-align: left; padding: 10px 10px 15px 15px"> <a href="../../../index.html"><img src="../../../_static/bcfg2_logo.png" border="0" alt="sampledoc"/></a> </div> <div class="related"> <h3>Navigation</h3> <ul> <li class="right" style="margin-right: 10px"> <a href="../../../genindex.html" title="General Index" accesskey="I">index</a></li> <li class="right" > <a href="../../../py-modindex.html" title="Python Module Index" >modules</a> |</li> <li><a href="../../../index.html">home</a> | </li> <!--<li><a href="../../../search.html">search</a> | </li>--> <li><a href="../../../help/index.html">help</a> | </li> <li><a href="../../../contents.html">documentation </a> »</li> <li><a href="../../index.html" accesskey="U">Module code</a> »</li> </ul> </div> <div class="document"> <div class="documentwrapper"> <div class="bodywrapper"> <div class="body"> <h1>Source code for Bcfg2.Server.Core</h1><div class="highlight"><pre> <span class="sd">""" Bcfg2.Server.Core provides the base core object that server core</span> <span class="sd">implementations inherit from. """</span> <span class="kn">import</span> <span class="nn">os</span> <span class="kn">import</span> <span class="nn">sys</span> <span class="kn">import</span> <span class="nn">time</span> <span class="kn">import</span> <span class="nn">atexit</span> <span class="kn">import</span> <span class="nn">select</span> <span class="kn">import</span> <span class="nn">signal</span> <span class="kn">import</span> <span class="nn">logging</span> <span class="kn">import</span> <span class="nn">inspect</span> <span class="kn">import</span> <span class="nn">threading</span> <span class="kn">import</span> <span class="nn">lxml.etree</span> <span class="kn">import</span> <span class="nn">Bcfg2.settings</span> <span class="kn">import</span> <span class="nn">Bcfg2.Server</span> <span class="kn">import</span> <span class="nn">Bcfg2.Logger</span> <span class="kn">import</span> <span class="nn">Bcfg2.Server.FileMonitor</span> <span class="kn">from</span> <span class="nn">Bcfg2.Cache</span> <span class="kn">import</span> <span class="n">Cache</span> <span class="kn">import</span> <span class="nn">Bcfg2.Statistics</span> <span class="kn">from</span> <span class="nn">itertools</span> <span class="kn">import</span> <span class="n">chain</span> <span class="kn">from</span> <span class="nn">Bcfg2.Compat</span> <span class="kn">import</span> <span class="n">xmlrpclib</span> <span class="c"># pylint: disable=W0622</span> <span class="kn">from</span> <span class="nn">Bcfg2.Server.Plugin</span> <span class="kn">import</span> <span class="n">PluginInitError</span><span class="p">,</span> <span class="n">PluginExecutionError</span><span class="p">,</span> \ <span class="n">track_statistics</span> <span class="k">try</span><span class="p">:</span> <span class="kn">import</span> <span class="nn">psyco</span> <span class="n">psyco</span><span class="o">.</span><span class="n">full</span><span class="p">()</span> <span class="k">except</span> <span class="ne">ImportError</span><span class="p">:</span> <span class="k">pass</span> <span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="p">[</span><span class="s">'DJANGO_SETTINGS_MODULE'</span><span class="p">]</span> <span class="o">=</span> <span class="s">'Bcfg2.settings'</span> <div class="viewcode-block" id="exposed"><a class="viewcode-back" href="../../../development/core.html#Bcfg2.Server.Core.exposed">[docs]</a><span class="k">def</span> <span class="nf">exposed</span><span class="p">(</span><span class="n">func</span><span class="p">):</span> <span class="sd">""" Decorator that sets the ``exposed`` attribute of a function to</span> <span class="sd"> ``True`` expose it via XML-RPC. This currently works for both the</span> <span class="sd"> builtin and CherryPy cores, although if other cores are added this</span> <span class="sd"> may need to be made a core-specific function.</span> <span class="sd"> :param func: The function to decorate</span> <span class="sd"> :type func: callable</span> <span class="sd"> :returns: callable - the decorated function"""</span> <span class="n">func</span><span class="o">.</span><span class="n">exposed</span> <span class="o">=</span> <span class="bp">True</span> <span class="k">return</span> <span class="n">func</span> </div> <div class="viewcode-block" id="sort_xml"><a class="viewcode-back" href="../../../development/core.html#Bcfg2.Server.Core.sort_xml">[docs]</a><span class="k">def</span> <span class="nf">sort_xml</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span> <span class="sd">""" Recursively sort an XML document in a deterministic fashion.</span> <span class="sd"> This shouldn't be used to perform a *useful* sort, merely to put</span> <span class="sd"> XML in a deterministic, replicable order. The document is sorted</span> <span class="sd"> in-place.</span> <span class="sd"> :param node: The root node of the XML tree to sort</span> <span class="sd"> :type node: lxml.etree._Element or lxml.etree.ElementTree</span> <span class="sd"> :param key: The key to sort by</span> <span class="sd"> :type key: callable</span> <span class="sd"> :returns: None</span> <span class="sd"> """</span> <span class="k">for</span> <span class="n">child</span> <span class="ow">in</span> <span class="n">node</span><span class="p">:</span> <span class="n">sort_xml</span><span class="p">(</span><span class="n">child</span><span class="p">,</span> <span class="n">key</span><span class="p">)</span> <span class="k">try</span><span class="p">:</span> <span class="n">sorted_children</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="n">key</span><span class="p">)</span> <span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span> <span class="n">sorted_children</span> <span class="o">=</span> <span class="n">node</span> <span class="n">node</span><span class="p">[:]</span> <span class="o">=</span> <span class="n">sorted_children</span> </div> <div class="viewcode-block" id="CoreInitError"><a class="viewcode-back" href="../../../development/core.html#Bcfg2.Server.Core.CoreInitError">[docs]</a><span class="k">class</span> <span class="nc">CoreInitError</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span> <span class="sd">""" Raised when the server core cannot be initialized. """</span> <span class="k">pass</span> </div> <div class="viewcode-block" id="NoExposedMethod"><a class="viewcode-back" href="../../../development/core.html#Bcfg2.Server.Core.NoExposedMethod">[docs]</a><span class="k">class</span> <span class="nc">NoExposedMethod</span> <span class="p">(</span><span class="ne">Exception</span><span class="p">):</span> <span class="sd">""" Raised when an XML-RPC method is called, but there is no</span> <span class="sd"> method exposed with the given name. """</span> <span class="c"># pylint: disable=W0702</span> <span class="c"># in core we frequently want to catch all exceptions, regardless of</span> <span class="c"># type, so disable the pylint rule that catches that.</span> </div> <div class="viewcode-block" id="BaseCore"><a class="viewcode-back" href="../../../development/core.html#Bcfg2.Server.Core.BaseCore">[docs]</a><span class="k">class</span> <span class="nc">BaseCore</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span> <span class="sd">""" The server core is the container for all Bcfg2 server logic</span> <span class="sd"> and modules. All core implementations must inherit from</span> <span class="sd"> ``BaseCore``. """</span> <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">setup</span><span class="p">):</span> <span class="c"># pylint: disable=R0912,R0915</span> <span class="sd">"""</span> <span class="sd"> :param setup: A Bcfg2 options dict</span> <span class="sd"> :type setup: Bcfg2.Options.OptionParser</span> <span class="sd"> .. automethod:: _daemonize</span> <span class="sd"> .. automethod:: _run</span> <span class="sd"> .. automethod:: _block</span> <span class="sd"> .. -----</span> <span class="sd"> .. automethod:: _file_monitor_thread</span> <span class="sd"> """</span> <span class="c">#: The Bcfg2 repository directory</span> <span class="bp">self</span><span class="o">.</span><span class="n">datastore</span> <span class="o">=</span> <span class="n">setup</span><span class="p">[</span><span class="s">'repo'</span><span class="p">]</span> <span class="k">if</span> <span class="n">setup</span><span class="p">[</span><span class="s">'debug'</span><span class="p">]:</span> <span class="n">level</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">DEBUG</span> <span class="k">elif</span> <span class="n">setup</span><span class="p">[</span><span class="s">'verbose'</span><span class="p">]:</span> <span class="n">level</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">INFO</span> <span class="k">else</span><span class="p">:</span> <span class="n">level</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">WARNING</span> <span class="c"># we set a higher log level for the console by default. we</span> <span class="c"># assume that if someone is running bcfg2-server in such a way</span> <span class="c"># that it _can_ log to console, they want more output. if</span> <span class="c"># level is set to DEBUG, that will get handled by</span> <span class="c"># setup_logging and the console will get DEBUG output.</span> <span class="n">Bcfg2</span><span class="o">.</span><span class="n">Logger</span><span class="o">.</span><span class="n">setup_logging</span><span class="p">(</span><span class="s">'bcfg2-server'</span><span class="p">,</span> <span class="n">to_console</span><span class="o">=</span><span class="n">logging</span><span class="o">.</span><span class="n">INFO</span><span class="p">,</span> <span class="n">to_syslog</span><span class="o">=</span><span class="n">setup</span><span class="p">[</span><span class="s">'syslog'</span><span class="p">],</span> <span class="n">to_file</span><span class="o">=</span><span class="n">setup</span><span class="p">[</span><span class="s">'logging'</span><span class="p">],</span> <span class="n">level</span><span class="o">=</span><span class="n">level</span><span class="p">)</span> <span class="c">#: A :class:`logging.Logger` object for use by the core</span> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s">'bcfg2-server'</span><span class="p">)</span> <span class="k">try</span><span class="p">:</span> <span class="n">filemonitor</span> <span class="o">=</span> \ <span class="n">Bcfg2</span><span class="o">.</span><span class="n">Server</span><span class="o">.</span><span class="n">FileMonitor</span><span class="o">.</span><span class="n">available</span><span class="p">[</span><span class="n">setup</span><span class="p">[</span><span class="s">'filemonitor'</span><span class="p">]]</span> <span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s">"File monitor driver </span><span class="si">%s</span><span class="s"> not available; "</span> <span class="s">"forcing to default"</span> <span class="o">%</span> <span class="n">setup</span><span class="p">[</span><span class="s">'filemonitor'</span><span class="p">])</span> <span class="n">filemonitor</span> <span class="o">=</span> <span class="n">Bcfg2</span><span class="o">.</span><span class="n">Server</span><span class="o">.</span><span class="n">FileMonitor</span><span class="o">.</span><span class="n">available</span><span class="p">[</span><span class="s">'default'</span><span class="p">]</span> <span class="n">famargs</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">(</span><span class="n">ignore</span><span class="o">=</span><span class="p">[],</span> <span class="n">debug</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span> <span class="k">if</span> <span class="s">'ignore'</span> <span class="ow">in</span> <span class="n">setup</span><span class="p">:</span> <span class="n">famargs</span><span class="p">[</span><span class="s">'ignore'</span><span class="p">]</span> <span class="o">=</span> <span class="n">setup</span><span class="p">[</span><span class="s">'ignore'</span><span class="p">]</span> <span class="k">if</span> <span class="s">'debug'</span> <span class="ow">in</span> <span class="n">setup</span><span class="p">:</span> <span class="n">famargs</span><span class="p">[</span><span class="s">'debug'</span><span class="p">]</span> <span class="o">=</span> <span class="n">setup</span><span class="p">[</span><span class="s">'debug'</span><span class="p">]</span> <span class="k">try</span><span class="p">:</span> <span class="c">#: The :class:`Bcfg2.Server.FileMonitor.FileMonitor`</span> <span class="c">#: object used by the core to monitor for Bcfg2 data</span> <span class="c">#: changes.</span> <span class="bp">self</span><span class="o">.</span><span class="n">fam</span> <span class="o">=</span> <span class="n">filemonitor</span><span class="p">(</span><span class="o">**</span><span class="n">famargs</span><span class="p">)</span> <span class="k">except</span> <span class="ne">IOError</span><span class="p">:</span> <span class="n">msg</span> <span class="o">=</span> <span class="s">"Failed to instantiate fam driver </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="n">setup</span><span class="p">[</span><span class="s">'filemonitor'</span><span class="p">]</span> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="n">msg</span><span class="p">,</span> <span class="n">exc_info</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span> <span class="k">raise</span> <span class="n">CoreInitError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span> <span class="c">#: Path to bcfg2.conf</span> <span class="bp">self</span><span class="o">.</span><span class="n">cfile</span> <span class="o">=</span> <span class="n">setup</span><span class="p">[</span><span class="s">'configfile'</span><span class="p">]</span> <span class="c">#: Dict of plugins that are enabled. Keys are the plugin</span> <span class="c">#: names (just the plugin name, in the correct case; e.g.,</span> <span class="c">#: "Cfg", not "Bcfg2.Server.Plugins.Cfg"), and values are</span> <span class="c">#: plugin objects.</span> <span class="bp">self</span><span class="o">.</span><span class="n">plugins</span> <span class="o">=</span> <span class="p">{}</span> <span class="c">#: Blacklist of plugins that conflict with enabled plugins.</span> <span class="c">#: If two plugins are loaded that conflict with each other,</span> <span class="c">#: the first one loaded wins.</span> <span class="bp">self</span><span class="o">.</span><span class="n">plugin_blacklist</span> <span class="o">=</span> <span class="p">{}</span> <span class="c">#: Revision of the Bcfg2 specification. This will be sent to</span> <span class="c">#: the client in the configuration, and can be set by a</span> <span class="c">#: :class:`Bcfg2.Server.Plugin.interfaces.Version` plugin.</span> <span class="bp">self</span><span class="o">.</span><span class="n">revision</span> <span class="o">=</span> <span class="s">'-1'</span> <span class="c">#: The Bcfg2 options dict</span> <span class="bp">self</span><span class="o">.</span><span class="n">setup</span> <span class="o">=</span> <span class="n">setup</span> <span class="n">atexit</span><span class="o">.</span><span class="n">register</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">shutdown</span><span class="p">)</span> <span class="c">#: Threading event to signal worker threads (e.g.,</span> <span class="c">#: :attr:`fam_thread`) to shutdown</span> <span class="bp">self</span><span class="o">.</span><span class="n">terminate</span> <span class="o">=</span> <span class="n">threading</span><span class="o">.</span><span class="n">Event</span><span class="p">()</span> <span class="c">#: RLock to be held on writes to the backend db</span> <span class="bp">self</span><span class="o">.</span><span class="n">db_write_lock</span> <span class="o">=</span> <span class="n">threading</span><span class="o">.</span><span class="n">RLock</span><span class="p">()</span> <span class="c"># generate Django ORM settings. this must be done _before_ we</span> <span class="c"># load plugins</span> <span class="n">Bcfg2</span><span class="o">.</span><span class="n">settings</span><span class="o">.</span><span class="n">read_config</span><span class="p">(</span><span class="n">repo</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">datastore</span><span class="p">)</span> <span class="c">#: Whether or not it's possible to use the Django database</span> <span class="c">#: backend for plugins that have that capability</span> <span class="bp">self</span><span class="o">.</span><span class="n">_database_available</span> <span class="o">=</span> <span class="bp">False</span> <span class="k">if</span> <span class="n">Bcfg2</span><span class="o">.</span><span class="n">settings</span><span class="o">.</span><span class="n">HAS_DJANGO</span><span class="p">:</span> <span class="n">db_settings</span> <span class="o">=</span> <span class="n">Bcfg2</span><span class="o">.</span><span class="n">settings</span><span class="o">.</span><span class="n">DATABASES</span><span class="p">[</span><span class="s">'default'</span><span class="p">]</span> <span class="k">if</span> <span class="p">(</span><span class="s">'daemon'</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">setup</span> <span class="ow">and</span> <span class="s">'daemon_uid'</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">setup</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">setup</span><span class="p">[</span><span class="s">'daemon'</span><span class="p">]</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">setup</span><span class="p">[</span><span class="s">'daemon_uid'</span><span class="p">]</span> <span class="ow">and</span> <span class="n">db_settings</span><span class="p">[</span><span class="s">'ENGINE'</span><span class="p">]</span><span class="o">.</span><span class="n">endswith</span><span class="p">(</span><span class="s">".sqlite3"</span><span class="p">)</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">db_settings</span><span class="p">[</span><span class="s">'NAME'</span><span class="p">])):</span> <span class="c"># syncdb will create the sqlite database, and we're</span> <span class="c"># going to daemonize, dropping privs to a non-root</span> <span class="c"># user, so we need to chown the database after</span> <span class="c"># creating it</span> <span class="n">do_chown</span> <span class="o">=</span> <span class="bp">True</span> <span class="k">else</span><span class="p">:</span> <span class="n">do_chown</span> <span class="o">=</span> <span class="bp">False</span> <span class="kn">from</span> <span class="nn">django.core.exceptions</span> <span class="kn">import</span> <span class="n">ImproperlyConfigured</span> <span class="kn">from</span> <span class="nn">django.core</span> <span class="kn">import</span> <span class="n">management</span> <span class="k">try</span><span class="p">:</span> <span class="n">management</span><span class="o">.</span><span class="n">call_command</span><span class="p">(</span><span class="s">"syncdb"</span><span class="p">,</span> <span class="n">interactive</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">verbosity</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">_database_available</span> <span class="o">=</span> <span class="bp">True</span> <span class="k">except</span> <span class="n">ImproperlyConfigured</span><span class="p">:</span> <span class="n">err</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">exc_info</span><span class="p">()[</span><span class="mi">1</span><span class="p">]</span> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s">"Django configuration problem: </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="n">err</span><span class="p">)</span> <span class="k">except</span><span class="p">:</span> <span class="n">err</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">exc_info</span><span class="p">()[</span><span class="mi">1</span><span class="p">]</span> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s">"Database update failed: </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="n">err</span><span class="p">)</span> <span class="k">if</span> <span class="n">do_chown</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">_database_available</span><span class="p">:</span> <span class="k">try</span><span class="p">:</span> <span class="n">os</span><span class="o">.</span><span class="n">chown</span><span class="p">(</span><span class="n">db_settings</span><span class="p">[</span><span class="s">'NAME'</span><span class="p">],</span> <span class="bp">self</span><span class="o">.</span><span class="n">setup</span><span class="p">[</span><span class="s">'daemon_uid'</span><span class="p">],</span> <span class="bp">self</span><span class="o">.</span><span class="n">setup</span><span class="p">[</span><span class="s">'daemon_gid'</span><span class="p">])</span> <span class="k">except</span> <span class="ne">OSError</span><span class="p">:</span> <span class="n">err</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">exc_info</span><span class="p">()[</span><span class="mi">1</span><span class="p">]</span> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s">"Failed to set ownership of database "</span> <span class="s">"at </span><span class="si">%s</span><span class="s">: </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">db_settings</span><span class="p">[</span><span class="s">'NAME'</span><span class="p">],</span> <span class="n">err</span><span class="p">))</span> <span class="k">if</span> <span class="s">''</span> <span class="ow">in</span> <span class="n">setup</span><span class="p">[</span><span class="s">'plugins'</span><span class="p">]:</span> <span class="n">setup</span><span class="p">[</span><span class="s">'plugins'</span><span class="p">]</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="s">''</span><span class="p">)</span> <span class="k">for</span> <span class="n">plugin</span> <span class="ow">in</span> <span class="n">setup</span><span class="p">[</span><span class="s">'plugins'</span><span class="p">]:</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">plugin</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">plugins</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">init_plugin</span><span class="p">(</span><span class="n">plugin</span><span class="p">)</span> <span class="c"># Remove blacklisted plugins</span> <span class="k">for</span> <span class="n">plugin</span><span class="p">,</span> <span class="n">blacklist</span> <span class="ow">in</span> <span class="nb">list</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">plugin_blacklist</span><span class="o">.</span><span class="n">items</span><span class="p">()):</span> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">blacklist</span><span class="p">)</span> <span class="o">></span> <span class="mi">0</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s">"The following plugins conflict with </span><span class="si">%s</span><span class="s">;"</span> <span class="s">"Unloading </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">plugin</span><span class="p">,</span> <span class="n">blacklist</span><span class="p">))</span> <span class="k">for</span> <span class="n">plug</span> <span class="ow">in</span> <span class="n">blacklist</span><span class="p">:</span> <span class="k">del</span> <span class="bp">self</span><span class="o">.</span><span class="n">plugins</span><span class="p">[</span><span class="n">plug</span><span class="p">]</span> <span class="c"># Log experimental plugins</span> <span class="n">expl</span> <span class="o">=</span> <span class="p">[</span><span class="n">plug</span> <span class="k">for</span> <span class="n">plug</span> <span class="ow">in</span> <span class="nb">list</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">plugins</span><span class="o">.</span><span class="n">values</span><span class="p">())</span> <span class="k">if</span> <span class="n">plug</span><span class="o">.</span><span class="n">experimental</span><span class="p">]</span> <span class="k">if</span> <span class="n">expl</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">"Loading experimental plugin(s): </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="p">(</span><span class="s">" "</span><span class="o">.</span><span class="n">join</span><span class="p">([</span><span class="n">x</span><span class="o">.</span><span class="n">name</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">expl</span><span class="p">])))</span> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">"NOTE: Interfaces subject to change"</span><span class="p">)</span> <span class="c"># Log deprecated plugins</span> <span class="n">depr</span> <span class="o">=</span> <span class="p">[</span><span class="n">plug</span> <span class="k">for</span> <span class="n">plug</span> <span class="ow">in</span> <span class="nb">list</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">plugins</span><span class="o">.</span><span class="n">values</span><span class="p">())</span> <span class="k">if</span> <span class="n">plug</span><span class="o">.</span><span class="n">deprecated</span><span class="p">]</span> <span class="k">if</span> <span class="n">depr</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">"Loading deprecated plugin(s): </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="p">(</span><span class="s">" "</span><span class="o">.</span><span class="n">join</span><span class="p">([</span><span class="n">x</span><span class="o">.</span><span class="n">name</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">depr</span><span class="p">])))</span> <span class="c"># Find the metadata plugin and set self.metadata</span> <span class="n">mlist</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">plugins_by_type</span><span class="p">(</span><span class="n">Bcfg2</span><span class="o">.</span><span class="n">Server</span><span class="o">.</span><span class="n">Plugin</span><span class="o">.</span><span class="n">Metadata</span><span class="p">)</span> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">mlist</span><span class="p">)</span> <span class="o">>=</span> <span class="mi">1</span><span class="p">:</span> <span class="c">#: The Metadata plugin</span> <span class="bp">self</span><span class="o">.</span><span class="n">metadata</span> <span class="o">=</span> <span class="n">mlist</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">mlist</span><span class="p">)</span> <span class="o">></span> <span class="mi">1</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s">"Multiple Metadata plugins loaded; "</span> <span class="s">"using </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">metadata</span><span class="p">)</span> <span class="k">else</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s">"No Metadata plugin loaded; "</span> <span class="s">"failed to instantiate Core"</span><span class="p">)</span> <span class="k">raise</span> <span class="n">CoreInitError</span><span class="p">(</span><span class="s">"No Metadata Plugin"</span><span class="p">)</span> <span class="c">#: The list of plugins that handle</span> <span class="c">#: :class:`Bcfg2.Server.Plugin.interfaces.Statistics`</span> <span class="bp">self</span><span class="o">.</span><span class="n">statistics</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">plugins_by_type</span><span class="p">(</span><span class="n">Bcfg2</span><span class="o">.</span><span class="n">Server</span><span class="o">.</span><span class="n">Plugin</span><span class="o">.</span><span class="n">Statistics</span><span class="p">)</span> <span class="c">#: The list of plugins that implement the</span> <span class="c">#: :class:`Bcfg2.Server.Plugin.interfaces.PullSource`</span> <span class="c">#: interface</span> <span class="bp">self</span><span class="o">.</span><span class="n">pull_sources</span> <span class="o">=</span> \ <span class="bp">self</span><span class="o">.</span><span class="n">plugins_by_type</span><span class="p">(</span><span class="n">Bcfg2</span><span class="o">.</span><span class="n">Server</span><span class="o">.</span><span class="n">Plugin</span><span class="o">.</span><span class="n">PullSource</span><span class="p">)</span> <span class="c">#: The list of</span> <span class="c">#: :class:`Bcfg2.Server.Plugin.interfaces.Generator` plugins</span> <span class="bp">self</span><span class="o">.</span><span class="n">generators</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">plugins_by_type</span><span class="p">(</span><span class="n">Bcfg2</span><span class="o">.</span><span class="n">Server</span><span class="o">.</span><span class="n">Plugin</span><span class="o">.</span><span class="n">Generator</span><span class="p">)</span> <span class="c">#: The list of plugins that handle</span> <span class="c">#: :class:`Bcfg2.Server.Plugin.interfaces.Structure`</span> <span class="c">#: generation</span> <span class="bp">self</span><span class="o">.</span><span class="n">structures</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">plugins_by_type</span><span class="p">(</span><span class="n">Bcfg2</span><span class="o">.</span><span class="n">Server</span><span class="o">.</span><span class="n">Plugin</span><span class="o">.</span><span class="n">Structure</span><span class="p">)</span> <span class="c">#: The list of plugins that implement the</span> <span class="c">#: :class:`Bcfg2.Server.Plugin.interfaces.Connector` interface</span> <span class="bp">self</span><span class="o">.</span><span class="n">connectors</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">plugins_by_type</span><span class="p">(</span><span class="n">Bcfg2</span><span class="o">.</span><span class="n">Server</span><span class="o">.</span><span class="n">Plugin</span><span class="o">.</span><span class="n">Connector</span><span class="p">)</span> <span class="c">#: The CA that signed the server cert</span> <span class="bp">self</span><span class="o">.</span><span class="n">ca</span> <span class="o">=</span> <span class="n">setup</span><span class="p">[</span><span class="s">'ca'</span><span class="p">]</span> <span class="k">def</span> <span class="nf">hdlr</span><span class="p">(</span><span class="n">sig</span><span class="p">,</span> <span class="n">frame</span><span class="p">):</span> <span class="c"># pylint: disable=W0613</span> <span class="sd">""" Handle SIGINT/Ctrl-C by shutting down the core and exiting</span> <span class="sd"> properly. """</span> <span class="bp">self</span><span class="o">.</span><span class="n">shutdown</span><span class="p">()</span> <span class="n">os</span><span class="o">.</span><span class="n">_exit</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="c"># pylint: disable=W0212</span> <span class="n">signal</span><span class="o">.</span><span class="n">signal</span><span class="p">(</span><span class="n">signal</span><span class="o">.</span><span class="n">SIGINT</span><span class="p">,</span> <span class="n">hdlr</span><span class="p">)</span> <span class="c">#: The FAM :class:`threading.Thread`,</span> <span class="c">#: :func:`_file_monitor_thread`</span> <span class="bp">self</span><span class="o">.</span><span class="n">fam_thread</span> <span class="o">=</span> \ <span class="n">threading</span><span class="o">.</span><span class="n">Thread</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s">"</span><span class="si">%s</span><span class="s">FAMThread"</span> <span class="o">%</span> <span class="n">setup</span><span class="p">[</span><span class="s">'filemonitor'</span><span class="p">],</span> <span class="n">target</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_file_monitor_thread</span><span class="p">)</span> <span class="c">#: A :func:`threading.Lock` for use by</span> <span class="c">#: :func:`Bcfg2.Server.FileMonitor.FileMonitor.handle_event_set`</span> <span class="bp">self</span><span class="o">.</span><span class="n">lock</span> <span class="o">=</span> <span class="n">threading</span><span class="o">.</span><span class="n">Lock</span><span class="p">()</span> <span class="c">#: A :class:`Bcfg2.Cache.Cache` object for caching client</span> <span class="c">#: metadata</span> <span class="bp">self</span><span class="o">.</span><span class="n">metadata_cache</span> <span class="o">=</span> <span class="n">Cache</span><span class="p">()</span> <div class="viewcode-block" id="BaseCore.plugins_by_type"><a class="viewcode-back" href="../../../development/core.html#Bcfg2.Server.Core.BaseCore.plugins_by_type">[docs]</a> <span class="k">def</span> <span class="nf">plugins_by_type</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">base_cls</span><span class="p">):</span> <span class="sd">""" Return a list of loaded plugins that match the passed type.</span> <span class="sd"> The returned list is sorted in ascending order by the plugins'</span> <span class="sd"> ``sort_order`` value. The</span> <span class="sd"> :attr:`Bcfg2.Server.Plugin.base.Plugin.sort_order` defaults to</span> <span class="sd"> 500, but can be overridden by individual plugins. Plugins with</span> <span class="sd"> the same numerical sort_order value are sorted in alphabetical</span> <span class="sd"> order by their name.</span> <span class="sd"> :param base_cls: The base plugin interface class to match (see</span> <span class="sd"> :mod:`Bcfg2.Server.Plugin.interfaces`)</span> <span class="sd"> :type base_cls: type</span> <span class="sd"> :returns: list of :attr:`Bcfg2.Server.Plugin.base.Plugin`</span> <span class="sd"> objects</span> <span class="sd"> """</span> <span class="k">return</span> <span class="nb">sorted</span><span class="p">([</span><span class="n">plugin</span> <span class="k">for</span> <span class="n">plugin</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">plugins</span><span class="o">.</span><span class="n">values</span><span class="p">()</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">plugin</span><span class="p">,</span> <span class="n">base_cls</span><span class="p">)],</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">p</span><span class="p">:</span> <span class="p">(</span><span class="n">p</span><span class="o">.</span><span class="n">sort_order</span><span class="p">,</span> <span class="n">p</span><span class="o">.</span><span class="n">name</span><span class="p">))</span> </div> <div class="viewcode-block" id="BaseCore._file_monitor_thread"><a class="viewcode-back" href="../../../development/core.html#Bcfg2.Server.Core.BaseCore._file_monitor_thread">[docs]</a> <span class="k">def</span> <span class="nf">_file_monitor_thread</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="sd">""" The thread that runs the</span> <span class="sd"> :class:`Bcfg2.Server.FileMonitor.FileMonitor`. This also</span> <span class="sd"> queries :class:`Bcfg2.Server.Plugin.interfaces.Version`</span> <span class="sd"> plugins for the current revision of the Bcfg2 repo. """</span> <span class="n">famfd</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">fam</span><span class="o">.</span><span class="n">fileno</span><span class="p">()</span> <span class="n">terminate</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">terminate</span> <span class="k">while</span> <span class="ow">not</span> <span class="n">terminate</span><span class="o">.</span><span class="n">isSet</span><span class="p">():</span> <span class="k">try</span><span class="p">:</span> <span class="k">if</span> <span class="n">famfd</span><span class="p">:</span> <span class="n">select</span><span class="o">.</span><span class="n">select</span><span class="p">([</span><span class="n">famfd</span><span class="p">],</span> <span class="p">[],</span> <span class="p">[],</span> <span class="mi">2</span><span class="p">)</span> <span class="k">else</span><span class="p">:</span> <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">fam</span><span class="o">.</span><span class="n">pending</span><span class="p">():</span> <span class="n">terminate</span><span class="o">.</span><span class="n">wait</span><span class="p">(</span><span class="mi">15</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">fam</span><span class="o">.</span><span class="n">handle_event_set</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">lock</span><span class="p">)</span> <span class="k">except</span><span class="p">:</span> <span class="k">continue</span> <span class="bp">self</span><span class="o">.</span><span class="n">_update_vcs_revision</span><span class="p">()</span> </div> <span class="nd">@track_statistics</span><span class="p">()</span> <span class="k">def</span> <span class="nf">_update_vcs_revision</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="sd">""" Update the revision of the current configuration on-disk</span> <span class="sd"> from the VCS plugin """</span> <span class="k">for</span> <span class="n">plugin</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">plugins_by_type</span><span class="p">(</span><span class="n">Bcfg2</span><span class="o">.</span><span class="n">Server</span><span class="o">.</span><span class="n">Plugin</span><span class="o">.</span><span class="n">Version</span><span class="p">):</span> <span class="k">try</span><span class="p">:</span> <span class="n">newrev</span> <span class="o">=</span> <span class="n">plugin</span><span class="o">.</span><span class="n">get_revision</span><span class="p">()</span> <span class="k">if</span> <span class="n">newrev</span> <span class="o">!=</span> <span class="bp">self</span><span class="o">.</span><span class="n">revision</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">"Updated to revision </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="n">newrev</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">revision</span> <span class="o">=</span> <span class="n">newrev</span> <span class="k">break</span> <span class="k">except</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="s">"Error getting revision from </span><span class="si">%s</span><span class="s">: </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">plugin</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="n">sys</span><span class="o">.</span><span class="n">exc_info</span><span class="p">()[</span><span class="mi">1</span><span class="p">]))</span> <span class="bp">self</span><span class="o">.</span><span class="n">revision</span> <span class="o">=</span> <span class="s">'-1'</span> <div class="viewcode-block" id="BaseCore.init_plugin"><a class="viewcode-back" href="../../../development/core.html#Bcfg2.Server.Core.BaseCore.init_plugin">[docs]</a> <span class="k">def</span> <span class="nf">init_plugin</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">plugin</span><span class="p">):</span> <span class="sd">""" Import and instantiate a single plugin. The plugin is</span> <span class="sd"> stored to :attr:`plugins`.</span> <span class="sd"> :param plugin: The name of the plugin. This is just the name</span> <span class="sd"> of the plugin, in the appropriate case. I.e.,</span> <span class="sd"> ``Cfg``, not ``Bcfg2.Server.Plugins.Cfg``.</span> <span class="sd"> :type plugin: string</span> <span class="sd"> :returns: None</span> <span class="sd"> """</span> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">"Loading plugin </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="n">plugin</span><span class="p">)</span> <span class="k">try</span><span class="p">:</span> <span class="n">mod</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="nb">__import__</span><span class="p">(</span><span class="s">"Bcfg2.Server.Plugins.</span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">plugin</span><span class="p">))</span><span class="o">.</span><span class="n">Server</span><span class="o">.</span><span class="n">Plugins</span><span class="p">,</span> <span class="n">plugin</span><span class="p">)</span> <span class="k">except</span> <span class="ne">ImportError</span><span class="p">:</span> <span class="k">try</span><span class="p">:</span> <span class="n">mod</span> <span class="o">=</span> <span class="nb">__import__</span><span class="p">(</span><span class="n">plugin</span><span class="p">,</span> <span class="nb">globals</span><span class="p">(),</span> <span class="nb">locals</span><span class="p">(),</span> <span class="p">[</span><span class="n">plugin</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">'.'</span><span class="p">)[</span><span class="o">-</span><span class="mi">1</span><span class="p">]])</span> <span class="k">except</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s">"Failed to load plugin </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="n">plugin</span><span class="p">)</span> <span class="k">return</span> <span class="k">try</span><span class="p">:</span> <span class="n">plug</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">mod</span><span class="p">,</span> <span class="n">plugin</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">'.'</span><span class="p">)[</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span> <span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s">"Failed to load plugin </span><span class="si">%s</span><span class="s">: </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">plugin</span><span class="p">,</span> <span class="n">sys</span><span class="o">.</span><span class="n">exc_info</span><span class="p">()[</span><span class="mi">1</span><span class="p">]))</span> <span class="k">return</span> <span class="c"># Blacklist conflicting plugins</span> <span class="n">cplugs</span> <span class="o">=</span> <span class="p">[</span><span class="n">conflict</span> <span class="k">for</span> <span class="n">conflict</span> <span class="ow">in</span> <span class="n">plug</span><span class="o">.</span><span class="n">conflicts</span> <span class="k">if</span> <span class="n">conflict</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">plugins</span><span class="p">]</span> <span class="bp">self</span><span class="o">.</span><span class="n">plugin_blacklist</span><span class="p">[</span><span class="n">plug</span><span class="o">.</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="n">cplugs</span> <span class="k">try</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">plugins</span><span class="p">[</span><span class="n">plugin</span><span class="p">]</span> <span class="o">=</span> <span class="n">plug</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">datastore</span><span class="p">)</span> <span class="k">except</span> <span class="n">PluginInitError</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s">"Failed to instantiate plugin </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="n">plugin</span><span class="p">,</span> <span class="n">exc_info</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span> <span class="k">except</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s">"Unexpected instantiation failure for plugin </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="n">plugin</span><span class="p">,</span> <span class="n">exc_info</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span> </div> <div class="viewcode-block" id="BaseCore.shutdown"><a class="viewcode-back" href="../../../development/core.html#Bcfg2.Server.Core.BaseCore.shutdown">[docs]</a> <span class="k">def</span> <span class="nf">shutdown</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="sd">""" Perform plugin and FAM shutdown tasks. """</span> <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">terminate</span><span class="o">.</span><span class="n">isSet</span><span class="p">():</span> <span class="bp">self</span><span class="o">.</span><span class="n">terminate</span><span class="o">.</span><span class="n">set</span><span class="p">()</span> <span class="bp">self</span><span class="o">.</span><span class="n">fam</span><span class="o">.</span><span class="n">shutdown</span><span class="p">()</span> <span class="k">for</span> <span class="n">plugin</span> <span class="ow">in</span> <span class="nb">list</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">plugins</span><span class="o">.</span><span class="n">values</span><span class="p">()):</span> <span class="n">plugin</span><span class="o">.</span><span class="n">shutdown</span><span class="p">()</span> </div> <span class="nd">@property</span> <div class="viewcode-block" id="BaseCore.metadata_cache_mode"><a class="viewcode-back" href="../../../development/core.html#Bcfg2.Server.Core.BaseCore.metadata_cache_mode">[docs]</a> <span class="k">def</span> <span class="nf">metadata_cache_mode</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="sd">""" Get the client :attr:`metadata_cache` mode. Options are</span> <span class="sd"> off, initial, cautious, aggressive, on (synonym for</span> <span class="sd"> cautious). See :ref:`server-caching` for more details. """</span> <span class="n">mode</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">setup</span><span class="o">.</span><span class="n">cfp</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">"caching"</span><span class="p">,</span> <span class="s">"client_metadata"</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="s">"off"</span><span class="p">)</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="k">if</span> <span class="n">mode</span> <span class="o">==</span> <span class="s">"on"</span><span class="p">:</span> <span class="k">return</span> <span class="s">"cautious"</span> <span class="k">else</span><span class="p">:</span> <span class="k">return</span> <span class="n">mode</span> </div> <div class="viewcode-block" id="BaseCore.client_run_hook"><a class="viewcode-back" href="../../../development/core.html#Bcfg2.Server.Core.BaseCore.client_run_hook">[docs]</a> <span class="k">def</span> <span class="nf">client_run_hook</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">hook</span><span class="p">,</span> <span class="n">metadata</span><span class="p">):</span> <span class="sd">""" Invoke hooks from</span> <span class="sd"> :class:`Bcfg2.Server.Plugin.interfaces.ClientRunHooks` plugins</span> <span class="sd"> for a given stage.</span> <span class="sd"> :param hook: The name of the stage to run hooks for. A stage</span> <span class="sd"> can be any abstract function defined in the</span> <span class="sd"> :class:`Bcfg2.Server.Plugin.interfaces.ClientRunHooks`</span> <span class="sd"> interface.</span> <span class="sd"> :type hook: string</span> <span class="sd"> :param metadata: Client metadata to run the hook for. This</span> <span class="sd"> will be passed as the sole argument to each</span> <span class="sd"> hook.</span> <span class="sd"> :type metadata: Bcfg2.Server.Plugins.Metadata.ClientMetadata</span> <span class="sd"> """</span> <span class="n">start</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="k">try</span><span class="p">:</span> <span class="k">for</span> <span class="n">plugin</span> <span class="ow">in</span> \ <span class="bp">self</span><span class="o">.</span><span class="n">plugins_by_type</span><span class="p">(</span><span class="n">Bcfg2</span><span class="o">.</span><span class="n">Server</span><span class="o">.</span><span class="n">Plugin</span><span class="o">.</span><span class="n">ClientRunHooks</span><span class="p">):</span> <span class="k">try</span><span class="p">:</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">plugin</span><span class="p">,</span> <span class="n">hook</span><span class="p">)(</span><span class="n">metadata</span><span class="p">)</span> <span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span> <span class="n">err</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">exc_info</span><span class="p">()[</span><span class="mi">1</span><span class="p">]</span> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s">"Unknown attribute: </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="n">err</span><span class="p">)</span> <span class="k">raise</span> <span class="k">except</span><span class="p">:</span> <span class="n">err</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">exc_info</span><span class="p">()[</span><span class="mi">1</span><span class="p">]</span> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s">"</span><span class="si">%s</span><span class="s">: Error invoking hook </span><span class="si">%s</span><span class="s">: </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">plugin</span><span class="p">,</span> <span class="n">hook</span><span class="p">,</span> <span class="n">err</span><span class="p">))</span> <span class="k">finally</span><span class="p">:</span> <span class="n">Bcfg2</span><span class="o">.</span><span class="n">Statistics</span><span class="o">.</span><span class="n">stats</span><span class="o">.</span><span class="n">add_value</span><span class="p">(</span><span class="s">"</span><span class="si">%s</span><span class="s">:client_run_hook:</span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">__class__</span><span class="o">.</span><span class="n">__name__</span><span class="p">,</span> <span class="n">hook</span><span class="p">),</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o">-</span> <span class="n">start</span><span class="p">)</span> </div> <span class="nd">@track_statistics</span><span class="p">()</span> <div class="viewcode-block" id="BaseCore.validate_structures"><a class="viewcode-back" href="../../../development/core.html#Bcfg2.Server.Core.BaseCore.validate_structures">[docs]</a> <span class="k">def</span> <span class="nf">validate_structures</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">metadata</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span> <span class="sd">""" Checks the data structures by calling the</span> <span class="sd"> :func:`Bcfg2.Server.Plugin.interfaces.StructureValidator.validate_structures`</span> <span class="sd"> method of</span> <span class="sd"> :class:`Bcfg2.Server.Plugin.interfaces.StructureValidator`</span> <span class="sd"> plugins.</span> <span class="sd"> :param metadata: Client metadata to validate structures for</span> <span class="sd"> :type metadata: Bcfg2.Server.Plugins.Metadata.ClientMetadata</span> <span class="sd"> :param data: The list of structures (i.e., bundles) for this</span> <span class="sd"> client</span> <span class="sd"> :type data: list of lxml.etree._Element objects</span> <span class="sd"> """</span> <span class="k">for</span> <span class="n">plugin</span> <span class="ow">in</span> \ <span class="bp">self</span><span class="o">.</span><span class="n">plugins_by_type</span><span class="p">(</span><span class="n">Bcfg2</span><span class="o">.</span><span class="n">Server</span><span class="o">.</span><span class="n">Plugin</span><span class="o">.</span><span class="n">StructureValidator</span><span class="p">):</span> <span class="k">try</span><span class="p">:</span> <span class="n">plugin</span><span class="o">.</span><span class="n">validate_structures</span><span class="p">(</span><span class="n">metadata</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span> <span class="k">except</span> <span class="n">Bcfg2</span><span class="o">.</span><span class="n">Server</span><span class="o">.</span><span class="n">Plugin</span><span class="o">.</span><span class="n">ValidationError</span><span class="p">:</span> <span class="n">err</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">exc_info</span><span class="p">()[</span><span class="mi">1</span><span class="p">]</span> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s">"Plugin </span><span class="si">%s</span><span class="s"> structure validation failed: </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">plugin</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="n">err</span><span class="p">))</span> <span class="k">raise</span> <span class="k">except</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s">"Plugin </span><span class="si">%s</span><span class="s">: unexpected structure validation "</span> <span class="s">"failure"</span> <span class="o">%</span> <span class="n">plugin</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="n">exc_info</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span> </div> <span class="nd">@track_statistics</span><span class="p">()</span> <div class="viewcode-block" id="BaseCore.validate_goals"><a class="viewcode-back" href="../../../development/core.html#Bcfg2.Server.Core.BaseCore.validate_goals">[docs]</a> <span class="k">def</span> <span class="nf">validate_goals</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">metadata</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span> <span class="sd">""" Checks that the config matches the goals enforced by</span> <span class="sd"> :class:`Bcfg2.Server.Plugin.interfaces.GoalValidator` plugins</span> <span class="sd"> by calling</span> <span class="sd"> :func:`Bcfg2.Server.Plugin.interfaces.GoalValidator.validate_goals`.</span> <span class="sd"> :param metadata: Client metadata to validate goals for</span> <span class="sd"> :type metadata: Bcfg2.Server.Plugins.Metadata.ClientMetadata</span> <span class="sd"> :param data: The list of structures (i.e., bundles) for this</span> <span class="sd"> client</span> <span class="sd"> :type data: list of lxml.etree._Element objects</span> <span class="sd"> """</span> <span class="k">for</span> <span class="n">plugin</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">plugins_by_type</span><span class="p">(</span><span class="n">Bcfg2</span><span class="o">.</span><span class="n">Server</span><span class="o">.</span><span class="n">Plugin</span><span class="o">.</span><span class="n">GoalValidator</span><span class="p">):</span> <span class="k">try</span><span class="p">:</span> <span class="n">plugin</span><span class="o">.</span><span class="n">validate_goals</span><span class="p">(</span><span class="n">metadata</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span> <span class="k">except</span> <span class="n">Bcfg2</span><span class="o">.</span><span class="n">Server</span><span class="o">.</span><span class="n">Plugin</span><span class="o">.</span><span class="n">ValidationError</span><span class="p">:</span> <span class="n">err</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">exc_info</span><span class="p">()[</span><span class="mi">1</span><span class="p">]</span> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s">"Plugin </span><span class="si">%s</span><span class="s"> goal validation failed: </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">plugin</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="n">err</span><span class="o">.</span><span class="n">message</span><span class="p">))</span> <span class="k">raise</span> <span class="k">except</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s">"Plugin </span><span class="si">%s</span><span class="s">: unexpected goal validation "</span> <span class="s">"failure"</span> <span class="o">%</span> <span class="n">plugin</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="n">exc_info</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span> </div> <span class="nd">@track_statistics</span><span class="p">()</span> <div class="viewcode-block" id="BaseCore.GetStructures"><a class="viewcode-back" href="../../../development/core.html#Bcfg2.Server.Core.BaseCore.GetStructures">[docs]</a> <span class="k">def</span> <span class="nf">GetStructures</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">metadata</span><span class="p">):</span> <span class="sd">""" Get all structures (i.e., bundles) for the given client</span> <span class="sd"> :param metadata: Client metadata to get structures for</span> <span class="sd"> :type metadata: Bcfg2.Server.Plugins.Metadata.ClientMetadata</span> <span class="sd"> :returns: list of :class:`lxml.etree._Element` objects</span> <span class="sd"> """</span> <span class="n">structures</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">chain</span><span class="p">(</span><span class="o">*</span><span class="p">[</span><span class="n">struct</span><span class="o">.</span><span class="n">BuildStructures</span><span class="p">(</span><span class="n">metadata</span><span class="p">)</span> <span class="k">for</span> <span class="n">struct</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">structures</span><span class="p">]))</span> <span class="n">sbundles</span> <span class="o">=</span> <span class="p">[</span><span class="n">b</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">'name'</span><span class="p">)</span> <span class="k">for</span> <span class="n">b</span> <span class="ow">in</span> <span class="n">structures</span> <span class="k">if</span> <span class="n">b</span><span class="o">.</span><span class="n">tag</span> <span class="o">==</span> <span class="s">'Bundle'</span><span class="p">]</span> <span class="n">missing</span> <span class="o">=</span> <span class="p">[</span><span class="n">b</span> <span class="k">for</span> <span class="n">b</span> <span class="ow">in</span> <span class="n">metadata</span><span class="o">.</span><span class="n">bundles</span> <span class="k">if</span> <span class="n">b</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">sbundles</span><span class="p">]</span> <span class="k">if</span> <span class="n">missing</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s">"Client </span><span class="si">%s</span><span class="s"> configuration missing bundles: </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">metadata</span><span class="o">.</span><span class="n">hostname</span><span class="p">,</span> <span class="s">':'</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">missing</span><span class="p">)))</span> <span class="k">return</span> <span class="n">structures</span> </div> <span class="nd">@track_statistics</span><span class="p">()</span> <div class="viewcode-block" id="BaseCore.BindStructures"><a class="viewcode-back" href="../../../development/core.html#Bcfg2.Server.Core.BaseCore.BindStructures">[docs]</a> <span class="k">def</span> <span class="nf">BindStructures</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">structures</span><span class="p">,</span> <span class="n">metadata</span><span class="p">,</span> <span class="n">config</span><span class="p">):</span> <span class="sd">""" Given a list of structures (i.e. bundles), bind all the</span> <span class="sd"> entries in them and add the structures to the config.</span> <span class="sd"> :param structures: The list of structures for this client</span> <span class="sd"> :type structures: list of lxml.etree._Element objects</span> <span class="sd"> :param metadata: Client metadata to bind structures for</span> <span class="sd"> :type metadata: Bcfg2.Server.Plugins.Metadata.ClientMetadata</span> <span class="sd"> :param config: The configuration document to add fully-bound</span> <span class="sd"> structures to. Modified in-place.</span> <span class="sd"> :type config: lxml.etree._Element</span> <span class="sd"> """</span> <span class="k">for</span> <span class="n">astruct</span> <span class="ow">in</span> <span class="n">structures</span><span class="p">:</span> <span class="k">try</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">BindStructure</span><span class="p">(</span><span class="n">astruct</span><span class="p">,</span> <span class="n">metadata</span><span class="p">)</span> <span class="n">config</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">astruct</span><span class="p">)</span> <span class="k">except</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s">"error in BindStructure"</span><span class="p">,</span> <span class="n">exc_info</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span> </div> <span class="nd">@track_statistics</span><span class="p">()</span> <div class="viewcode-block" id="BaseCore.BindStructure"><a class="viewcode-back" href="../../../development/core.html#Bcfg2.Server.Core.BaseCore.BindStructure">[docs]</a> <span class="k">def</span> <span class="nf">BindStructure</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">structure</span><span class="p">,</span> <span class="n">metadata</span><span class="p">):</span> <span class="sd">""" Bind all elements in a single structure (i.e., bundle).</span> <span class="sd"> :param structure: The structure to bind. Modified in-place.</span> <span class="sd"> :type structures: lxml.etree._Element</span> <span class="sd"> :param metadata: Client metadata to bind structure for</span> <span class="sd"> :type metadata: Bcfg2.Server.Plugins.Metadata.ClientMetadata</span> <span class="sd"> """</span> <span class="k">for</span> <span class="n">entry</span> <span class="ow">in</span> <span class="n">structure</span><span class="o">.</span><span class="n">getchildren</span><span class="p">():</span> <span class="k">if</span> <span class="n">entry</span><span class="o">.</span><span class="n">tag</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s">"Bound"</span><span class="p">):</span> <span class="n">entry</span><span class="o">.</span><span class="n">tag</span> <span class="o">=</span> <span class="n">entry</span><span class="o">.</span><span class="n">tag</span><span class="p">[</span><span class="mi">5</span><span class="p">:]</span> <span class="k">continue</span> <span class="k">try</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">Bind</span><span class="p">(</span><span class="n">entry</span><span class="p">,</span> <span class="n">metadata</span><span class="p">)</span> <span class="k">except</span><span class="p">:</span> <span class="n">exc</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">exc_info</span><span class="p">()[</span><span class="mi">1</span><span class="p">]</span> <span class="k">if</span> <span class="s">'failure'</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">entry</span><span class="o">.</span><span class="n">attrib</span><span class="p">:</span> <span class="n">entry</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s">'failure'</span><span class="p">,</span> <span class="s">'bind error: </span><span class="si">%s</span><span class="s">'</span> <span class="o">%</span> <span class="n">exc</span><span class="p">)</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">exc</span><span class="p">,</span> <span class="n">PluginExecutionError</span><span class="p">):</span> <span class="n">msg</span> <span class="o">=</span> <span class="s">"Failed to bind entry"</span> <span class="k">else</span><span class="p">:</span> <span class="n">msg</span> <span class="o">=</span> <span class="s">"Unexpected failure binding entry"</span> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s">"</span><span class="si">%s</span><span class="s"> </span><span class="si">%s</span><span class="s">:</span><span class="si">%s</span><span class="s">: </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">msg</span><span class="p">,</span> <span class="n">entry</span><span class="o">.</span><span class="n">tag</span><span class="p">,</span> <span class="n">entry</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">'name'</span><span class="p">),</span> <span class="n">exc</span><span class="p">))</span> </div> <div class="viewcode-block" id="BaseCore.Bind"><a class="viewcode-back" href="../../../development/core.html#Bcfg2.Server.Core.BaseCore.Bind">[docs]</a> <span class="k">def</span> <span class="nf">Bind</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">entry</span><span class="p">,</span> <span class="n">metadata</span><span class="p">):</span> <span class="sd">""" Bind a single entry using the appropriate generator.</span> <span class="sd"> :param entry: The entry to bind. Modified in-place.</span> <span class="sd"> :type entry: lxml.etree._Element</span> <span class="sd"> :param metadata: Client metadata to bind structure for</span> <span class="sd"> :type metadata: Bcfg2.Server.Plugins.Metadata.ClientMetadata</span> <span class="sd"> """</span> <span class="n">start</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="k">if</span> <span class="s">'altsrc'</span> <span class="ow">in</span> <span class="n">entry</span><span class="o">.</span><span class="n">attrib</span><span class="p">:</span> <span class="n">oldname</span> <span class="o">=</span> <span class="n">entry</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">'name'</span><span class="p">)</span> <span class="n">entry</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s">'name'</span><span class="p">,</span> <span class="n">entry</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">'altsrc'</span><span class="p">))</span> <span class="n">entry</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s">'realname'</span><span class="p">,</span> <span class="n">oldname</span><span class="p">)</span> <span class="k">del</span> <span class="n">entry</span><span class="o">.</span><span class="n">attrib</span><span class="p">[</span><span class="s">'altsrc'</span><span class="p">]</span> <span class="k">try</span><span class="p">:</span> <span class="n">ret</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">Bind</span><span class="p">(</span><span class="n">entry</span><span class="p">,</span> <span class="n">metadata</span><span class="p">)</span> <span class="n">entry</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s">'name'</span><span class="p">,</span> <span class="n">oldname</span><span class="p">)</span> <span class="k">del</span> <span class="n">entry</span><span class="o">.</span><span class="n">attrib</span><span class="p">[</span><span class="s">'realname'</span><span class="p">]</span> <span class="k">return</span> <span class="n">ret</span> <span class="k">except</span><span class="p">:</span> <span class="n">entry</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s">'name'</span><span class="p">,</span> <span class="n">oldname</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s">"Failed binding entry </span><span class="si">%s</span><span class="s">:</span><span class="si">%s</span><span class="s"> with altsrc </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">entry</span><span class="o">.</span><span class="n">tag</span><span class="p">,</span> <span class="n">entry</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">'name'</span><span class="p">),</span> <span class="n">entry</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">'altsrc'</span><span class="p">)))</span> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s">"Falling back to </span><span class="si">%s</span><span class="s">:</span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">entry</span><span class="o">.</span><span class="n">tag</span><span class="p">,</span> <span class="n">entry</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">'name'</span><span class="p">)))</span> <span class="n">glist</span> <span class="o">=</span> <span class="p">[</span><span class="n">gen</span> <span class="k">for</span> <span class="n">gen</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">generators</span> <span class="k">if</span> <span class="n">entry</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">'name'</span><span class="p">)</span> <span class="ow">in</span> <span class="n">gen</span><span class="o">.</span><span class="n">Entries</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">entry</span><span class="o">.</span><span class="n">tag</span><span class="p">,</span> <span class="p">{})]</span> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">glist</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span> <span class="k">return</span> <span class="n">glist</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">Entries</span><span class="p">[</span><span class="n">entry</span><span class="o">.</span><span class="n">tag</span><span class="p">][</span><span class="n">entry</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">'name'</span><span class="p">)](</span><span class="n">entry</span><span class="p">,</span> <span class="n">metadata</span><span class="p">)</span> <span class="k">elif</span> <span class="nb">len</span><span class="p">(</span><span class="n">glist</span><span class="p">)</span> <span class="o">></span> <span class="mi">1</span><span class="p">:</span> <span class="n">generators</span> <span class="o">=</span> <span class="s">", "</span><span class="o">.</span><span class="n">join</span><span class="p">([</span><span class="n">gen</span><span class="o">.</span><span class="n">name</span> <span class="k">for</span> <span class="n">gen</span> <span class="ow">in</span> <span class="n">glist</span><span class="p">])</span> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s">"</span><span class="si">%s</span><span class="s"> </span><span class="si">%s</span><span class="s"> served by multiple generators: </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">entry</span><span class="o">.</span><span class="n">tag</span><span class="p">,</span> <span class="n">entry</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">'name'</span><span class="p">),</span> <span class="n">generators</span><span class="p">))</span> <span class="n">g2list</span> <span class="o">=</span> <span class="p">[</span><span class="n">gen</span> <span class="k">for</span> <span class="n">gen</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">generators</span> <span class="k">if</span> <span class="n">gen</span><span class="o">.</span><span class="n">HandlesEntry</span><span class="p">(</span><span class="n">entry</span><span class="p">,</span> <span class="n">metadata</span><span class="p">)]</span> <span class="k">try</span><span class="p">:</span> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">g2list</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span> <span class="k">return</span> <span class="n">g2list</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">HandleEntry</span><span class="p">(</span><span class="n">entry</span><span class="p">,</span> <span class="n">metadata</span><span class="p">)</span> <span class="n">entry</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s">'failure'</span><span class="p">,</span> <span class="s">'no matching generator'</span><span class="p">)</span> <span class="k">raise</span> <span class="n">PluginExecutionError</span><span class="p">(</span><span class="s">"No matching generator: </span><span class="si">%s</span><span class="s">:</span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">entry</span><span class="o">.</span><span class="n">tag</span><span class="p">,</span> <span class="n">entry</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">'name'</span><span class="p">)))</span> <span class="k">finally</span><span class="p">:</span> <span class="n">Bcfg2</span><span class="o">.</span><span class="n">Statistics</span><span class="o">.</span><span class="n">stats</span><span class="o">.</span><span class="n">add_value</span><span class="p">(</span><span class="s">"</span><span class="si">%s</span><span class="s">:Bind:</span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">__class__</span><span class="o">.</span><span class="n">__name__</span><span class="p">,</span> <span class="n">entry</span><span class="o">.</span><span class="n">tag</span><span class="p">),</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o">-</span> <span class="n">start</span><span class="p">)</span> </div> <div class="viewcode-block" id="BaseCore.BuildConfiguration"><a class="viewcode-back" href="../../../development/core.html#Bcfg2.Server.Core.BaseCore.BuildConfiguration">[docs]</a> <span class="k">def</span> <span class="nf">BuildConfiguration</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">client</span><span class="p">):</span> <span class="sd">""" Build the complete configuration for a client.</span> <span class="sd"> :param client: The hostname of the client to build the</span> <span class="sd"> configuration for</span> <span class="sd"> :type client: string</span> <span class="sd"> :returns: :class:`lxml.etree._Element` - A complete Bcfg2</span> <span class="sd"> configuration document """</span> <span class="n">start</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="n">config</span> <span class="o">=</span> <span class="n">lxml</span><span class="o">.</span><span class="n">etree</span><span class="o">.</span><span class="n">Element</span><span class="p">(</span><span class="s">"Configuration"</span><span class="p">,</span> <span class="n">version</span><span class="o">=</span><span class="s">'2.0'</span><span class="p">,</span> <span class="n">revision</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">revision</span><span class="p">)</span> <span class="k">try</span><span class="p">:</span> <span class="n">meta</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">build_metadata</span><span class="p">(</span><span class="n">client</span><span class="p">)</span> <span class="k">except</span> <span class="n">Bcfg2</span><span class="o">.</span><span class="n">Server</span><span class="o">.</span><span class="n">Plugin</span><span class="o">.</span><span class="n">MetadataConsistencyError</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s">"Metadata consistency error for client </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="n">client</span><span class="p">)</span> <span class="k">return</span> <span class="n">lxml</span><span class="o">.</span><span class="n">etree</span><span class="o">.</span><span class="n">Element</span><span class="p">(</span><span class="s">"error"</span><span class="p">,</span> <span class="nb">type</span><span class="o">=</span><span class="s">'metadata error'</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">client_run_hook</span><span class="p">(</span><span class="s">"start_client_run"</span><span class="p">,</span> <span class="n">meta</span><span class="p">)</span> <span class="k">try</span><span class="p">:</span> <span class="n">structures</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">GetStructures</span><span class="p">(</span><span class="n">meta</span><span class="p">)</span> <span class="k">except</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s">"Error in GetStructures"</span><span class="p">,</span> <span class="n">exc_info</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span> <span class="k">return</span> <span class="n">lxml</span><span class="o">.</span><span class="n">etree</span><span class="o">.</span><span class="n">Element</span><span class="p">(</span><span class="s">"error"</span><span class="p">,</span> <span class="nb">type</span><span class="o">=</span><span class="s">'structure error'</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">validate_structures</span><span class="p">(</span><span class="n">meta</span><span class="p">,</span> <span class="n">structures</span><span class="p">)</span> <span class="c"># Perform altsrc consistency checking</span> <span class="n">esrcs</span> <span class="o">=</span> <span class="p">{}</span> <span class="k">for</span> <span class="n">struct</span> <span class="ow">in</span> <span class="n">structures</span><span class="p">:</span> <span class="k">for</span> <span class="n">entry</span> <span class="ow">in</span> <span class="n">struct</span><span class="p">:</span> <span class="n">key</span> <span class="o">=</span> <span class="p">(</span><span class="n">entry</span><span class="o">.</span><span class="n">tag</span><span class="p">,</span> <span class="n">entry</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">'name'</span><span class="p">))</span> <span class="k">if</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">esrcs</span><span class="p">:</span> <span class="k">if</span> <span class="n">esrcs</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">!=</span> <span class="n">entry</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">'altsrc'</span><span class="p">):</span> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s">"Found inconsistent altsrc mapping "</span> <span class="s">"for entry </span><span class="si">%s</span><span class="s">:</span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="n">key</span><span class="p">)</span> <span class="k">else</span><span class="p">:</span> <span class="n">esrcs</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">entry</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">'altsrc'</span><span class="p">,</span> <span class="bp">None</span><span class="p">)</span> <span class="k">del</span> <span class="n">esrcs</span> <span class="bp">self</span><span class="o">.</span><span class="n">BindStructures</span><span class="p">(</span><span class="n">structures</span><span class="p">,</span> <span class="n">meta</span><span class="p">,</span> <span class="n">config</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">validate_goals</span><span class="p">(</span><span class="n">meta</span><span class="p">,</span> <span class="n">config</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">client_run_hook</span><span class="p">(</span><span class="s">"end_client_run"</span><span class="p">,</span> <span class="n">meta</span><span class="p">)</span> <span class="n">sort_xml</span><span class="p">(</span><span class="n">config</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">e</span><span class="p">:</span> <span class="n">e</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">'name'</span><span class="p">))</span> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">"Generated config for </span><span class="si">%s</span><span class="s"> in </span><span class="si">%.03f</span><span class="s"> seconds"</span> <span class="o">%</span> <span class="p">(</span><span class="n">client</span><span class="p">,</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o">-</span> <span class="n">start</span><span class="p">))</span> <span class="k">return</span> <span class="n">config</span> </div> <div class="viewcode-block" id="BaseCore.HandleEvent"><a class="viewcode-back" href="../../../development/core.html#Bcfg2.Server.Core.BaseCore.HandleEvent">[docs]</a> <span class="k">def</span> <span class="nf">HandleEvent</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">event</span><span class="p">):</span> <span class="sd">""" Handle a change in the Bcfg2 config file.</span> <span class="sd"> :param event: The event to handle</span> <span class="sd"> :type event: Bcfg2.Server.FileMonitor.Event</span> <span class="sd"> """</span> <span class="k">if</span> <span class="n">event</span><span class="o">.</span><span class="n">filename</span> <span class="o">!=</span> <span class="bp">self</span><span class="o">.</span><span class="n">cfile</span><span class="p">:</span> <span class="k">print</span><span class="p">(</span><span class="s">"Got event for unknown file: </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="n">event</span><span class="o">.</span><span class="n">filename</span><span class="p">)</span> <span class="k">return</span> <span class="k">if</span> <span class="n">event</span><span class="o">.</span><span class="n">code2str</span><span class="p">()</span> <span class="o">==</span> <span class="s">'deleted'</span><span class="p">:</span> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">setup</span><span class="o">.</span><span class="n">reparse</span><span class="p">()</span> <span class="bp">self</span><span class="o">.</span><span class="n">metadata_cache</span><span class="o">.</span><span class="n">expire</span><span class="p">()</span> </div> <div class="viewcode-block" id="BaseCore.run"><a class="viewcode-back" href="../../../development/core.html#Bcfg2.Server.Core.BaseCore.run">[docs]</a> <span class="k">def</span> <span class="nf">run</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="sd">""" Run the server core. This calls :func:`_daemonize`,</span> <span class="sd"> :func:`_run`, starts the :attr:`fam_thread`, and calls</span> <span class="sd"> :func:`_block`, but note that it is the responsibility of the</span> <span class="sd"> server core implementation to call :func:`shutdown` under</span> <span class="sd"> normal operation. This also handles creation of the directory</span> <span class="sd"> containing the pidfile, if necessary. """</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">setup</span><span class="p">[</span><span class="s">'daemon'</span><span class="p">]:</span> <span class="c"># if we're dropping privs, then the pidfile is likely</span> <span class="c"># /var/run/bcfg2-server/bcfg2-server.pid or similar.</span> <span class="c"># since some OSes clean directories out of /var/run on</span> <span class="c"># reboot, we need to ensure that the directory containing</span> <span class="c"># the pidfile exists and has the appropriate permissions</span> <span class="n">piddir</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">dirname</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">setup</span><span class="p">[</span><span class="s">'daemon'</span><span class="p">])</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">piddir</span><span class="p">):</span> <span class="n">os</span><span class="o">.</span><span class="n">makedirs</span><span class="p">(</span><span class="n">piddir</span><span class="p">)</span> <span class="n">os</span><span class="o">.</span><span class="n">chown</span><span class="p">(</span><span class="n">piddir</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">setup</span><span class="p">[</span><span class="s">'daemon_uid'</span><span class="p">],</span> <span class="bp">self</span><span class="o">.</span><span class="n">setup</span><span class="p">[</span><span class="s">'daemon_gid'</span><span class="p">])</span> <span class="n">os</span><span class="o">.</span><span class="n">chmod</span><span class="p">(</span><span class="n">piddir</span><span class="p">,</span> <span class="mi">493</span><span class="p">)</span> <span class="c"># 0775</span> <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_daemonize</span><span class="p">():</span> <span class="k">return</span> <span class="bp">False</span> <span class="k">else</span><span class="p">:</span> <span class="n">os</span><span class="o">.</span><span class="n">umask</span><span class="p">(</span><span class="nb">int</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">setup</span><span class="p">[</span><span class="s">'umask'</span><span class="p">],</span> <span class="mi">8</span><span class="p">))</span> <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_run</span><span class="p">():</span> <span class="bp">self</span><span class="o">.</span><span class="n">shutdown</span><span class="p">()</span> <span class="k">return</span> <span class="bp">False</span> <span class="k">try</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">fam</span><span class="o">.</span><span class="n">start</span><span class="p">()</span> <span class="bp">self</span><span class="o">.</span><span class="n">fam_thread</span><span class="o">.</span><span class="n">start</span><span class="p">()</span> <span class="bp">self</span><span class="o">.</span><span class="n">fam</span><span class="o">.</span><span class="n">AddMonitor</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">cfile</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span> <span class="k">for</span> <span class="n">plug</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">plugins_by_type</span><span class="p">(</span><span class="n">Bcfg2</span><span class="o">.</span><span class="n">Server</span><span class="o">.</span><span class="n">Plugin</span><span class="o">.</span><span class="n">Threaded</span><span class="p">):</span> <span class="n">plug</span><span class="o">.</span><span class="n">start_threads</span><span class="p">()</span> <span class="k">except</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">shutdown</span><span class="p">()</span> <span class="k">raise</span> <span class="bp">self</span><span class="o">.</span><span class="n">_block</span><span class="p">()</span> </div> <div class="viewcode-block" id="BaseCore._daemonize"><a class="viewcode-back" href="../../../development/core.html#Bcfg2.Server.Core.BaseCore._daemonize">[docs]</a> <span class="k">def</span> <span class="nf">_daemonize</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="sd">""" Daemonize the server and write the pidfile. This must be</span> <span class="sd"> overridden by a core implementation. """</span> <span class="k">raise</span> <span class="ne">NotImplementedError</span> </div> <div class="viewcode-block" id="BaseCore._run"><a class="viewcode-back" href="../../../development/core.html#Bcfg2.Server.Core.BaseCore._run">[docs]</a> <span class="k">def</span> <span class="nf">_run</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="sd">""" Start up the server; this method should return</span> <span class="sd"> immediately. This must be overridden by a core</span> <span class="sd"> implementation. """</span> <span class="k">raise</span> <span class="ne">NotImplementedError</span> </div> <div class="viewcode-block" id="BaseCore._block"><a class="viewcode-back" href="../../../development/core.html#Bcfg2.Server.Core.BaseCore._block">[docs]</a> <span class="k">def</span> <span class="nf">_block</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="sd">""" Enter the infinite loop. This method should not return</span> <span class="sd"> until the server is killed. This must be overridden by a core</span> <span class="sd"> implementation. """</span> <span class="k">raise</span> <span class="ne">NotImplementedError</span> </div> <div class="viewcode-block" id="BaseCore.GetDecisions"><a class="viewcode-back" href="../../../development/core.html#Bcfg2.Server.Core.BaseCore.GetDecisions">[docs]</a> <span class="k">def</span> <span class="nf">GetDecisions</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">metadata</span><span class="p">,</span> <span class="n">mode</span><span class="p">):</span> <span class="sd">""" Get the decision list for a client.</span> <span class="sd"> :param metadata: Client metadata to get the decision list for</span> <span class="sd"> :type metadata: Bcfg2.Server.Plugins.Metadata.ClientMetadata</span> <span class="sd"> :param mode: The decision mode ("whitelist" or "blacklist")</span> <span class="sd"> :type mode: string</span> <span class="sd"> :returns: list of Decision tuples ``(<entry tag>, <entry name>)``</span> <span class="sd"> """</span> <span class="n">result</span> <span class="o">=</span> <span class="p">[]</span> <span class="k">for</span> <span class="n">plugin</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">plugins_by_type</span><span class="p">(</span><span class="n">Bcfg2</span><span class="o">.</span><span class="n">Server</span><span class="o">.</span><span class="n">Plugin</span><span class="o">.</span><span class="n">Decision</span><span class="p">):</span> <span class="k">try</span><span class="p">:</span> <span class="n">result</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">plugin</span><span class="o">.</span><span class="n">GetDecisions</span><span class="p">(</span><span class="n">metadata</span><span class="p">,</span> <span class="n">mode</span><span class="p">))</span> <span class="k">except</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s">"Plugin: </span><span class="si">%s</span><span class="s"> failed to generate decision list"</span> <span class="o">%</span> <span class="n">plugin</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="n">exc_info</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span> <span class="k">return</span> <span class="n">result</span> </div> <span class="nd">@track_statistics</span><span class="p">()</span> <div class="viewcode-block" id="BaseCore.build_metadata"><a class="viewcode-back" href="../../../development/core.html#Bcfg2.Server.Core.BaseCore.build_metadata">[docs]</a> <span class="k">def</span> <span class="nf">build_metadata</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">client_name</span><span class="p">):</span> <span class="sd">""" Build initial client metadata for a client</span> <span class="sd"> :param client_name: The name of the client to build metadata</span> <span class="sd"> for</span> <span class="sd"> :type client_name: string</span> <span class="sd"> :returns: :class:`Bcfg2.Server.Plugins.Metadata.ClientMetadata`</span> <span class="sd"> """</span> <span class="k">if</span> <span class="ow">not</span> <span class="nb">hasattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s">'metadata'</span><span class="p">):</span> <span class="c"># some threads start before metadata is even loaded</span> <span class="k">raise</span> <span class="n">Bcfg2</span><span class="o">.</span><span class="n">Server</span><span class="o">.</span><span class="n">Plugin</span><span class="o">.</span><span class="n">MetadataRuntimeError</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">metadata_cache_mode</span> <span class="o">==</span> <span class="s">'initial'</span><span class="p">:</span> <span class="c"># the Metadata plugin handles loading the cached data if</span> <span class="c"># we're only caching the initial metadata object</span> <span class="n">imd</span> <span class="o">=</span> <span class="bp">None</span> <span class="k">else</span><span class="p">:</span> <span class="n">imd</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">metadata_cache</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">client_name</span><span class="p">,</span> <span class="bp">None</span><span class="p">)</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">imd</span><span class="p">:</span> <span class="n">imd</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">metadata</span><span class="o">.</span><span class="n">get_initial_metadata</span><span class="p">(</span><span class="n">client_name</span><span class="p">)</span> <span class="k">for</span> <span class="n">conn</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">connectors</span><span class="p">:</span> <span class="n">grps</span> <span class="o">=</span> <span class="n">conn</span><span class="o">.</span><span class="n">get_additional_groups</span><span class="p">(</span><span class="n">imd</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">metadata</span><span class="o">.</span><span class="n">merge_additional_groups</span><span class="p">(</span><span class="n">imd</span><span class="p">,</span> <span class="n">grps</span><span class="p">)</span> <span class="k">for</span> <span class="n">conn</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">connectors</span><span class="p">:</span> <span class="n">data</span> <span class="o">=</span> <span class="n">conn</span><span class="o">.</span><span class="n">get_additional_data</span><span class="p">(</span><span class="n">imd</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">metadata</span><span class="o">.</span><span class="n">merge_additional_data</span><span class="p">(</span><span class="n">imd</span><span class="p">,</span> <span class="n">conn</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span> <span class="n">imd</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">by_name</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">build_metadata</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">metadata_cache_mode</span> <span class="ow">in</span> <span class="p">[</span><span class="s">'cautious'</span><span class="p">,</span> <span class="s">'aggressive'</span><span class="p">]:</span> <span class="bp">self</span><span class="o">.</span><span class="n">metadata_cache</span><span class="p">[</span><span class="n">client_name</span><span class="p">]</span> <span class="o">=</span> <span class="n">imd</span> <span class="k">return</span> <span class="n">imd</span> </div> <div class="viewcode-block" id="BaseCore.process_statistics"><a class="viewcode-back" href="../../../development/core.html#Bcfg2.Server.Core.BaseCore.process_statistics">[docs]</a> <span class="k">def</span> <span class="nf">process_statistics</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">client_name</span><span class="p">,</span> <span class="n">statistics</span><span class="p">):</span> <span class="sd">""" Process uploaded statistics for client.</span> <span class="sd"> :param client_name: The name of the client to process</span> <span class="sd"> statistics for</span> <span class="sd"> :type client_name: string</span> <span class="sd"> :param statistics: The statistics document to process</span> <span class="sd"> :type statistics: lxml.etree._Element</span> <span class="sd"> """</span> <span class="n">meta</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">build_metadata</span><span class="p">(</span><span class="n">client_name</span><span class="p">)</span> <span class="n">state</span> <span class="o">=</span> <span class="n">statistics</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="s">".//Statistics"</span><span class="p">)</span> <span class="k">if</span> <span class="n">state</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">'version'</span><span class="p">)</span> <span class="o">>=</span> <span class="s">'2.0'</span><span class="p">:</span> <span class="k">for</span> <span class="n">plugin</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">statistics</span><span class="p">:</span> <span class="k">try</span><span class="p">:</span> <span class="n">plugin</span><span class="o">.</span><span class="n">process_statistics</span><span class="p">(</span><span class="n">meta</span><span class="p">,</span> <span class="n">statistics</span><span class="p">)</span> <span class="k">except</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s">"Plugin </span><span class="si">%s</span><span class="s"> failed to process stats from "</span> <span class="s">"</span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">plugin</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="n">meta</span><span class="o">.</span><span class="n">hostname</span><span class="p">),</span> <span class="n">exc_info</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">"Client </span><span class="si">%s</span><span class="s"> reported state </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">client_name</span><span class="p">,</span> <span class="n">state</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">'state'</span><span class="p">)))</span> <span class="bp">self</span><span class="o">.</span><span class="n">client_run_hook</span><span class="p">(</span><span class="s">"end_statistics"</span><span class="p">,</span> <span class="n">meta</span><span class="p">)</span> </div> <div class="viewcode-block" id="BaseCore.resolve_client"><a class="viewcode-back" href="../../../development/core.html#Bcfg2.Server.Core.BaseCore.resolve_client">[docs]</a> <span class="k">def</span> <span class="nf">resolve_client</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">address</span><span class="p">,</span> <span class="n">cleanup_cache</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">metadata</span><span class="o">=</span><span class="bp">True</span><span class="p">):</span> <span class="sd">""" Given a client address, get the client hostname and</span> <span class="sd"> optionally metadata.</span> <span class="sd"> :param address: The address pair of the client to get the</span> <span class="sd"> canonical hostname for.</span> <span class="sd"> :type address: tuple of (<ip address>, <hostname>)</span> <span class="sd"> :param cleanup_cache: Tell the</span> <span class="sd"> :class:`Bcfg2.Server.Plugin.interfaces.Metadata`</span> <span class="sd"> plugin in :attr:`metadata` to clean up</span> <span class="sd"> any client or session cache it might</span> <span class="sd"> keep</span> <span class="sd"> :type cleanup_cache: bool</span> <span class="sd"> :param metadata: Build a</span> <span class="sd"> :class:`Bcfg2.Server.Plugins.Metadata.ClientMetadata`</span> <span class="sd"> object for this client as well. This is</span> <span class="sd"> offered for convenience.</span> <span class="sd"> :type metadata: bool</span> <span class="sd"> :returns: tuple - If ``metadata`` is False, returns</span> <span class="sd"> ``(<canonical hostname>, None)``; if ``metadata`` is</span> <span class="sd"> True, returns ``(<canonical hostname>, <client</span> <span class="sd"> metadata object>)``</span> <span class="sd"> """</span> <span class="k">try</span><span class="p">:</span> <span class="n">client</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">metadata</span><span class="o">.</span><span class="n">resolve_client</span><span class="p">(</span><span class="n">address</span><span class="p">,</span> <span class="n">cleanup_cache</span><span class="o">=</span><span class="n">cleanup_cache</span><span class="p">)</span> <span class="k">if</span> <span class="n">metadata</span><span class="p">:</span> <span class="n">meta</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">build_metadata</span><span class="p">(</span><span class="n">client</span><span class="p">)</span> <span class="k">else</span><span class="p">:</span> <span class="n">meta</span> <span class="o">=</span> <span class="bp">None</span> <span class="k">except</span> <span class="n">Bcfg2</span><span class="o">.</span><span class="n">Server</span><span class="o">.</span><span class="n">Plugin</span><span class="o">.</span><span class="n">MetadataConsistencyError</span><span class="p">:</span> <span class="n">err</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">exc_info</span><span class="p">()[</span><span class="mi">1</span><span class="p">]</span> <span class="bp">self</span><span class="o">.</span><span class="n">critical_error</span><span class="p">(</span><span class="s">"Client metadata resolution error for </span><span class="si">%s</span><span class="s">: </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">address</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">err</span><span class="p">))</span> <span class="k">except</span> <span class="n">Bcfg2</span><span class="o">.</span><span class="n">Server</span><span class="o">.</span><span class="n">Plugin</span><span class="o">.</span><span class="n">MetadataRuntimeError</span><span class="p">:</span> <span class="n">err</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">exc_info</span><span class="p">()[</span><span class="mi">1</span><span class="p">]</span> <span class="bp">self</span><span class="o">.</span><span class="n">critical_error</span><span class="p">(</span><span class="s">'Metadata system runtime failure for </span><span class="si">%s</span><span class="s">: </span><span class="si">%s</span><span class="s">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">address</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">err</span><span class="p">))</span> <span class="k">return</span> <span class="p">(</span><span class="n">client</span><span class="p">,</span> <span class="n">meta</span><span class="p">)</span> </div> <div class="viewcode-block" id="BaseCore.critical_error"><a class="viewcode-back" href="../../../development/core.html#Bcfg2.Server.Core.BaseCore.critical_error">[docs]</a> <span class="k">def</span> <span class="nf">critical_error</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span> <span class="sd">""" Log an error with its traceback and return an XML-RPC fault</span> <span class="sd"> to the client.</span> <span class="sd"> :param message: The message to log and return to the client</span> <span class="sd"> :type message: string</span> <span class="sd"> :raises: :exc:`xmlrpclib.Fault`</span> <span class="sd"> """</span> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="n">message</span><span class="p">,</span> <span class="n">exc_info</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span> <span class="k">raise</span> <span class="n">xmlrpclib</span><span class="o">.</span><span class="n">Fault</span><span class="p">(</span><span class="n">xmlrpclib</span><span class="o">.</span><span class="n">APPLICATION_ERROR</span><span class="p">,</span> <span class="s">"Critical failure: </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="n">message</span><span class="p">)</span> </div> <span class="k">def</span> <span class="nf">_get_rmi</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="sd">""" Get a list of RMI calls exposed by plugins """</span> <span class="n">rmi</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">()</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">plugins</span><span class="p">:</span> <span class="k">for</span> <span class="n">pname</span><span class="p">,</span> <span class="n">pinst</span> <span class="ow">in</span> <span class="nb">list</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">plugins</span><span class="o">.</span><span class="n">items</span><span class="p">()):</span> <span class="k">for</span> <span class="n">mname</span> <span class="ow">in</span> <span class="n">pinst</span><span class="o">.</span><span class="n">__rmi__</span><span class="p">:</span> <span class="n">rmi</span><span class="p">[</span><span class="s">"</span><span class="si">%s</span><span class="s">.</span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">pname</span><span class="p">,</span> <span class="n">mname</span><span class="p">)]</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">pinst</span><span class="p">,</span> <span class="n">mname</span><span class="p">)</span> <span class="k">return</span> <span class="n">rmi</span> <span class="k">def</span> <span class="nf">_resolve_exposed_method</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">method_name</span><span class="p">):</span> <span class="sd">""" Resolve a method name to the callable that implements that</span> <span class="sd"> method.</span> <span class="sd"> :param method_name: Name of the method to resolve</span> <span class="sd"> :type method_name: string</span> <span class="sd"> :returns: callable</span> <span class="sd"> """</span> <span class="k">try</span><span class="p">:</span> <span class="n">func</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">method_name</span><span class="p">)</span> <span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span> <span class="k">raise</span> <span class="n">NoExposedMethod</span><span class="p">(</span><span class="n">method_name</span><span class="p">)</span> <span class="k">if</span> <span class="ow">not</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">func</span><span class="p">,</span> <span class="s">"exposed"</span><span class="p">,</span> <span class="bp">False</span><span class="p">):</span> <span class="k">raise</span> <span class="n">NoExposedMethod</span><span class="p">(</span><span class="n">method_name</span><span class="p">)</span> <span class="k">return</span> <span class="n">func</span> <span class="c"># XMLRPC handlers start here</span> <span class="nd">@exposed</span> <div class="viewcode-block" id="BaseCore.listMethods"><a class="viewcode-back" href="../../../development/core.html#Bcfg2.Server.Core.BaseCore.listMethods">[docs]</a> <span class="k">def</span> <span class="nf">listMethods</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">address</span><span class="p">):</span> <span class="c"># pylint: disable=W0613</span> <span class="sd">""" List all exposed methods, including plugin RMI.</span> <span class="sd"> :param address: Client (address, hostname) pair</span> <span class="sd"> :type address: tuple</span> <span class="sd"> :returns: list of exposed method names</span> <span class="sd"> """</span> <span class="n">methods</span> <span class="o">=</span> <span class="p">[</span><span class="n">name</span> <span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">func</span> <span class="ow">in</span> <span class="n">inspect</span><span class="o">.</span><span class="n">getmembers</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">callable</span><span class="p">)</span> <span class="k">if</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">func</span><span class="p">,</span> <span class="s">"exposed"</span><span class="p">,</span> <span class="bp">False</span><span class="p">)]</span> <span class="n">methods</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_get_rmi</span><span class="p">()</span><span class="o">.</span><span class="n">keys</span><span class="p">())</span> <span class="k">return</span> <span class="n">methods</span> </div> <span class="nd">@exposed</span> <div class="viewcode-block" id="BaseCore.methodHelp"><a class="viewcode-back" href="../../../development/core.html#Bcfg2.Server.Core.BaseCore.methodHelp">[docs]</a> <span class="k">def</span> <span class="nf">methodHelp</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">address</span><span class="p">,</span> <span class="n">method_name</span><span class="p">):</span> <span class="c"># pylint: disable=W0613</span> <span class="sd">""" Get help from the docstring of an exposed method</span> <span class="sd"> :param address: Client (address, hostname) pair</span> <span class="sd"> :type address: tuple</span> <span class="sd"> :param method_name: The name of the method to get help on</span> <span class="sd"> :type method_name: string</span> <span class="sd"> :returns: string - The help message from the method's docstring</span> <span class="sd"> """</span> <span class="k">try</span><span class="p">:</span> <span class="n">func</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_resolve_exposed_method</span><span class="p">(</span><span class="n">method_name</span><span class="p">)</span> <span class="k">except</span> <span class="n">NoExposedMethod</span><span class="p">:</span> <span class="k">return</span> <span class="s">""</span> <span class="k">return</span> <span class="n">func</span><span class="o">.</span><span class="n">__doc__</span> </div> <span class="nd">@exposed</span> <div class="viewcode-block" id="BaseCore.DeclareVersion"><a class="viewcode-back" href="../../../development/core.html#Bcfg2.Server.Core.BaseCore.DeclareVersion">[docs]</a> <span class="k">def</span> <span class="nf">DeclareVersion</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">address</span><span class="p">,</span> <span class="n">version</span><span class="p">):</span> <span class="sd">""" Declare the client version.</span> <span class="sd"> :param address: Client (address, hostname) pair</span> <span class="sd"> :type address: tuple</span> <span class="sd"> :param version: The client's declared version</span> <span class="sd"> :type version: string</span> <span class="sd"> :returns: bool - True on success</span> <span class="sd"> :raises: :exc:`xmlrpclib.Fault`</span> <span class="sd"> """</span> <span class="n">client</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">resolve_client</span><span class="p">(</span><span class="n">address</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span> <span class="k">try</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">metadata</span><span class="o">.</span><span class="n">set_version</span><span class="p">(</span><span class="n">client</span><span class="p">,</span> <span class="n">version</span><span class="p">)</span> <span class="k">except</span> <span class="p">(</span><span class="n">Bcfg2</span><span class="o">.</span><span class="n">Server</span><span class="o">.</span><span class="n">Plugin</span><span class="o">.</span><span class="n">MetadataConsistencyError</span><span class="p">,</span> <span class="n">Bcfg2</span><span class="o">.</span><span class="n">Server</span><span class="o">.</span><span class="n">Plugin</span><span class="o">.</span><span class="n">MetadataRuntimeError</span><span class="p">):</span> <span class="n">err</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">exc_info</span><span class="p">()[</span><span class="mi">1</span><span class="p">]</span> <span class="bp">self</span><span class="o">.</span><span class="n">critical_error</span><span class="p">(</span><span class="s">"Unable to set version for </span><span class="si">%s</span><span class="s">: </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">client</span><span class="p">,</span> <span class="n">err</span><span class="p">))</span> <span class="k">return</span> <span class="bp">True</span> </div> <span class="nd">@exposed</span> <div class="viewcode-block" id="BaseCore.GetProbes"><a class="viewcode-back" href="../../../development/core.html#Bcfg2.Server.Core.BaseCore.GetProbes">[docs]</a> <span class="k">def</span> <span class="nf">GetProbes</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">address</span><span class="p">):</span> <span class="sd">""" Fetch probes for the client.</span> <span class="sd"> :param address: Client (address, hostname) pair</span> <span class="sd"> :type address: tuple</span> <span class="sd"> :returns: lxml.etree._Element - XML tree describing probes for</span> <span class="sd"> this client</span> <span class="sd"> :raises: :exc:`xmlrpclib.Fault`</span> <span class="sd"> """</span> <span class="n">resp</span> <span class="o">=</span> <span class="n">lxml</span><span class="o">.</span><span class="n">etree</span><span class="o">.</span><span class="n">Element</span><span class="p">(</span><span class="s">'probes'</span><span class="p">)</span> <span class="n">client</span><span class="p">,</span> <span class="n">metadata</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">resolve_client</span><span class="p">(</span><span class="n">address</span><span class="p">,</span> <span class="n">cleanup_cache</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span> <span class="k">try</span><span class="p">:</span> <span class="k">for</span> <span class="n">plugin</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">plugins_by_type</span><span class="p">(</span><span class="n">Bcfg2</span><span class="o">.</span><span class="n">Server</span><span class="o">.</span><span class="n">Plugin</span><span class="o">.</span><span class="n">Probing</span><span class="p">):</span> <span class="k">for</span> <span class="n">probe</span> <span class="ow">in</span> <span class="n">plugin</span><span class="o">.</span><span class="n">GetProbes</span><span class="p">(</span><span class="n">metadata</span><span class="p">):</span> <span class="n">resp</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">probe</span><span class="p">)</span> <span class="k">return</span> <span class="n">lxml</span><span class="o">.</span><span class="n">etree</span><span class="o">.</span><span class="n">tostring</span><span class="p">(</span><span class="n">resp</span><span class="p">,</span> <span class="n">xml_declaration</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s">'UTF-8'</span><span class="p">)</span> <span class="k">except</span><span class="p">:</span> <span class="n">err</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">exc_info</span><span class="p">()[</span><span class="mi">1</span><span class="p">]</span> <span class="bp">self</span><span class="o">.</span><span class="n">critical_error</span><span class="p">(</span><span class="s">"Error determining probes for </span><span class="si">%s</span><span class="s">: </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">client</span><span class="p">,</span> <span class="n">err</span><span class="p">))</span> </div> <span class="nd">@exposed</span> <div class="viewcode-block" id="BaseCore.RecvProbeData"><a class="viewcode-back" href="../../../development/core.html#Bcfg2.Server.Core.BaseCore.RecvProbeData">[docs]</a> <span class="k">def</span> <span class="nf">RecvProbeData</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">address</span><span class="p">,</span> <span class="n">probedata</span><span class="p">):</span> <span class="sd">""" Receive probe data from clients.</span> <span class="sd"> :param address: Client (address, hostname) pair</span> <span class="sd"> :type address: tuple</span> <span class="sd"> :returns: bool - True on success</span> <span class="sd"> :raises: :exc:`xmlrpclib.Fault`</span> <span class="sd"> """</span> <span class="n">client</span><span class="p">,</span> <span class="n">metadata</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">resolve_client</span><span class="p">(</span><span class="n">address</span><span class="p">)</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">metadata_cache_mode</span> <span class="o">==</span> <span class="s">'cautious'</span><span class="p">:</span> <span class="c"># clear the metadata cache right after building the</span> <span class="c"># metadata object; that way the cache is cleared for any</span> <span class="c"># new probe data that's received, but the metadata object</span> <span class="c"># that's created for RecvProbeData doesn't get cached.</span> <span class="c"># I.e., the next metadata object that's built, after probe</span> <span class="c"># data is processed, is cached.</span> <span class="bp">self</span><span class="o">.</span><span class="n">metadata_cache</span><span class="o">.</span><span class="n">expire</span><span class="p">(</span><span class="n">client</span><span class="p">)</span> <span class="k">try</span><span class="p">:</span> <span class="n">xpdata</span> <span class="o">=</span> <span class="n">lxml</span><span class="o">.</span><span class="n">etree</span><span class="o">.</span><span class="n">XML</span><span class="p">(</span><span class="n">probedata</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s">'utf-8'</span><span class="p">),</span> <span class="n">parser</span><span class="o">=</span><span class="n">Bcfg2</span><span class="o">.</span><span class="n">Server</span><span class="o">.</span><span class="n">XMLParser</span><span class="p">)</span> <span class="k">except</span> <span class="n">lxml</span><span class="o">.</span><span class="n">etree</span><span class="o">.</span><span class="n">XMLSyntaxError</span><span class="p">:</span> <span class="n">err</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">exc_info</span><span class="p">()[</span><span class="mi">1</span><span class="p">]</span> <span class="bp">self</span><span class="o">.</span><span class="n">critical_error</span><span class="p">(</span><span class="s">"Failed to parse probe data from client </span><span class="si">%s</span><span class="s">: </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">client</span><span class="p">,</span> <span class="n">err</span><span class="p">))</span> <span class="n">sources</span> <span class="o">=</span> <span class="p">[]</span> <span class="k">for</span> <span class="n">data</span> <span class="ow">in</span> <span class="n">xpdata</span><span class="p">:</span> <span class="n">source</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">'source'</span><span class="p">)</span> <span class="k">if</span> <span class="n">source</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">sources</span><span class="p">:</span> <span class="k">if</span> <span class="n">source</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">plugins</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="s">"Failed to locate plugin </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="n">source</span><span class="p">)</span> <span class="k">continue</span> <span class="n">sources</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">source</span><span class="p">)</span> <span class="k">for</span> <span class="n">source</span> <span class="ow">in</span> <span class="n">sources</span><span class="p">:</span> <span class="n">datalist</span> <span class="o">=</span> <span class="p">[</span><span class="n">data</span> <span class="k">for</span> <span class="n">data</span> <span class="ow">in</span> <span class="n">xpdata</span> <span class="k">if</span> <span class="n">data</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">'source'</span><span class="p">)</span> <span class="o">==</span> <span class="n">source</span><span class="p">]</span> <span class="k">try</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">plugins</span><span class="p">[</span><span class="n">source</span><span class="p">]</span><span class="o">.</span><span class="n">ReceiveData</span><span class="p">(</span><span class="n">metadata</span><span class="p">,</span> <span class="n">datalist</span><span class="p">)</span> <span class="k">except</span><span class="p">:</span> <span class="n">err</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">exc_info</span><span class="p">()[</span><span class="mi">1</span><span class="p">]</span> <span class="bp">self</span><span class="o">.</span><span class="n">critical_error</span><span class="p">(</span><span class="s">"Failed to process probe data from client "</span> <span class="s">"</span><span class="si">%s</span><span class="s">: </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">client</span><span class="p">,</span> <span class="n">err</span><span class="p">))</span> <span class="k">return</span> <span class="bp">True</span> </div> <span class="nd">@exposed</span> <div class="viewcode-block" id="BaseCore.AssertProfile"><a class="viewcode-back" href="../../../development/core.html#Bcfg2.Server.Core.BaseCore.AssertProfile">[docs]</a> <span class="k">def</span> <span class="nf">AssertProfile</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">address</span><span class="p">,</span> <span class="n">profile</span><span class="p">):</span> <span class="sd">""" Set profile for a client.</span> <span class="sd"> :param address: Client (address, hostname) pair</span> <span class="sd"> :type address: tuple</span> <span class="sd"> :returns: bool - True on success</span> <span class="sd"> :raises: :exc:`xmlrpclib.Fault`</span> <span class="sd"> """</span> <span class="n">client</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">resolve_client</span><span class="p">(</span><span class="n">address</span><span class="p">,</span> <span class="n">metadata</span><span class="o">=</span><span class="bp">False</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span> <span class="k">try</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">metadata</span><span class="o">.</span><span class="n">set_profile</span><span class="p">(</span><span class="n">client</span><span class="p">,</span> <span class="n">profile</span><span class="p">,</span> <span class="n">address</span><span class="p">)</span> <span class="k">except</span> <span class="p">(</span><span class="n">Bcfg2</span><span class="o">.</span><span class="n">Server</span><span class="o">.</span><span class="n">Plugin</span><span class="o">.</span><span class="n">MetadataConsistencyError</span><span class="p">,</span> <span class="n">Bcfg2</span><span class="o">.</span><span class="n">Server</span><span class="o">.</span><span class="n">Plugin</span><span class="o">.</span><span class="n">MetadataRuntimeError</span><span class="p">):</span> <span class="n">err</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">exc_info</span><span class="p">()[</span><span class="mi">1</span><span class="p">]</span> <span class="bp">self</span><span class="o">.</span><span class="n">critical_error</span><span class="p">(</span><span class="s">"Unable to assert profile for </span><span class="si">%s</span><span class="s">: </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">client</span><span class="p">,</span> <span class="n">err</span><span class="p">))</span> <span class="k">return</span> <span class="bp">True</span> </div> <span class="nd">@exposed</span> <div class="viewcode-block" id="BaseCore.GetConfig"><a class="viewcode-back" href="../../../development/core.html#Bcfg2.Server.Core.BaseCore.GetConfig">[docs]</a> <span class="k">def</span> <span class="nf">GetConfig</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">address</span><span class="p">):</span> <span class="sd">""" Build config for a client by calling</span> <span class="sd"> :func:`BuildConfiguration`.</span> <span class="sd"> :param address: Client (address, hostname) pair</span> <span class="sd"> :type address: tuple</span> <span class="sd"> :returns: lxml.etree._Element - The full configuration</span> <span class="sd"> document for the client</span> <span class="sd"> :raises: :exc:`xmlrpclib.Fault`</span> <span class="sd"> """</span> <span class="n">client</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">resolve_client</span><span class="p">(</span><span class="n">address</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span> <span class="k">try</span><span class="p">:</span> <span class="n">config</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">BuildConfiguration</span><span class="p">(</span><span class="n">client</span><span class="p">)</span> <span class="k">return</span> <span class="n">lxml</span><span class="o">.</span><span class="n">etree</span><span class="o">.</span><span class="n">tostring</span><span class="p">(</span><span class="n">config</span><span class="p">,</span> <span class="n">xml_declaration</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s">'UTF-8'</span><span class="p">)</span> <span class="k">except</span> <span class="n">Bcfg2</span><span class="o">.</span><span class="n">Server</span><span class="o">.</span><span class="n">Plugin</span><span class="o">.</span><span class="n">MetadataConsistencyError</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">critical_error</span><span class="p">(</span><span class="s">"Metadata consistency failure for </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="n">client</span><span class="p">)</span> </div> <span class="nd">@exposed</span> <div class="viewcode-block" id="BaseCore.RecvStats"><a class="viewcode-back" href="../../../development/core.html#Bcfg2.Server.Core.BaseCore.RecvStats">[docs]</a> <span class="k">def</span> <span class="nf">RecvStats</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">address</span><span class="p">,</span> <span class="n">stats</span><span class="p">):</span> <span class="sd">""" Act on statistics upload with :func:`process_statistics`.</span> <span class="sd"> :param address: Client (address, hostname) pair</span> <span class="sd"> :type address: tuple</span> <span class="sd"> :returns: bool - True on success</span> <span class="sd"> :raises: :exc:`xmlrpclib.Fault`</span> <span class="sd"> """</span> <span class="n">client</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">resolve_client</span><span class="p">(</span><span class="n">address</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span> <span class="n">sdata</span> <span class="o">=</span> <span class="n">lxml</span><span class="o">.</span><span class="n">etree</span><span class="o">.</span><span class="n">XML</span><span class="p">(</span><span class="n">stats</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s">'utf-8'</span><span class="p">),</span> <span class="n">parser</span><span class="o">=</span><span class="n">Bcfg2</span><span class="o">.</span><span class="n">Server</span><span class="o">.</span><span class="n">XMLParser</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">process_statistics</span><span class="p">(</span><span class="n">client</span><span class="p">,</span> <span class="n">sdata</span><span class="p">)</span> <span class="k">return</span> <span class="bp">True</span> </div> <div class="viewcode-block" id="BaseCore.authenticate"><a class="viewcode-back" href="../../../development/core.html#Bcfg2.Server.Core.BaseCore.authenticate">[docs]</a> <span class="k">def</span> <span class="nf">authenticate</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">cert</span><span class="p">,</span> <span class="n">user</span><span class="p">,</span> <span class="n">password</span><span class="p">,</span> <span class="n">address</span><span class="p">):</span> <span class="sd">""" Authenticate a client connection with</span> <span class="sd"> :func:`Bcfg2.Server.Plugin.interfaces.Metadata.AuthenticateConnection`.</span> <span class="sd"> :param cert: an x509 certificate</span> <span class="sd"> :type cert: dict</span> <span class="sd"> :param user: The username of the user trying to authenticate</span> <span class="sd"> :type user: string</span> <span class="sd"> :param password: The password supplied by the client</span> <span class="sd"> :type password: string</span> <span class="sd"> :param address: An address pair of ``(<ip address>, <hostname>)``</span> <span class="sd"> :type address: tuple</span> <span class="sd"> :return: bool - True if the authenticate succeeds, False otherwise</span> <span class="sd"> """</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">ca</span><span class="p">:</span> <span class="n">acert</span> <span class="o">=</span> <span class="n">cert</span> <span class="k">else</span><span class="p">:</span> <span class="c"># No ca, so no cert validation can be done</span> <span class="n">acert</span> <span class="o">=</span> <span class="bp">None</span> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">metadata</span><span class="o">.</span><span class="n">AuthenticateConnection</span><span class="p">(</span><span class="n">acert</span><span class="p">,</span> <span class="n">user</span><span class="p">,</span> <span class="n">password</span><span class="p">,</span> <span class="n">address</span><span class="p">)</span> </div> <span class="nd">@exposed</span> <div class="viewcode-block" id="BaseCore.GetDecisionList"><a class="viewcode-back" href="../../../development/core.html#Bcfg2.Server.Core.BaseCore.GetDecisionList">[docs]</a> <span class="k">def</span> <span class="nf">GetDecisionList</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">address</span><span class="p">,</span> <span class="n">mode</span><span class="p">):</span> <span class="sd">""" Get the decision list for the client with :func:`GetDecisions`.</span> <span class="sd"> :param address: Client (address, hostname) pair</span> <span class="sd"> :type address: tuple</span> <span class="sd"> :returns: list of decision tuples</span> <span class="sd"> :raises: :exc:`xmlrpclib.Fault`</span> <span class="sd"> """</span> <span class="n">metadata</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">resolve_client</span><span class="p">(</span><span class="n">address</span><span class="p">)[</span><span class="mi">1</span><span class="p">]</span> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">GetDecisions</span><span class="p">(</span><span class="n">metadata</span><span class="p">,</span> <span class="n">mode</span><span class="p">)</span> </div> <span class="nd">@property</span> <div class="viewcode-block" id="BaseCore.database_available"><a class="viewcode-back" href="../../../development/core.html#Bcfg2.Server.Core.BaseCore.database_available">[docs]</a> <span class="k">def</span> <span class="nf">database_available</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="sd">""" True if the database is configured and available, False</span> <span class="sd"> otherwise. """</span> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_database_available</span> </div> <span class="nd">@exposed</span> <div class="viewcode-block" id="BaseCore.get_statistics"><a class="viewcode-back" href="../../../development/core.html#Bcfg2.Server.Core.BaseCore.get_statistics">[docs]</a> <span class="k">def</span> <span class="nf">get_statistics</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">_</span><span class="p">):</span> <span class="sd">""" Get current statistics about component execution from</span> <span class="sd"> :attr:`Bcfg2.Statistics.stats`.</span> <span class="sd"> :returns: dict - The statistics data as returned by</span> <span class="sd"> :func:`Bcfg2.Statistics.Statistics.display` """</span> <span class="k">return</span> <span class="n">Bcfg2</span><span class="o">.</span><span class="n">Statistics</span><span class="o">.</span><span class="n">stats</span><span class="o">.</span><span class="n">display</span><span class="p">()</span> </div> <span class="nd">@exposed</span> <div class="viewcode-block" id="BaseCore.toggle_debug"><a class="viewcode-back" href="../../../development/core.html#Bcfg2.Server.Core.BaseCore.toggle_debug">[docs]</a> <span class="k">def</span> <span class="nf">toggle_debug</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">address</span><span class="p">):</span> <span class="sd">""" Toggle debug status of the FAM and all plugins</span> <span class="sd"> :param address: Client (address, hostname) pair</span> <span class="sd"> :type address: tuple</span> <span class="sd"> :returns: bool - The new debug state of the FAM</span> <span class="sd"> """</span> <span class="k">for</span> <span class="n">plugin</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">plugins</span><span class="o">.</span><span class="n">values</span><span class="p">():</span> <span class="n">plugin</span><span class="o">.</span><span class="n">toggle_debug</span><span class="p">()</span> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">toggle_fam_debug</span><span class="p">(</span><span class="n">address</span><span class="p">)</span> </div> <span class="nd">@exposed</span> <div class="viewcode-block" id="BaseCore.toggle_fam_debug"><a class="viewcode-back" href="../../../development/core.html#Bcfg2.Server.Core.BaseCore.toggle_fam_debug">[docs]</a> <span class="k">def</span> <span class="nf">toggle_fam_debug</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">_</span><span class="p">):</span> <span class="sd">""" Toggle debug status of the FAM</span> <span class="sd"> :returns: bool - The new debug state of the FAM</span> <span class="sd"> """</span> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">fam</span><span class="o">.</span><span class="n">toggle_debug</span><span class="p">()</span> </div> <span class="nd">@exposed</span> <div class="viewcode-block" id="BaseCore.set_debug"><a class="viewcode-back" href="../../../development/core.html#Bcfg2.Server.Core.BaseCore.set_debug">[docs]</a> <span class="k">def</span> <span class="nf">set_debug</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">address</span><span class="p">,</span> <span class="n">debug</span><span class="p">):</span> <span class="sd">""" Explicitly set debug status of the FAM and all plugins</span> <span class="sd"> :param debug: The new debug status. This can either be a</span> <span class="sd"> boolean, or a string describing the state (e.g.,</span> <span class="sd"> "true" or "false"; case-insensitive)</span> <span class="sd"> :type debug: bool or string</span> <span class="sd"> :returns: bool - The new debug state</span> <span class="sd"> """</span> <span class="k">if</span> <span class="n">debug</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">[</span><span class="bp">True</span><span class="p">,</span> <span class="bp">False</span><span class="p">]:</span> <span class="n">debug</span> <span class="o">=</span> <span class="n">debug</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="o">==</span> <span class="s">"true"</span> <span class="k">for</span> <span class="n">plugin</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">plugins</span><span class="o">.</span><span class="n">values</span><span class="p">():</span> <span class="n">plugin</span><span class="o">.</span><span class="n">set_debug</span><span class="p">(</span><span class="n">debug</span><span class="p">)</span> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">set_fam_debug</span><span class="p">(</span><span class="n">address</span><span class="p">,</span> <span class="n">debug</span><span class="p">)</span> </div> <span class="nd">@exposed</span> <div class="viewcode-block" id="BaseCore.set_fam_debug"><a class="viewcode-back" href="../../../development/core.html#Bcfg2.Server.Core.BaseCore.set_fam_debug">[docs]</a> <span class="k">def</span> <span class="nf">set_fam_debug</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">debug</span><span class="p">):</span> <span class="sd">""" Explicitly set debug status of the FAM</span> <span class="sd"> :param debug: The new debug status of the FAM. This can</span> <span class="sd"> either be a boolean, or a string describing the</span> <span class="sd"> state (e.g., "true" or "false";</span> <span class="sd"> case-insensitive)</span> <span class="sd"> :type debug: bool or string</span> <span class="sd"> :returns: bool - The new debug state of the FAM</span> <span class="sd"> """</span> <span class="k">if</span> <span class="n">debug</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">[</span><span class="bp">True</span><span class="p">,</span> <span class="bp">False</span><span class="p">]:</span> <span class="n">debug</span> <span class="o">=</span> <span class="n">debug</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="o">==</span> <span class="s">"true"</span> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">fam</span><span class="o">.</span><span class="n">set_debug</span><span class="p">(</span><span class="n">debug</span><span class="p">)</span></div></div> </pre></div> </div> </div> </div> <div class="sphinxsidebar"> <div class="sphinxsidebarwrapper"> <div id="searchbox" style="display: none"> <h3>Quick search</h3> <form class="search" action="../../../search.html" method="get"> <input type="text" name="q" /> <input type="submit" value="Go" /> <input type="hidden" name="check_keywords" value="yes" /> <input type="hidden" name="area" value="default" /> </form> <p class="searchtip" style="font-size: 90%"> Enter search terms or a module, class or function name. </p> </div> <script type="text/javascript">$('#searchbox').show(0);</script> </div> </div> <div class="clearer"></div> </div> <div class="related"> <h3>Navigation</h3> <ul> <li class="right" style="margin-right: 10px"> <a href="../../../genindex.html" title="General Index" >index</a></li> <li class="right" > <a href="../../../py-modindex.html" title="Python Module Index" >modules</a> |</li> <li><a href="../../../index.html">home</a> | </li> <!--<li><a href="../../../search.html">search</a> | </li>--> <li><a href="../../../help/index.html">help</a> | </li> <li><a href="../../../contents.html">documentation </a> »</li> <li><a href="../../index.html" >Module code</a> »</li> </ul> </div> <div class="footer"> © Copyright 2009-2013, Narayan Desai. Last updated on Mar 20, 2013. Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3. </div> </body> </html>