<!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.Plugins.Packages — 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="Bcfg2.Server.Plugins" href="../Plugins.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" >Module code</a> »</li> <li><a href="../Plugins.html" accesskey="U">Bcfg2.Server.Plugins</a> »</li> </ul> </div> <div class="document"> <div class="documentwrapper"> <div class="bodywrapper"> <div class="body"> <h1>Source code for Bcfg2.Server.Plugins.Packages</h1><div class="highlight"><pre> <span class="sd">""" Packages resolves Package entries on the Bcfg2 server in order to</span> <span class="sd">present a complete list of Package entries to the client in order to</span> <span class="sd">determine the completeness of the client configuration. """</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">glob</span> <span class="kn">import</span> <span class="nn">shutil</span> <span class="kn">import</span> <span class="nn">lxml.etree</span> <span class="kn">import</span> <span class="nn">Bcfg2.Logger</span> <span class="kn">import</span> <span class="nn">Bcfg2.Server.Plugin</span> <span class="kn">from</span> <span class="nn">Bcfg2.Compat</span> <span class="kn">import</span> <span class="n">ConfigParser</span><span class="p">,</span> <span class="n">urlopen</span><span class="p">,</span> <span class="n">HTTPError</span> <span class="kn">from</span> <span class="nn">Bcfg2.Server.Plugins.Packages.Collection</span> <span class="kn">import</span> <span class="n">Collection</span><span class="p">,</span> \ <span class="n">get_collection_class</span> <span class="kn">from</span> <span class="nn">Bcfg2.Server.Plugins.Packages.PackagesSources</span> <span class="kn">import</span> <span class="n">PackagesSources</span> <span class="c">#: The default path for generated yum configs</span> <span class="n">YUM_CONFIG_DEFAULT</span> <span class="o">=</span> <span class="s">"/etc/yum.repos.d/bcfg2.repo"</span> <span class="c">#: The default path for generated apt configs</span> <span class="n">APT_CONFIG_DEFAULT</span> <span class="o">=</span> <span class="s">"/etc/apt/sources.d/bcfg2"</span> <div class="viewcode-block" id="Packages"><a class="viewcode-back" href="../../../../development/packages.html#Bcfg2.Server.Plugins.Packages.Packages">[docs]</a><span class="k">class</span> <span class="nc">Packages</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">Plugin</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="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="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="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="sd">""" Packages resolves Package entries on the Bcfg2 server in order</span> <span class="sd"> to present a complete list of Package entries to the client in</span> <span class="sd"> order to determine the completeness of the client configuration.</span> <span class="sd"> It does so by delegating control of package version information to</span> <span class="sd"> a number of backends, which may parse repository metadata directly</span> <span class="sd"> or defer to package manager libraries for truly dynamic</span> <span class="sd"> resolution.</span> <span class="sd"> .. private-include: _build_packages"""</span> <span class="c">#: Packages is an alternative to</span> <span class="c">#: :mod:`Bcfg2.Server.Plugins.Pkgmgr` and conflicts with it.</span> <span class="n">conflicts</span> <span class="o">=</span> <span class="p">[</span><span class="s">'Pkgmgr'</span><span class="p">]</span> <span class="c">#: Packages exposes two additional XML-RPC calls, :func:`Refresh`</span> <span class="c">#: and :func:`Reload`</span> <span class="n">__rmi__</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">Plugin</span><span class="o">.</span><span class="n">Plugin</span><span class="o">.</span><span class="n">__rmi__</span> <span class="o">+</span> <span class="p">[</span><span class="s">'Refresh'</span><span class="p">,</span> <span class="s">'Reload'</span><span class="p">]</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">core</span><span class="p">,</span> <span class="n">datastore</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">Plugin</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">core</span><span class="p">,</span> <span class="n">datastore</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="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="bp">self</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="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="bp">self</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="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="bp">self</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="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="c">#: Packages does a potentially tremendous amount of on-disk</span> <span class="c">#: caching. ``cachepath`` holds the base directory to where</span> <span class="c">#: data should be cached.</span> <span class="bp">self</span><span class="o">.</span><span class="n">cachepath</span> <span class="o">=</span> \ <span class="bp">self</span><span class="o">.</span><span class="n">core</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">"packages"</span><span class="p">,</span> <span class="s">"cache"</span><span class="p">,</span> <span class="n">default</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">join</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">,</span> <span class="s">'cache'</span><span class="p">))</span> <span class="c">#: Where Packages should store downloaded GPG key files</span> <span class="bp">self</span><span class="o">.</span><span class="n">keypath</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">join</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">cachepath</span><span class="p">,</span> <span class="s">'keys'</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="bp">self</span><span class="o">.</span><span class="n">keypath</span><span class="p">):</span> <span class="c"># create key directory if needed</span> <span class="n">os</span><span class="o">.</span><span class="n">makedirs</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">keypath</span><span class="p">)</span> <span class="c"># warn about deprecated magic groups</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">core</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">getboolean</span><span class="p">(</span><span class="s">"packages"</span><span class="p">,</span> <span class="s">"magic_groups"</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="bp">False</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">"Packages: Magic groups are deprecated and "</span> <span class="s">"will be removed in a future release"</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">"You can disable magic groups by setting "</span> <span class="s">"magic_groups=0 in [packages] in bcfg2.conf"</span><span class="p">)</span> <span class="c"># pylint: disable=C0301</span> <span class="c">#: The</span> <span class="c">#: :class:`Bcfg2.Server.Plugins.Packages.PackagesSources.PackagesSources`</span> <span class="c">#: object used to generate</span> <span class="c">#: :class:`Bcfg2.Server.Plugins.Packages.Source.Source` objects for</span> <span class="c">#: this plugin.</span> <span class="bp">self</span><span class="o">.</span><span class="n">sources</span> <span class="o">=</span> <span class="n">PackagesSources</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">,</span> <span class="s">"sources.xml"</span><span class="p">),</span> <span class="bp">self</span><span class="o">.</span><span class="n">cachepath</span><span class="p">,</span> <span class="n">core</span><span class="o">.</span><span class="n">fam</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">core</span><span class="o">.</span><span class="n">setup</span><span class="p">)</span> <span class="c">#: We cache</span> <span class="c">#: :class:`Bcfg2.Server.Plugins.Packages.Collection.Collection`</span> <span class="c">#: objects in ``collections`` so that calling :func:`Refresh`</span> <span class="c">#: or :func:`Reload` can tell the collection objects to clean</span> <span class="c">#: up their cache, but we don't actually use the cache to</span> <span class="c">#: return a ``Collection`` object when one is requested,</span> <span class="c">#: because that prevents new machines from working, since a</span> <span class="c">#: ``Collection`` object gets created by</span> <span class="c">#: :func:`get_additional_data`, which is called for all</span> <span class="c">#: clients at server startup and various other times. (It</span> <span class="c">#: would also prevent machines that change groups from working</span> <span class="c">#: properly; e.g., if you reinstall a machine with a new OS,</span> <span class="c">#: then returning a cached ``Collection`` object would give</span> <span class="c">#: the wrong sources to that client.) These are keyed by the</span> <span class="c">#: collection</span> <span class="c">#: :attr:`Bcfg2.Server.Plugins.Packages.Collection.Collection.cachekey`,</span> <span class="c">#: a unique key identifying the collection by its *config*,</span> <span class="c">#: which could be shared among multiple clients.</span> <span class="bp">self</span><span class="o">.</span><span class="n">collections</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">()</span> <span class="c">#: clients is a cache mapping of hostname -></span> <span class="c">#: :attr:`Bcfg2.Server.Plugins.Packages.Collection.Collection.cachekey`</span> <span class="c">#: Unlike :attr:`collections`, this _is_ used to return a</span> <span class="c">#: :class:`Bcfg2.Server.Plugins.Packages.Collection.Collection`</span> <span class="c">#: object when one is requested, so each entry is very</span> <span class="c">#: short-lived -- it's purged at the end of each client run.</span> <span class="bp">self</span><span class="o">.</span><span class="n">clients</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">()</span> <span class="c"># pylint: enable=C0301</span> <span class="n">__init__</span><span class="o">.</span><span class="n">__doc__</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">Plugin</span><span class="o">.</span><span class="n">Plugin</span><span class="o">.</span><span class="n">__init__</span><span class="o">.</span><span class="n">__doc__</span> <div class="viewcode-block" id="Packages.set_debug"><a class="viewcode-back" href="../../../../development/packages.html#Bcfg2.Server.Plugins.Packages.Packages.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">debug</span><span class="p">):</span> <span class="n">rv</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">Plugin</span><span class="o">.</span><span class="n">Plugin</span><span class="o">.</span><span class="n">set_debug</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">debug</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">sources</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">for</span> <span class="n">collection</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">collections</span><span class="o">.</span><span class="n">values</span><span class="p">():</span> <span class="n">collection</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="n">rv</span></div> <span class="n">set_debug</span><span class="o">.</span><span class="n">__doc__</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">Plugin</span><span class="o">.</span><span class="n">Plugin</span><span class="o">.</span><span class="n">set_debug</span><span class="o">.</span><span class="n">__doc__</span> <span class="nd">@property</span> <div class="viewcode-block" id="Packages.disableResolver"><a class="viewcode-back" href="../../../../development/packages.html#Bcfg2.Server.Plugins.Packages.Packages.disableResolver">[docs]</a> <span class="k">def</span> <span class="nf">disableResolver</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="sd">""" Report the state of the resolver. This can be disabled in</span> <span class="sd"> the configuration. Note that disabling metadata (see</span> <span class="sd"> :attr:`disableMetaData`) implies disabling the resolver.</span> <span class="sd"> This property cannot be set. """</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">disableMetaData</span><span class="p">:</span> <span class="c"># disabling metadata without disabling the resolver Breaks</span> <span class="c"># Things</span> <span class="k">return</span> <span class="bp">True</span> <span class="k">try</span><span class="p">:</span> <span class="k">return</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">core</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">getboolean</span><span class="p">(</span><span class="s">"packages"</span><span class="p">,</span> <span class="s">"resolver"</span><span class="p">)</span> <span class="k">except</span> <span class="p">(</span><span class="n">ConfigParser</span><span class="o">.</span><span class="n">NoSectionError</span><span class="p">,</span> <span class="n">ConfigParser</span><span class="o">.</span><span class="n">NoOptionError</span><span class="p">):</span> <span class="k">return</span> <span class="bp">False</span> <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span> <span class="c"># for historical reasons we also accept "enabled" and</span> <span class="c"># "disabled", which are not handled according to the</span> <span class="c"># Python docs but appear to be handled properly by</span> <span class="c"># ConfigParser in at least some versions</span> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">core</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">"packages"</span><span class="p">,</span> <span class="s">"resolver"</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="s">"enabled"</span><span class="p">)</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="o">==</span> <span class="s">"disabled"</span> </div> <span class="nd">@property</span> <div class="viewcode-block" id="Packages.disableMetaData"><a class="viewcode-back" href="../../../../development/packages.html#Bcfg2.Server.Plugins.Packages.Packages.disableMetaData">[docs]</a> <span class="k">def</span> <span class="nf">disableMetaData</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="sd">""" Report whether or not metadata processing is enabled.</span> <span class="sd"> This property cannot be set. """</span> <span class="k">try</span><span class="p">:</span> <span class="k">return</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">core</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">getboolean</span><span class="p">(</span><span class="s">"packages"</span><span class="p">,</span> <span class="s">"resolver"</span><span class="p">)</span> <span class="k">except</span> <span class="p">(</span><span class="n">ConfigParser</span><span class="o">.</span><span class="n">NoSectionError</span><span class="p">,</span> <span class="n">ConfigParser</span><span class="o">.</span><span class="n">NoOptionError</span><span class="p">):</span> <span class="k">return</span> <span class="bp">False</span> <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span> <span class="c"># for historical reasons we also accept "enabled" and</span> <span class="c"># "disabled"</span> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">core</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">"packages"</span><span class="p">,</span> <span class="s">"metadata"</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="s">"enabled"</span><span class="p">)</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="o">==</span> <span class="s">"disabled"</span> </div> <div class="viewcode-block" id="Packages.create_config"><a class="viewcode-back" href="../../../../development/packages.html#Bcfg2.Server.Plugins.Packages.Packages.create_config">[docs]</a> <span class="k">def</span> <span class="nf">create_config</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">""" Create yum/apt config for the specified client.</span> <span class="sd"> :param entry: The base entry to bind. This will be modified</span> <span class="sd"> in place.</span> <span class="sd"> :type entry: lxml.etree._Element</span> <span class="sd"> :param metadata: The client to create the config for.</span> <span class="sd"> :type metadata: Bcfg2.Server.Plugins.Metadata.ClientMetadata</span> <span class="sd"> """</span> <span class="n">attrib</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">(</span><span class="n">encoding</span><span class="o">=</span><span class="s">'ascii'</span><span class="p">,</span> <span class="n">owner</span><span class="o">=</span><span class="s">'root'</span><span class="p">,</span> <span class="n">group</span><span class="o">=</span><span class="s">'root'</span><span class="p">,</span> <span class="nb">type</span><span class="o">=</span><span class="s">'file'</span><span class="p">,</span> <span class="n">mode</span><span class="o">=</span><span class="s">'0644'</span><span class="p">,</span> <span class="n">important</span><span class="o">=</span><span class="s">'true'</span><span class="p">)</span> <span class="n">collection</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_collection</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">text</span> <span class="o">=</span> <span class="n">collection</span><span class="o">.</span><span class="n">get_config</span><span class="p">()</span> <span class="k">for</span> <span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span> <span class="ow">in</span> <span class="nb">list</span><span class="p">(</span><span class="n">attrib</span><span class="o">.</span><span class="n">items</span><span class="p">()):</span> <span class="n">entry</span><span class="o">.</span><span class="n">attrib</span><span class="o">.</span><span class="n">__setitem__</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span> </div> <div class="viewcode-block" id="Packages.HandleEntry"><a class="viewcode-back" href="../../../../development/packages.html#Bcfg2.Server.Plugins.Packages.Packages.HandleEntry">[docs]</a> <span class="k">def</span> <span class="nf">HandleEntry</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 configuration entries. ``HandleEntry`` handles</span> <span class="sd"> entries two different ways:</span> <span class="sd"> * All ``Package`` entries have their ``version`` and ``type``</span> <span class="sd"> attributes set according to the appropriate</span> <span class="sd"> :class:`Bcfg2.Server.Plugins.Packages.Collection.Collection`</span> <span class="sd"> object for this client.</span> <span class="sd"> * ``Path`` entries are delegated to :func:`create_config`</span> <span class="sd"> :param entry: The entry to bind</span> <span class="sd"> :type entry: lxml.etree._Element</span> <span class="sd"> :param metadata: The client metadata</span> <span class="sd"> :type metadata: Bcfg2.Server.Plugins.Metadata.ClientMetadata</span> <span class="sd"> :return: lxml.etree._Element - The fully bound entry</span> <span class="sd"> """</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="s">'Package'</span><span class="p">:</span> <span class="n">collection</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_collection</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">'version'</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">core</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">"packages"</span><span class="p">,</span> <span class="s">"version"</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="s">"auto"</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">'type'</span><span class="p">,</span> <span class="n">collection</span><span class="o">.</span><span class="n">ptype</span><span class="p">)</span> <span class="k">elif</span> <span class="n">entry</span><span class="o">.</span><span class="n">tag</span> <span class="o">==</span> <span class="s">'Path'</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">create_config</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">return</span> <span class="n">entry</span> </div> <div class="viewcode-block" id="Packages.HandlesEntry"><a class="viewcode-back" href="../../../../development/packages.html#Bcfg2.Server.Plugins.Packages.Packages.HandlesEntry">[docs]</a> <span class="k">def</span> <span class="nf">HandlesEntry</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">""" Determine if the given entry can be handled. Packages</span> <span class="sd"> handles two kinds of entries:</span> <span class="sd"> * ``Package`` entries are handled if the client has any</span> <span class="sd"> sources at all.</span> <span class="sd"> * ``Path`` entries are handled if they match the paths that</span> <span class="sd"> are handled by a backend that can produce client</span> <span class="sd"> configurations, e.g., :attr:`YUM_CONFIG_DEFAULT`,</span> <span class="sd"> :attr:`APT_CONFIG_DEFAULT`, or the overridden value of</span> <span class="sd"> either of those from the configuration.</span> <span class="sd"> :param entry: The entry to bind</span> <span class="sd"> :type entry: lxml.etree._Element</span> <span class="sd"> :param metadata: The client metadata</span> <span class="sd"> :type metadata: Bcfg2.Server.Plugins.Metadata.ClientMetadata</span> <span class="sd"> :return: bool - Whether or not this plugin can handle the entry</span> <span class="sd"> :raises: :class:`Bcfg2.Server.Plugin.exceptions.PluginExecutionError`</span> <span class="sd"> """</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="s">'Package'</span><span class="p">:</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">core</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">getboolean</span><span class="p">(</span><span class="s">"packages"</span><span class="p">,</span> <span class="s">"magic_groups"</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="bp">False</span><span class="p">):</span> <span class="n">collection</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_collection</span><span class="p">(</span><span class="n">metadata</span><span class="p">)</span> <span class="k">if</span> <span class="n">collection</span><span class="o">.</span><span class="n">magic_groups_match</span><span class="p">():</span> <span class="k">return</span> <span class="bp">True</span> <span class="k">else</span><span class="p">:</span> <span class="k">return</span> <span class="bp">True</span> <span class="k">elif</span> <span class="n">entry</span><span class="o">.</span><span class="n">tag</span> <span class="o">==</span> <span class="s">'Path'</span><span class="p">:</span> <span class="c"># managed entries for yum/apt configs</span> <span class="k">if</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="o">==</span> \ <span class="bp">self</span><span class="o">.</span><span class="n">core</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">"packages"</span><span class="p">,</span> <span class="s">"yum_config"</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="n">YUM_CONFIG_DEFAULT</span><span class="p">)</span> <span class="ow">or</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="o">==</span> \ <span class="bp">self</span><span class="o">.</span><span class="n">core</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">"packages"</span><span class="p">,</span> <span class="s">"apt_config"</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="n">APT_CONFIG_DEFAULT</span><span class="p">)):</span> <span class="k">return</span> <span class="bp">True</span> <span class="k">return</span> <span class="bp">False</span> </div> <span class="nd">@Bcfg2.Server.Plugin.track_statistics</span><span class="p">()</span> <div class="viewcode-block" id="Packages.validate_structures"><a class="viewcode-back" href="../../../../development/packages.html#Bcfg2.Server.Plugins.Packages.Packages.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">structures</span><span class="p">):</span> <span class="sd">""" Do the real work of Packages. This does two things:</span> <span class="sd"> #. Given the full list of all packages that apply to this</span> <span class="sd"> client from the specification, calls</span> <span class="sd"> :func:`_build_packages` to resolve dependencies, determine</span> <span class="sd"> unknown packages (i.e., those that are not in any</span> <span class="sd"> repository that applies to this client), and build a</span> <span class="sd"> complete package list.</span> <span class="sd"> #. Calls</span> <span class="sd"> :func:`Bcfg2.Server.Plugins.Packages.Collection.Collection.build_extra_structures`</span> <span class="sd"> to add any other extra data required by the backend (e.g.,</span> <span class="sd"> GPG keys)</span> <span class="sd"> :param metadata: The client metadata</span> <span class="sd"> :type metadata: Bcfg2.Server.Plugins.Metadata.ClientMetadata</span> <span class="sd"> :param metadata: The client metadata</span> <span class="sd"> :type metadata: Bcfg2.Server.Plugins.Metadata.ClientMetadata</span> <span class="sd"> :param structures: A list of lxml.etree._Element objects</span> <span class="sd"> describing the structures (i.e., bundles)</span> <span class="sd"> for this client. This can be modified in</span> <span class="sd"> place.</span> <span class="sd"> :type structures: list of lxml.etree._Element objects</span> <span class="sd"> :returns: None</span> <span class="sd"> """</span> <span class="n">collection</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_collection</span><span class="p">(</span><span class="n">metadata</span><span class="p">)</span> <span class="n">indep</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">'Independent'</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">_build_packages</span><span class="p">(</span><span class="n">metadata</span><span class="p">,</span> <span class="n">indep</span><span class="p">,</span> <span class="n">structures</span><span class="p">,</span> <span class="n">collection</span><span class="o">=</span><span class="n">collection</span><span class="p">)</span> <span class="n">collection</span><span class="o">.</span><span class="n">build_extra_structures</span><span class="p">(</span><span class="n">indep</span><span class="p">)</span> <span class="n">structures</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">indep</span><span class="p">)</span> </div> <span class="nd">@Bcfg2.Server.Plugin.track_statistics</span><span class="p">()</span> <div class="viewcode-block" id="Packages._build_packages"><a class="viewcode-back" href="../../../../development/packages.html#Bcfg2.Server.Plugins.Packages.Packages._build_packages">[docs]</a> <span class="k">def</span> <span class="nf">_build_packages</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">independent</span><span class="p">,</span> <span class="n">structures</span><span class="p">,</span> <span class="n">collection</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span> <span class="sd">""" Perform dependency resolution and build the complete list</span> <span class="sd"> of packages that need to be included in the specification by</span> <span class="sd"> :func:`validate_structures`, based on the initial list of</span> <span class="sd"> packages.</span> <span class="sd"> :param metadata: The client metadata</span> <span class="sd"> :type metadata: Bcfg2.Server.Plugins.Metadata.ClientMetadata</span> <span class="sd"> :param independent: The XML tag to add package entries</span> <span class="sd"> generated by dependency resolution to.</span> <span class="sd"> This will be modified in place.</span> <span class="sd"> :type independent: lxml.etree._Element</span> <span class="sd"> :param structures: A list of lxml.etree._Element objects</span> <span class="sd"> describing the structures (i.e., bundles)</span> <span class="sd"> for this client</span> <span class="sd"> :type structures: list of lxml.etree._Element objects</span> <span class="sd"> :param collection: The collection of sources for this client.</span> <span class="sd"> If none is given, one will be created with</span> <span class="sd"> :func:`get_collection`</span> <span class="sd"> :type collection: Bcfg2.Server.Plugins.Packages.Collection.Collection</span> <span class="sd"> """</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">disableResolver</span><span class="p">:</span> <span class="c"># Config requests no resolver</span> <span class="k">return</span> <span class="k">if</span> <span class="n">collection</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span> <span class="n">collection</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_collection</span><span class="p">(</span><span class="n">metadata</span><span class="p">)</span> <span class="n">initial</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span> <span class="n">to_remove</span> <span class="o">=</span> <span class="p">[]</span> <span class="n">groups</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">pkg</span> <span class="ow">in</span> <span class="n">struct</span><span class="o">.</span><span class="n">xpath</span><span class="p">(</span><span class="s">'//Package | //BoundPackage'</span><span class="p">):</span> <span class="k">if</span> <span class="n">pkg</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">initial</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">collection</span><span class="o">.</span><span class="n">packages_from_entry</span><span class="p">(</span><span class="n">pkg</span><span class="p">))</span> <span class="k">elif</span> <span class="n">pkg</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">"group"</span><span class="p">):</span> <span class="n">groups</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">pkg</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">"group"</span><span class="p">),</span> <span class="n">pkg</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">"type"</span><span class="p">)))</span> <span class="n">to_remove</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">pkg</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">"Packages: Malformed Package: </span><span class="si">%s</span><span class="s">"</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">tostring</span><span class="p">(</span> <span class="n">pkg</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="c"># base is the set of initial packages explicitly given in the</span> <span class="c"># specification, packages from expanded package groups, and</span> <span class="c"># packages essential to the distribution</span> <span class="n">base</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">initial</span><span class="p">)</span> <span class="c"># remove package groups</span> <span class="k">for</span> <span class="n">el</span> <span class="ow">in</span> <span class="n">to_remove</span><span class="p">:</span> <span class="n">el</span><span class="o">.</span><span class="n">getparent</span><span class="p">()</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">el</span><span class="p">)</span> <span class="n">gpkgs</span> <span class="o">=</span> <span class="n">collection</span><span class="o">.</span><span class="n">get_groups</span><span class="p">(</span><span class="n">groups</span><span class="p">)</span> <span class="k">for</span> <span class="n">pkgs</span> <span class="ow">in</span> <span class="n">gpkgs</span><span class="o">.</span><span class="n">values</span><span class="p">():</span> <span class="n">base</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">pkgs</span><span class="p">)</span> <span class="c"># essential pkgs are those marked as such by the distribution</span> <span class="n">base</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">collection</span><span class="o">.</span><span class="n">get_essential</span><span class="p">())</span> <span class="n">packages</span><span class="p">,</span> <span class="n">unknown</span> <span class="o">=</span> <span class="n">collection</span><span class="o">.</span><span class="n">complete</span><span class="p">(</span><span class="n">base</span><span class="p">)</span> <span class="k">if</span> <span class="n">unknown</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">"Packages: Got </span><span class="si">%d</span><span class="s"> unknown entries"</span> <span class="o">%</span> <span class="nb">len</span><span class="p">(</span><span class="n">unknown</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">"Packages: </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="nb">list</span><span class="p">(</span><span class="n">unknown</span><span class="p">))</span> <span class="n">newpkgs</span> <span class="o">=</span> <span class="n">collection</span><span class="o">.</span><span class="n">get_new_packages</span><span class="p">(</span><span class="n">initial</span><span class="p">,</span> <span class="n">packages</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">debug_log</span><span class="p">(</span><span class="s">"Packages: </span><span class="si">%d</span><span class="s"> base, </span><span class="si">%d</span><span class="s"> complete, </span><span class="si">%d</span><span class="s"> new"</span> <span class="o">%</span> <span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">base</span><span class="p">),</span> <span class="nb">len</span><span class="p">(</span><span class="n">packages</span><span class="p">),</span> <span class="nb">len</span><span class="p">(</span><span class="n">newpkgs</span><span class="p">)))</span> <span class="n">newpkgs</span><span class="o">.</span><span class="n">sort</span><span class="p">()</span> <span class="n">collection</span><span class="o">.</span><span class="n">packages_to_entry</span><span class="p">(</span><span class="n">newpkgs</span><span class="p">,</span> <span class="n">independent</span><span class="p">)</span> </div> <span class="nd">@Bcfg2.Server.Plugin.track_statistics</span><span class="p">()</span> <div class="viewcode-block" id="Packages.Refresh"><a class="viewcode-back" href="../../../../development/packages.html#Bcfg2.Server.Plugins.Packages.Packages.Refresh">[docs]</a> <span class="k">def</span> <span class="nf">Refresh</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="sd">""" Packages.Refresh() => True|False</span> <span class="sd"> Reload configuration specification and download sources """</span> <span class="bp">self</span><span class="o">.</span><span class="n">_load_config</span><span class="p">(</span><span class="n">force_update</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span> <span class="k">return</span> <span class="bp">True</span> </div> <span class="nd">@Bcfg2.Server.Plugin.track_statistics</span><span class="p">()</span> <div class="viewcode-block" id="Packages.Reload"><a class="viewcode-back" href="../../../../development/packages.html#Bcfg2.Server.Plugins.Packages.Packages.Reload">[docs]</a> <span class="k">def</span> <span class="nf">Reload</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="sd">""" Packages.Refresh() => True|False</span> <span class="sd"> Reload configuration specification and sources """</span> <span class="bp">self</span><span class="o">.</span><span class="n">_load_config</span><span class="p">()</span> <span class="k">return</span> <span class="bp">True</span> </div> <span class="k">def</span> <span class="nf">_load_config</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">force_update</span><span class="o">=</span><span class="bp">False</span><span class="p">):</span> <span class="sd">"""</span> <span class="sd"> Load the configuration data and setup sources</span> <span class="sd"> :param force_update: Ignore all locally cached and downloaded</span> <span class="sd"> data and fetch the metadata anew from the</span> <span class="sd"> upstream repository.</span> <span class="sd"> :type force_update: bool</span> <span class="sd"> """</span> <span class="bp">self</span><span class="o">.</span><span class="n">_load_sources</span><span class="p">(</span><span class="n">force_update</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">_load_gpg_keys</span><span class="p">(</span><span class="n">force_update</span><span class="p">)</span> <span class="k">def</span> <span class="nf">_load_sources</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">force_update</span><span class="p">):</span> <span class="sd">""" Load sources from the config, downloading if necessary.</span> <span class="sd"> :param force_update: Ignore all locally cached and downloaded</span> <span class="sd"> data and fetch the metadata anew from the</span> <span class="sd"> upstream repository.</span> <span class="sd"> :type force_update: bool</span> <span class="sd"> """</span> <span class="n">cachefiles</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span> <span class="k">for</span> <span class="n">collection</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">collections</span><span class="o">.</span><span class="n">values</span><span class="p">()):</span> <span class="n">cachefiles</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">collection</span><span class="o">.</span><span class="n">cachefiles</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">disableMetaData</span><span class="p">:</span> <span class="n">collection</span><span class="o">.</span><span class="n">setup_data</span><span class="p">(</span><span class="n">force_update</span><span class="p">)</span> <span class="c"># clear Collection caches</span> <span class="bp">self</span><span class="o">.</span><span class="n">clients</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">()</span> <span class="bp">self</span><span class="o">.</span><span class="n">collections</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">()</span> <span class="k">for</span> <span class="n">source</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">sources</span><span class="o">.</span><span class="n">entries</span><span class="p">:</span> <span class="n">cachefiles</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">source</span><span class="o">.</span><span class="n">cachefile</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">disableMetaData</span><span class="p">:</span> <span class="n">source</span><span class="o">.</span><span class="n">setup_data</span><span class="p">(</span><span class="n">force_update</span><span class="p">)</span> <span class="k">for</span> <span class="n">cfile</span> <span class="ow">in</span> <span class="n">glob</span><span class="o">.</span><span class="n">glob</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">cachepath</span><span class="p">,</span> <span class="s">"cache-*"</span><span class="p">)):</span> <span class="k">if</span> <span class="n">cfile</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">cachefiles</span><span class="p">:</span> <span class="k">try</span><span class="p">:</span> <span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">isdir</span><span class="p">(</span><span class="n">cfile</span><span class="p">):</span> <span class="n">shutil</span><span class="o">.</span><span class="n">rmtree</span><span class="p">(</span><span class="n">cfile</span><span class="p">)</span> <span class="k">else</span><span class="p">:</span> <span class="n">os</span><span class="o">.</span><span class="n">unlink</span><span class="p">(</span><span class="n">cfile</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">"Packages: Could not remove cache file "</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">cfile</span><span class="p">,</span> <span class="n">err</span><span class="p">))</span> <span class="k">def</span> <span class="nf">_load_gpg_keys</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">force_update</span><span class="p">):</span> <span class="sd">""" Load GPG keys from the config, downloading if necessary.</span> <span class="sd"> :param force_update: Ignore all locally cached and downloaded</span> <span class="sd"> data and fetch the metadata anew from the</span> <span class="sd"> upstream repository.</span> <span class="sd"> :type force_update: bool</span> <span class="sd"> """</span> <span class="n">keyfiles</span> <span class="o">=</span> <span class="p">[]</span> <span class="n">keys</span> <span class="o">=</span> <span class="p">[]</span> <span class="k">for</span> <span class="n">source</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">sources</span><span class="o">.</span><span class="n">entries</span><span class="p">:</span> <span class="k">for</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">source</span><span class="o">.</span><span class="n">gpgkeys</span><span class="p">:</span> <span class="n">localfile</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">join</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">keypath</span><span class="p">,</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">basename</span><span class="p">(</span><span class="n">key</span><span class="o">.</span><span class="n">rstrip</span><span class="p">(</span><span class="s">"/"</span><span class="p">)))</span> <span class="k">if</span> <span class="n">localfile</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">keyfiles</span><span class="p">:</span> <span class="n">keyfiles</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">localfile</span><span class="p">)</span> <span class="k">if</span> <span class="p">((</span><span class="n">force_update</span> <span class="ow">and</span> <span class="n">key</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">keys</span><span class="p">)</span> <span class="ow">or</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">localfile</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">"Packages: Downloading and parsing </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">try</span><span class="p">:</span> <span class="nb">open</span><span class="p">(</span><span class="n">localfile</span><span class="p">,</span> <span class="s">'w'</span><span class="p">)</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">urlopen</span><span class="p">(</span><span class="n">key</span><span class="p">)</span><span class="o">.</span><span class="n">read</span><span class="p">())</span> <span class="n">keys</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">key</span><span class="p">)</span> <span class="k">except</span> <span class="n">HTTPError</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">"Packages: Error downloading </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">key</span><span class="p">,</span> <span class="n">err</span><span class="p">))</span> <span class="k">except</span> <span class="ne">IOError</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">"Packages: Error writing </span><span class="si">%s</span><span class="s"> to </span><span class="si">%s</span><span class="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">key</span><span class="p">,</span> <span class="n">localfile</span><span class="p">,</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">"Packages: Unknown error fetching "</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">key</span><span class="p">,</span> <span class="n">err</span><span class="p">))</span> <span class="k">for</span> <span class="n">kfile</span> <span class="ow">in</span> <span class="n">glob</span><span class="o">.</span><span class="n">glob</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">keypath</span><span class="p">,</span> <span class="s">"*"</span><span class="p">)):</span> <span class="k">if</span> <span class="n">kfile</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">keyfiles</span><span class="p">:</span> <span class="n">os</span><span class="o">.</span><span class="n">unlink</span><span class="p">(</span><span class="n">kfile</span><span class="p">)</span> <span class="nd">@Bcfg2.Server.Plugin.track_statistics</span><span class="p">()</span> <div class="viewcode-block" id="Packages.get_collection"><a class="viewcode-back" href="../../../../development/packages.html#Bcfg2.Server.Plugins.Packages.Packages.get_collection">[docs]</a> <span class="k">def</span> <span class="nf">get_collection</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 a</span> <span class="sd"> :class:`Bcfg2.Server.Plugins.Packages.Collection.Collection`</span> <span class="sd"> object for this client.</span> <span class="sd"> :param metadata: The client metadata to get a Collection for</span> <span class="sd"> :type metadata: Bcfg2.Server.Plugins.Metadata.ClientMetadata</span> <span class="sd"> :returns: An instance of the appropriate subclass of</span> <span class="sd"> :class:`Bcfg2.Server.Plugins.Packages.Collection.Collection`</span> <span class="sd"> that contains all relevant sources that apply to the</span> <span class="sd"> given client</span> <span class="sd"> """</span> <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">sources</span><span class="o">.</span><span class="n">loaded</span><span class="p">:</span> <span class="c"># if sources.xml has not received a FAM event yet, defer;</span> <span class="c"># instantiate a dummy Collection object</span> <span class="k">return</span> <span class="n">Collection</span><span class="p">(</span><span class="n">metadata</span><span class="p">,</span> <span class="p">[],</span> <span class="bp">self</span><span class="o">.</span><span class="n">cachepath</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">core</span><span class="o">.</span><span class="n">fam</span><span class="p">)</span> <span class="k">if</span> <span class="n">metadata</span><span class="o">.</span><span class="n">hostname</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">clients</span><span class="p">:</span> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">collections</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">clients</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="n">sclasses</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span> <span class="n">relevant</span> <span class="o">=</span> <span class="nb">list</span><span class="p">()</span> <span class="k">for</span> <span class="n">source</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">sources</span><span class="o">.</span><span class="n">entries</span><span class="p">:</span> <span class="k">if</span> <span class="n">source</span><span class="o">.</span><span class="n">applies</span><span class="p">(</span><span class="n">metadata</span><span class="p">):</span> <span class="n">relevant</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="n">sclasses</span><span class="o">.</span><span class="n">update</span><span class="p">([</span><span class="n">source</span><span class="o">.</span><span class="n">__class__</span><span class="p">])</span> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">sclasses</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">warning</span><span class="p">(</span><span class="s">"Packages: Multiple source types found for "</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="s">","</span><span class="o">.</span><span class="n">join</span><span class="p">([</span><span class="n">s</span><span class="o">.</span><span class="n">__name__</span> <span class="k">for</span> <span class="n">s</span> <span class="ow">in</span> <span class="n">sclasses</span><span class="p">]))</span> <span class="n">cclass</span> <span class="o">=</span> <span class="n">Collection</span> <span class="k">elif</span> <span class="nb">len</span><span class="p">(</span><span class="n">sclasses</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">"Packages: No sources found for </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="n">metadata</span><span class="o">.</span><span class="n">hostname</span><span class="p">)</span> <span class="n">cclass</span> <span class="o">=</span> <span class="n">Collection</span> <span class="k">else</span><span class="p">:</span> <span class="n">cclass</span> <span class="o">=</span> <span class="n">get_collection_class</span><span class="p">(</span> <span class="n">sclasses</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span><span class="o">.</span><span class="n">__name__</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s">"Source"</span><span class="p">,</span> <span class="s">""</span><span class="p">))</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">debug_flag</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">"Packages: Using </span><span class="si">%s</span><span class="s"> for Collection of sources "</span> <span class="s">"for </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">cclass</span><span class="o">.</span><span class="n">__name__</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="n">collection</span> <span class="o">=</span> <span class="n">cclass</span><span class="p">(</span><span class="n">metadata</span><span class="p">,</span> <span class="n">relevant</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">cachepath</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">core</span><span class="o">.</span><span class="n">fam</span><span class="p">,</span> <span class="n">debug</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">debug_flag</span><span class="p">)</span> <span class="n">ckey</span> <span class="o">=</span> <span class="n">collection</span><span class="o">.</span><span class="n">cachekey</span> <span class="bp">self</span><span class="o">.</span><span class="n">clients</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="o">=</span> <span class="n">ckey</span> <span class="bp">self</span><span class="o">.</span><span class="n">collections</span><span class="p">[</span><span class="n">ckey</span><span class="p">]</span> <span class="o">=</span> <span class="n">collection</span> <span class="k">return</span> <span class="n">collection</span> </div> <div class="viewcode-block" id="Packages.get_additional_data"><a class="viewcode-back" href="../../../../development/packages.html#Bcfg2.Server.Plugins.Packages.Packages.get_additional_data">[docs]</a> <span class="k">def</span> <span class="nf">get_additional_data</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">""" Return additional data for the given client. This will be</span> <span class="sd"> a dict containing a single key, ``sources``, whose value is a</span> <span class="sd"> list of data returned from</span> <span class="sd"> :func:`Bcfg2.Server.Plugins.Packages.Collection.Collection.get_additional_data`,</span> <span class="sd"> namely, a list of</span> <span class="sd"> :attr:`Bcfg2.Server.Plugins.Packages.Source.Source.url_map`</span> <span class="sd"> data.</span> <span class="sd"> :param metadata: The client metadata</span> <span class="sd"> :type metadata: Bcfg2.Server.Plugins.Metadata.ClientMetadata</span> <span class="sd"> :return: dict of lists of ``url_map`` data</span> <span class="sd"> """</span> <span class="n">collection</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_collection</span><span class="p">(</span><span class="n">metadata</span><span class="p">)</span> <span class="k">return</span> <span class="nb">dict</span><span class="p">(</span><span class="n">sources</span><span class="o">=</span><span class="n">collection</span><span class="o">.</span><span class="n">get_additional_data</span><span class="p">())</span> </div> <div class="viewcode-block" id="Packages.end_client_run"><a class="viewcode-back" href="../../../../development/packages.html#Bcfg2.Server.Plugins.Packages.Packages.end_client_run">[docs]</a> <span class="k">def</span> <span class="nf">end_client_run</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">""" Hook to clear the cache for this client in</span> <span class="sd"> :attr:`clients`, which must persist only the duration of a</span> <span class="sd"> client run.</span> <span class="sd"> :param metadata: The client metadata</span> <span class="sd"> :type metadata: Bcfg2.Server.Plugins.Metadata.ClientMetadata</span> <span class="sd"> """</span> <span class="k">if</span> <span class="n">metadata</span><span class="o">.</span><span class="n">hostname</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">clients</span><span class="p">:</span> <span class="k">del</span> <span class="bp">self</span><span class="o">.</span><span class="n">clients</span><span class="p">[</span><span class="n">metadata</span><span class="o">.</span><span class="n">hostname</span><span class="p">]</span> </div> <div class="viewcode-block" id="Packages.end_statistics"><a class="viewcode-back" href="../../../../development/packages.html#Bcfg2.Server.Plugins.Packages.Packages.end_statistics">[docs]</a> <span class="k">def</span> <span class="nf">end_statistics</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">""" Hook to clear the cache for this client in :attr:`clients`</span> <span class="sd"> once statistics are processed to ensure that a stray cached</span> <span class="sd"> :class:`Bcfg2.Server.Plugins.Packages.Collection.Collection`</span> <span class="sd"> object is not built during statistics and preserved until a</span> <span class="sd"> subsequent client run.</span> <span class="sd"> :param metadata: The client metadata</span> <span class="sd"> :type metadata: Bcfg2.Server.Plugins.Metadata.ClientMetadata</span> <span class="sd"> """</span> <span class="bp">self</span><span class="o">.</span><span class="n">end_client_run</span><span class="p">(</span><span class="n">metadata</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> <li><a href="../Plugins.html" >Bcfg2.Server.Plugins</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>