Sophie

Sophie

distrib > Fedora > 17 > i386 > media > updates > by-pkgid > b50d8ee6d7871fcc13c0677a9364ed59 > files > 52

bcfg2-doc-1.3.0-1.fc17.noarch.rpm



<!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.Collection &mdash; 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.Packages" href="../Packages.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> |&nbsp;</li>
	<!--<li><a href="../../../../../search.html">search</a> |&nbsp;</li>-->
	<li><a href="../../../../../help/index.html">help</a> |&nbsp;</li>
	<li><a href="../../../../../contents.html">documentation </a> &raquo;</li>

          <li><a href="../../../../index.html" >Module code</a> &raquo;</li>
          <li><a href="../../Plugins.html" >Bcfg2.Server.Plugins</a> &raquo;</li>
          <li><a href="../Packages.html" accesskey="U">Bcfg2.Server.Plugins.Packages</a> &raquo;</li> 
      </ul>
    </div>
  

    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body">
            
  <h1>Source code for Bcfg2.Server.Plugins.Packages.Collection</h1><div class="highlight"><pre>
<span class="sd">&quot;&quot;&quot; ``Collection`` objects represent the set of</span>
<span class="sd">:class:`Bcfg2.Server.Plugins.Packages.Source.Source` objects that</span>
<span class="sd">apply to a given client, and can be used to query all software</span>
<span class="sd">repositories for a client in aggregate.  In some cases this can give</span>
<span class="sd">faster or more accurate results.</span>

<span class="sd">In most cases, ``Collection`` methods have been designed to defer the</span>
<span class="sd">call to the Sources in the ``Collection`` and aggregate the results as</span>
<span class="sd">appropriate.  The simplest ``Collection`` implemention is thus often a</span>
<span class="sd">simple subclass that adds no additional functionality.</span>

<span class="sd">Overriding Methods</span>
<span class="sd">------------------</span>

<span class="sd">As noted above, the ``Collection`` object is written expressly so that</span>
<span class="sd">you can subclass it and override no methods or attributes, and it will</span>
<span class="sd">work by deferring all calls to the Source objects it contains.  There</span>
<span class="sd">are thus three approaches to writing a ``Collection`` subclass:</span>

<span class="sd">#. Keep the superclass almost entirely intact and defer to the</span>
<span class="sd">   ``Source`` objects inside it. For an example of this kind of</span>
<span class="sd">   ``Collection`` object, see</span>
<span class="sd">   :mod:`Bcfg2.Server.Plugins.Packages.Apt`.</span>

<span class="sd">#. Keep :func:`Collection.complete` intact, and override the methods</span>
<span class="sd">   it calls: :func:`Collection.is_package`,</span>
<span class="sd">   :func:`Collection.is_virtual_package`, :func:`Collection.get_deps`,</span>
<span class="sd">   :func:`Collection.get_provides`, :func:`Collection.get_vpkgs`, and</span>
<span class="sd">   :func:`Collection.setup_data`.  There are no examples of this kind</span>
<span class="sd">   of ``Collection`` subclass yet.</span>

<span class="sd">#. Provide your own implementation of :func:`Collection.complete`, in</span>
<span class="sd">   which case you do not have to override the above methods.  You may</span>
<span class="sd">   want to override :func:`Collection.packages_from_entry`,</span>
<span class="sd">   :func:`Collection.packages_to_entry`, and</span>
<span class="sd">   :func:`Collection.get_new_packages`.  For an example of this kind</span>
<span class="sd">   of ``Collection`` object, see</span>
<span class="sd">   :mod:`Bcfg2.Server.Plugins.Packages.yum`.</span>

<span class="sd">In either case, you may want to override</span>
<span class="sd">:func:`Collection.get_groups`, :func:`Collection.get_group`,</span>
<span class="sd">:func:`Collection.get_essential`, :func:`Collection.get_config`,</span>
<span class="sd">:func:`Collection.filter_unknown`, and</span>
<span class="sd">:func:`Collection.build_extra_structures`.</span>

<span class="sd">.. _pkg-objects:</span>

<span class="sd">Conversion Between Package Objects and XML Entries</span>
<span class="sd">--------------------------------------------------</span>

<span class="sd">Collection objects have to translate Bcfg2 entries,</span>
<span class="sd">:class:`lxml.etree._Element` objects, into objects suitable for use by</span>
<span class="sd">the backend for resolving dependencies.  This is handled by two</span>
<span class="sd">functions:</span>

<span class="sd">* :func:`Collection.packages_from_entry` is called to translate an XML</span>
<span class="sd">  entry into a list of packages;</span>

<span class="sd">* :func:`Collection.packages_to_entry` is called to translate a list</span>
<span class="sd">  of packages back into an XML entry.</span>

<span class="sd">Because of this translation layer, the return type of any functions</span>
<span class="sd">below that return packages (e.g., :func:`Collection.get_group`) is</span>
<span class="sd">actually indeterminate; they must return an object suitable for</span>
<span class="sd">passing to :func:`Collection.packages_to_entry`.  Similarly, functions</span>
<span class="sd">that take a package as an argument (e.g.,</span>
<span class="sd">:func:`Collection.is_package`) take the appropriate package object.</span>
<span class="sd">In the documentation below, the actual parameter return type (usually</span>
<span class="sd">.``string``) used in this base implementation is noted, as well as</span>
<span class="sd">this fact.</span>

<span class="sd">The Collection Module</span>
<span class="sd">---------------------</span>
<span class="sd">&quot;&quot;&quot;</span>

<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">import</span> <span class="nn">copy</span>
<span class="kn">import</span> <span class="nn">logging</span>
<span class="kn">import</span> <span class="nn">lxml.etree</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="nb">any</span><span class="p">,</span> <span class="n">md5</span>  <span class="c"># pylint: disable=W0622</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="n">__name__</span><span class="p">)</span>


<div class="viewcode-block" id="Collection"><a class="viewcode-back" href="../../../../../development/packages.html#Bcfg2.Server.Plugins.Packages.Collection.Collection">[docs]</a><span class="k">class</span> <span class="nc">Collection</span><span class="p">(</span><span class="nb">list</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">Debuggable</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot; ``Collection`` objects represent the set of</span>
<span class="sd">    :class:`Bcfg2.Server.Plugins.Packages.Source` objects that apply</span>
<span class="sd">    to a given client, and can be used to query all software</span>
<span class="sd">    repositories for a client in aggregate.  In some cases this can</span>
<span class="sd">    give faster or more accurate results. &quot;&quot;&quot;</span>

    <span class="c">#: Whether or not this Packages backend supports package groups</span>
    <span class="n">__package_groups__</span> <span class="o">=</span> <span class="bp">False</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">metadata</span><span class="p">,</span> <span class="n">sources</span><span class="p">,</span> <span class="n">cachepath</span><span class="p">,</span> <span class="n">basepath</span><span class="p">,</span> <span class="n">fam</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="sd">&quot;&quot;&quot;</span>
<span class="sd">        :param metadata: The client metadata for this collection</span>
<span class="sd">        :type metadata: Bcfg2.Server.Plugins.Metadata.ClientMetadata</span>
<span class="sd">        :param sources: A list of all sources known to the server that</span>
<span class="sd">                        will be used to generate the list of sources</span>
<span class="sd">                        that apply to this client</span>
<span class="sd">        :type sources: list of</span>
<span class="sd">                       :class:`Bcfg2.Server.Plugins.Packages.Source.Source`</span>
<span class="sd">                       objects</span>
<span class="sd">        :param cachepath: The filesystem path where cache and other temporary</span>
<span class="sd">                          data will be stored</span>
<span class="sd">        :type cachepath: string</span>
<span class="sd">        :param basepath: The filesystem path to the Packages plugin</span>
<span class="sd">                         directory, where more permanent data can be</span>
<span class="sd">                         stored</span>
<span class="sd">        :type basepath: string</span>
<span class="sd">        :param fam: A file monitor object to use if this Collection</span>
<span class="sd">                    needs to monitor for file activity</span>
<span class="sd">        :type fam: Bcfg2.Server.FileMonitor.FileMonitor</span>
<span class="sd">        :param debug: Enable debugging output</span>
<span class="sd">        :type debug: bool</span>

<span class="sd">        .. -----</span>
<span class="sd">        .. autoattribute:: __package_groups__</span>
<span class="sd">        &quot;&quot;&quot;</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">Debuggable</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="nb">list</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">sources</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">debug_flag</span> <span class="o">=</span> <span class="n">debug</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">metadata</span> <span class="o">=</span> <span class="n">metadata</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">basepath</span> <span class="o">=</span> <span class="n">basepath</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">cachepath</span> <span class="o">=</span> <span class="n">cachepath</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">virt_pkgs</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">fam</span> <span class="o">=</span> <span class="n">fam</span>

        <span class="k">try</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">setup</span> <span class="o">=</span> <span class="n">sources</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">setup</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">ptype</span> <span class="o">=</span> <span class="n">sources</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">ptype</span>
        <span class="k">except</span> <span class="ne">IndexError</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">setup</span> <span class="o">=</span> <span class="bp">None</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">ptype</span> <span class="o">=</span> <span class="s">&quot;unknown&quot;</span>

    <span class="nd">@property</span>
<div class="viewcode-block" id="Collection.cachekey"><a class="viewcode-back" href="../../../../../development/packages.html#Bcfg2.Server.Plugins.Packages.Collection.Collection.cachekey">[docs]</a>    <span class="k">def</span> <span class="nf">cachekey</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot; A unique identifier for the set of sources contained in</span>
<span class="sd">        this ``Collection`` object.  This is unique to a set of</span>
<span class="sd">        sources, **not** necessarily to the client, which lets clients</span>
<span class="sd">        with identical sources share cache data.&quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="n">md5</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">sourcelist</span><span class="p">()</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s">&#39;UTF-8&#39;</span><span class="p">))</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">()</span>
</div>
<div class="viewcode-block" id="Collection.get_config"><a class="viewcode-back" href="../../../../../development/packages.html#Bcfg2.Server.Plugins.Packages.Collection.Collection.get_config">[docs]</a>    <span class="k">def</span> <span class="nf">get_config</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot; Get the configuration for the package tool used by this</span>
<span class="sd">        source type.  This should be a config appropriate for use on</span>
<span class="sd">        either the server (to resolve dependencies) or the client.</span>

<span class="sd">        Subclasses must override this method in order to be able to</span>
<span class="sd">        generate configs.  By default it logs an error and returns the</span>
<span class="sd">        empty string.</span>

<span class="sd">        :returns: string &quot;&quot;&quot;</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">&quot;Packages: Cannot generate config for host </span><span class="si">%s</span><span class="s"> with &quot;</span>
                          <span class="s">&quot;no sources or multiple source types&quot;</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">hostname</span><span class="p">)</span>
        <span class="k">return</span> <span class="s">&quot;&quot;</span>
</div>
<div class="viewcode-block" id="Collection.sourcelist"><a class="viewcode-back" href="../../../../../development/packages.html#Bcfg2.Server.Plugins.Packages.Collection.Collection.sourcelist">[docs]</a>    <span class="k">def</span> <span class="nf">sourcelist</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot; Get a human-readable list of sources in this collection,</span>
<span class="sd">        including some information about each source.</span>

<span class="sd">        :returns: string &quot;&quot;&quot;</span>
        <span class="n">srcs</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="p">:</span>
            <span class="k">for</span> <span class="n">url_map</span> <span class="ow">in</span> <span class="n">source</span><span class="o">.</span><span class="n">url_map</span><span class="p">:</span>
                <span class="k">if</span> <span class="n">url_map</span><span class="p">[</span><span class="s">&#39;arch&#39;</span><span class="p">]</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">metadata</span><span class="o">.</span><span class="n">groups</span><span class="p">:</span>
                    <span class="k">continue</span>
                <span class="n">reponame</span> <span class="o">=</span> <span class="n">source</span><span class="o">.</span><span class="n">get_repo_name</span><span class="p">(</span><span class="n">url_map</span><span class="p">)</span>
                <span class="n">srcs</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s">&quot;Name: </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">reponame</span><span class="p">)</span>
                <span class="n">srcs</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s">&quot;  Type: </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">source</span><span class="o">.</span><span class="n">ptype</span><span class="p">)</span>
                <span class="k">if</span> <span class="n">url_map</span><span class="p">[</span><span class="s">&#39;url&#39;</span><span class="p">]:</span>
                    <span class="n">srcs</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s">&quot;  URL: </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">url_map</span><span class="p">[</span><span class="s">&#39;url&#39;</span><span class="p">])</span>
                <span class="k">elif</span> <span class="n">url_map</span><span class="p">[</span><span class="s">&#39;rawurl&#39;</span><span class="p">]:</span>
                    <span class="n">srcs</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s">&quot;  RAWURL: </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">url_map</span><span class="p">[</span><span class="s">&#39;rawurl&#39;</span><span class="p">])</span>
                <span class="k">if</span> <span class="n">source</span><span class="o">.</span><span class="n">gpgkeys</span><span class="p">:</span>
                    <span class="n">srcs</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s">&quot;  GPG Key(s): </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="s">&quot;, &quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">source</span><span class="o">.</span><span class="n">gpgkeys</span><span class="p">))</span>
                <span class="k">else</span><span class="p">:</span>
                    <span class="n">srcs</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s">&quot;  GPG Key(s): None&quot;</span><span class="p">)</span>
                <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">source</span><span class="o">.</span><span class="n">blacklist</span><span class="p">):</span>
                    <span class="n">srcs</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s">&quot;  Blacklist: </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span>
                                <span class="s">&quot;, &quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">source</span><span class="o">.</span><span class="n">blacklist</span><span class="p">))</span>
                <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">source</span><span class="o">.</span><span class="n">whitelist</span><span class="p">):</span>
                    <span class="n">srcs</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s">&quot;  Whitelist: </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span>
                                <span class="s">&quot;, &quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">source</span><span class="o">.</span><span class="n">whitelist</span><span class="p">))</span>
                <span class="n">srcs</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s">&quot;&quot;</span><span class="p">)</span>
        <span class="k">return</span> <span class="s">&quot;</span><span class="se">\n</span><span class="s">&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">srcs</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="Collection.get_relevant_groups"><a class="viewcode-back" href="../../../../../development/packages.html#Bcfg2.Server.Plugins.Packages.Collection.Collection.get_relevant_groups">[docs]</a>    <span class="k">def</span> <span class="nf">get_relevant_groups</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot; Get all groups that might be relevant to determining which</span>
<span class="sd">        sources apply to this collection&#39;s client.</span>

<span class="sd">        The base implementation simply aggregates the results of</span>
<span class="sd">        :func:`Bcfg2.Server.Plugins.Packages.Source.Source.get_relevant_groups`</span>

<span class="sd">        :return: list of strings - group names</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">groups</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="p">:</span>
            <span class="n">groups</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">source</span><span class="o">.</span><span class="n">get_relevant_groups</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">metadata</span><span class="p">))</span>
        <span class="k">return</span> <span class="nb">sorted</span><span class="p">(</span><span class="nb">list</span><span class="p">(</span><span class="nb">set</span><span class="p">(</span><span class="n">groups</span><span class="p">)))</span>
</div>
    <span class="nd">@property</span>
<div class="viewcode-block" id="Collection.basegroups"><a class="viewcode-back" href="../../../../../development/packages.html#Bcfg2.Server.Plugins.Packages.Collection.Collection.basegroups">[docs]</a>    <span class="k">def</span> <span class="nf">basegroups</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot; Get a list of group names used by this Collection type in</span>
<span class="sd">        resolution of</span>
<span class="sd">        :ref:`server-plugins-generators-packages-magic-groups`.</span>

<span class="sd">        The base implementation simply aggregates the results of</span>
<span class="sd">        :attr:`Bcfg2.Server.Plugins.Packages.Source.Source.basegroups`.&quot;&quot;&quot;</span>
        <span class="n">groups</span> <span class="o">=</span> <span class="nb">set</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="p">:</span>
            <span class="n">groups</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">basegroups</span><span class="p">)</span>
        <span class="k">return</span> <span class="nb">list</span><span class="p">(</span><span class="n">groups</span><span class="p">)</span>
</div>
    <span class="nd">@property</span>
<div class="viewcode-block" id="Collection.cachefiles"><a class="viewcode-back" href="../../../../../development/packages.html#Bcfg2.Server.Plugins.Packages.Collection.Collection.cachefiles">[docs]</a>    <span class="k">def</span> <span class="nf">cachefiles</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot; A list of the full path to all cachefiles used by this</span>
<span class="sd">        collection.</span>

<span class="sd">        The base implementation simply aggregates</span>
<span class="sd">        :attr:`Bcfg2.Server.Plugins.Packages.Source.Source.cachefile`</span>
<span class="sd">        attributes.&quot;&quot;&quot;</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">source</span> <span class="ow">in</span> <span class="bp">self</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">return</span> <span class="nb">list</span><span class="p">(</span><span class="n">cachefiles</span><span class="p">)</span>
</div>
    <span class="nd">@Bcfg2.Server.Plugin.track_statistics</span><span class="p">()</span>
<div class="viewcode-block" id="Collection.get_groups"><a class="viewcode-back" href="../../../../../development/packages.html#Bcfg2.Server.Plugins.Packages.Collection.Collection.get_groups">[docs]</a>    <span class="k">def</span> <span class="nf">get_groups</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">grouplist</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot; Given a list of package group names, return a dict of</span>
<span class="sd">        ``&lt;group name&gt;: &lt;list of packages&gt;``.  This method is provided</span>
<span class="sd">        since some backends may be able to query multiple groups at</span>
<span class="sd">        once faster than serially.</span>

<span class="sd">        The base implementation simply aggregates the results of</span>
<span class="sd">        :func:`Bcfg2.Server.Plugins.Packages.Source.Source.get_group`.</span>

<span class="sd">        :param grouplist: The list of groups to query</span>
<span class="sd">        :type grouplist: list of strings - group names</span>
<span class="sd">        :returns: dict of ``&lt;group name&gt;: &lt;list of packages&gt;``</span>

<span class="sd">        In this implementation the packages will be strings, but see</span>
<span class="sd">        :ref:`pkg-objects`.&quot;&quot;&quot;</span>
        <span class="n">rv</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">()</span>
        <span class="k">for</span> <span class="n">group</span><span class="p">,</span> <span class="n">ptype</span> <span class="ow">in</span> <span class="n">grouplist</span><span class="p">:</span>
            <span class="n">rv</span><span class="p">[</span><span class="n">group</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_group</span><span class="p">(</span><span class="n">group</span><span class="p">,</span> <span class="n">ptype</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">rv</span>
</div>
    <span class="nd">@Bcfg2.Server.Plugin.track_statistics</span><span class="p">()</span>
<div class="viewcode-block" id="Collection.get_group"><a class="viewcode-back" href="../../../../../development/packages.html#Bcfg2.Server.Plugins.Packages.Collection.Collection.get_group">[docs]</a>    <span class="k">def</span> <span class="nf">get_group</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">group</span><span class="p">,</span> <span class="n">ptype</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot; Get the list of packages of the given type in a package</span>
<span class="sd">        group.</span>

<span class="sd">        The base implementation simply aggregates the results of</span>
<span class="sd">        :func:`Bcfg2.Server.Plugins.Packages.Source.Source.get_group`.</span>

<span class="sd">        :param group: The name of the group to query</span>
<span class="sd">        :type group: string</span>
<span class="sd">        :param ptype: The type of packages to get, for backends that</span>
<span class="sd">                      support multiple package types in package groups</span>
<span class="sd">                      (e.g., &quot;recommended,&quot; &quot;optional,&quot; etc.)</span>
<span class="sd">        :type ptype: string</span>
<span class="sd">        :returns: list of strings - package names, but see</span>
<span class="sd">                  :ref:`pkg-objects`</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">__package_groups__</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">&quot;Packages: Package groups are not supported by &quot;</span>
                              <span class="s">&quot;</span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</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="k">return</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="p">:</span>
            <span class="n">pkgs</span> <span class="o">=</span> <span class="n">source</span><span class="o">.</span><span class="n">get_group</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">metadata</span><span class="p">,</span> <span class="n">group</span><span class="p">,</span> <span class="n">ptype</span><span class="o">=</span><span class="n">ptype</span><span class="p">)</span>
            <span class="k">if</span> <span class="n">pkgs</span><span class="p">:</span>
                <span class="k">return</span> <span class="n">pkgs</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">&quot;Packages: &#39;</span><span class="si">%s</span><span class="s">&#39; is not a valid group&quot;</span> <span class="o">%</span> <span class="n">group</span><span class="p">)</span>
        <span class="k">return</span> <span class="p">[]</span>
</div>
<div class="viewcode-block" id="Collection.is_package"><a class="viewcode-back" href="../../../../../development/packages.html#Bcfg2.Server.Plugins.Packages.Collection.Collection.is_package">[docs]</a>    <span class="k">def</span> <span class="nf">is_package</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">package</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot; Return True if a package is a package, False otherwise.</span>

<span class="sd">        The base implementation returns True if any Source object&#39;s</span>
<span class="sd">        :func:`Bcfg2.Server.Plugins.Packages.Source.Source.is_package`</span>
<span class="sd">        returns True.</span>

<span class="sd">        :param package: The name of the package, but see :ref:`pkg-objects`</span>
<span class="sd">        :type package: string</span>
<span class="sd">        :returns: bool</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="nb">any</span><span class="p">(</span><span class="n">source</span><span class="o">.</span><span class="n">is_package</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">metadata</span><span class="p">,</span> <span class="n">package</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="p">)</span>
</div>
<div class="viewcode-block" id="Collection.is_virtual_package"><a class="viewcode-back" href="../../../../../development/packages.html#Bcfg2.Server.Plugins.Packages.Collection.Collection.is_virtual_package">[docs]</a>    <span class="k">def</span> <span class="nf">is_virtual_package</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">package</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot; Return True if a name is a virtual package (i.e., is a</span>
<span class="sd">        symbol provided by a real package), False otherwise.</span>

<span class="sd">        The base implementation returns True if any Source object&#39;s</span>
<span class="sd">        :func:`Bcfg2.Server.Plugins.Packages.Source.Source.is_virtual_package`</span>
<span class="sd">        returns True.</span>

<span class="sd">        :param package: The name of the symbol, but see :ref:`pkg-objects`</span>
<span class="sd">        :type package: string</span>
<span class="sd">        :returns: bool</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="nb">any</span><span class="p">(</span><span class="n">source</span><span class="o">.</span><span class="n">is_virtual_package</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">metadata</span><span class="p">,</span> <span class="n">package</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="p">)</span>
</div>
<div class="viewcode-block" id="Collection.get_deps"><a class="viewcode-back" href="../../../../../development/packages.html#Bcfg2.Server.Plugins.Packages.Collection.Collection.get_deps">[docs]</a>    <span class="k">def</span> <span class="nf">get_deps</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">package</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot; Get a list of the dependencies of the given package.</span>

<span class="sd">        The base implementation simply aggregates the results of</span>
<span class="sd">        :func:`Bcfg2.Server.Plugins.Packages.Source.Source.get_deps`.</span>

<span class="sd">        :param package: The name of the symbol, but see :ref:`pkg-objects`</span>
<span class="sd">        :type package: string</span>
<span class="sd">        :returns: list of strings, but see :ref:`pkg-objects`</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">for</span> <span class="n">source</span> <span class="ow">in</span> <span class="bp">self</span><span class="p">:</span>
            <span class="k">if</span> <span class="n">source</span><span class="o">.</span><span class="n">is_package</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">metadata</span><span class="p">,</span> <span class="n">package</span><span class="p">):</span>
                <span class="k">return</span> <span class="n">source</span><span class="o">.</span><span class="n">get_deps</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">metadata</span><span class="p">,</span> <span class="n">package</span><span class="p">)</span>
        <span class="k">return</span> <span class="p">[]</span>
</div>
<div class="viewcode-block" id="Collection.get_essential"><a class="viewcode-back" href="../../../../../development/packages.html#Bcfg2.Server.Plugins.Packages.Collection.Collection.get_essential">[docs]</a>    <span class="k">def</span> <span class="nf">get_essential</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot; Get a list of packages that are essential to the repository.</span>

<span class="sd">        The base implementation simply aggregates</span>
<span class="sd">        :attr:`Bcfg2.Server.Plugins.Packages.Source.Source.essentialpkgs`</span>
<span class="sd">        attributes</span>

<span class="sd">        :returns: list of strings, but see :ref:`pkg-objects`</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">essential</span> <span class="o">=</span> <span class="nb">set</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="p">:</span>
            <span class="n">essential</span> <span class="o">|=</span> <span class="n">source</span><span class="o">.</span><span class="n">essentialpkgs</span>
        <span class="k">return</span> <span class="n">essential</span>
</div>
<div class="viewcode-block" id="Collection.get_provides"><a class="viewcode-back" href="../../../../../development/packages.html#Bcfg2.Server.Plugins.Packages.Collection.Collection.get_provides">[docs]</a>    <span class="k">def</span> <span class="nf">get_provides</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">package</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot; Get a list of all symbols provided by the given package.</span>

<span class="sd">        The base implementation simply aggregates the results of</span>
<span class="sd">        :func:`Bcfg2.Server.Plugins.Packages.Source.Source.get_provides`.</span>

<span class="sd">        :param package: The name of the package, but see :ref:`pkg-objects`</span>
<span class="sd">        :type package: string</span>
<span class="sd">        :returns: list of strings, but see :ref:`pkg-objects`</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">for</span> <span class="n">source</span> <span class="ow">in</span> <span class="bp">self</span><span class="p">:</span>
            <span class="n">providers</span> <span class="o">=</span> <span class="n">source</span><span class="o">.</span><span class="n">get_provides</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">metadata</span><span class="p">,</span> <span class="n">package</span><span class="p">)</span>
            <span class="k">if</span> <span class="n">providers</span><span class="p">:</span>
                <span class="k">return</span> <span class="n">providers</span>
        <span class="k">return</span> <span class="p">[]</span>
</div>
<div class="viewcode-block" id="Collection.get_vpkgs"><a class="viewcode-back" href="../../../../../development/packages.html#Bcfg2.Server.Plugins.Packages.Collection.Collection.get_vpkgs">[docs]</a>    <span class="k">def</span> <span class="nf">get_vpkgs</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot; Get a list of all virtual packages provided by all sources.</span>

<span class="sd">        The base implementation simply aggregates the results of</span>
<span class="sd">        :func:`Bcfg2.Server.Plugins.Packages.Source.Source.get_vpkgs`.</span>

<span class="sd">        :returns: list of strings, but see :ref:`pkg-objects`</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">vpkgs</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="p">:</span>
            <span class="n">s_vpkgs</span> <span class="o">=</span> <span class="n">source</span><span class="o">.</span><span class="n">get_vpkgs</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">metadata</span><span class="p">)</span>
            <span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">prov_set</span> <span class="ow">in</span> <span class="nb">list</span><span class="p">(</span><span class="n">s_vpkgs</span><span class="o">.</span><span class="n">items</span><span class="p">()):</span>
                <span class="k">if</span> <span class="n">name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">vpkgs</span><span class="p">:</span>
                    <span class="n">vpkgs</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">prov_set</span><span class="p">)</span>
                <span class="k">else</span><span class="p">:</span>
                    <span class="n">vpkgs</span><span class="p">[</span><span class="n">name</span><span class="p">]</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">prov_set</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">vpkgs</span>
</div>
<div class="viewcode-block" id="Collection.filter_unknown"><a class="viewcode-back" href="../../../../../development/packages.html#Bcfg2.Server.Plugins.Packages.Collection.Collection.filter_unknown">[docs]</a>    <span class="k">def</span> <span class="nf">filter_unknown</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">unknown</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot; After :func:`complete`, filter out packages that appear in</span>
<span class="sd">        the list of unknown packages but should not be presented to</span>
<span class="sd">        the user.  E.g., packages that you expect to be unknown.</span>

<span class="sd">        The base implementation filters out packages that are expected</span>
<span class="sd">        to be unknown by any source in this collection.</span>

<span class="sd">        :param unknown: A set of unknown packages.  The set should be</span>
<span class="sd">                        modified in place.</span>
<span class="sd">        :type unknown: set of strings, but see :ref:`pkg-objects`</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">for</span> <span class="n">source</span> <span class="ow">in</span> <span class="bp">self</span><span class="p">:</span>
            <span class="n">source</span><span class="o">.</span><span class="n">filter_unknown</span><span class="p">(</span><span class="n">unknown</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="Collection.magic_groups_match"><a class="viewcode-back" href="../../../../../development/packages.html#Bcfg2.Server.Plugins.Packages.Collection.Collection.magic_groups_match">[docs]</a>    <span class="k">def</span> <span class="nf">magic_groups_match</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot; Returns True if the client&#39;s</span>
<span class="sd">        :ref:`server-plugins-generators-packages-magic-groups` match</span>
<span class="sd">        the magic groups for any of the sources contained in this</span>
<span class="sd">        Collection.</span>

<span class="sd">        The base implementation returns True if any source</span>
<span class="sd">        :func:`Bcfg2.Server.Plugins.Packages.Source.Source.magic_groups_match`</span>
<span class="sd">        returns True.</span>

<span class="sd">        :returns: bool</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="nb">any</span><span class="p">(</span><span class="n">s</span><span class="o">.</span><span class="n">magic_groups_match</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">metadata</span><span class="p">)</span> <span class="k">for</span> <span class="n">s</span> <span class="ow">in</span> <span class="bp">self</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="Collection.build_extra_structures"><a class="viewcode-back" href="../../../../../development/packages.html#Bcfg2.Server.Plugins.Packages.Collection.Collection.build_extra_structures">[docs]</a>    <span class="k">def</span> <span class="nf">build_extra_structures</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">independent</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot; Add additional entries to the ``&lt;Independent/&gt;`` section</span>
<span class="sd">        of the final configuration.  This can be used to handle, e.g.,</span>
<span class="sd">        GPG keys and other entries besides packages that need to be</span>
<span class="sd">        handled for a complete client configuration.</span>

<span class="sd">        :param independent: The XML tag to add extra entries to.  This</span>
<span class="sd">                            is modified in place.</span>
<span class="sd">        :type independent: lxml.etree._Element</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">pass</span>
</div>
<div class="viewcode-block" id="Collection.get_additional_data"><a class="viewcode-back" href="../../../../../development/packages.html#Bcfg2.Server.Plugins.Packages.Collection.Collection.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="sd">&quot;&quot;&quot; Get additional</span>
<span class="sd">        :class:`Bcfg2.Server.Plugin.interfaces.Connector` data to be</span>
<span class="sd">        supplied to</span>
<span class="sd">        :func:`Bcfg2.Server.Plugins.Packages.Packages.get_additional_data`</span>
<span class="sd">        (and thence to client metadata objects).</span>

<span class="sd">        The base implementation simply aggregates</span>
<span class="sd">        :attr:`Bcfg2.Server.Plugins.Packages.Source.Source.url_map`</span>
<span class="sd">        attributes.</span>

<span class="sd">        :returns: list of additional Connector data</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">sdata</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="p">:</span>
            <span class="n">sdata</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">copy</span><span class="o">.</span><span class="n">deepcopy</span><span class="p">(</span><span class="n">source</span><span class="o">.</span><span class="n">url_map</span><span class="p">))</span>
        <span class="k">return</span> <span class="n">sdata</span>
</div>
<div class="viewcode-block" id="Collection.setup_data"><a class="viewcode-back" href="../../../../../development/packages.html#Bcfg2.Server.Plugins.Packages.Collection.Collection.setup_data">[docs]</a>    <span class="k">def</span> <span class="nf">setup_data</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">&quot;&quot;&quot; Do any collection-level data setup tasks. This is called</span>
<span class="sd">        when sources are loaded or reloaded by</span>
<span class="sd">        :class:`Bcfg2.Server.Plugins.Packages.Packages`.</span>

<span class="sd">        The base implementation is a no-op; the child</span>
<span class="sd">        :class:`Bcfg2.Server.Plugins.Packages.Source.Source` objects</span>
<span class="sd">        will handle all data setup.</span>

<span class="sd">        :param force_update: Ignore all local cache and setup data</span>
<span class="sd">                             from its original upstream sources (i.e.,</span>
<span class="sd">                             the package repositories)</span>
<span class="sd">        :type force_update: bool</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">pass</span>
</div>
<div class="viewcode-block" id="Collection.packages_from_entry"><a class="viewcode-back" href="../../../../../development/packages.html#Bcfg2.Server.Plugins.Packages.Collection.Collection.packages_from_entry">[docs]</a>    <span class="k">def</span> <span class="nf">packages_from_entry</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="sd">&quot;&quot;&quot; Given a Package or BoundPackage entry, get a list of the</span>
<span class="sd">        package(s) described by it in a format appropriate for passing</span>
<span class="sd">        to :func:`complete`.  By default, that&#39;s just the name; only</span>
<span class="sd">        the :mod:`Bcfg2.Server.Plugins.Packages.Yum` backend supports</span>
<span class="sd">        versions or other extended data. See :ref:`pkg-objects` for</span>
<span class="sd">        more details.</span>

<span class="sd">        :param entry: The XML entry describing the package or packages.</span>
<span class="sd">        :type entry: lxml.etree._Element</span>
<span class="sd">        :returns: list of strings, but see :ref:`pkg-objects`</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</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">&quot;name&quot;</span><span class="p">)]</span>
</div>
<div class="viewcode-block" id="Collection.packages_to_entry"><a class="viewcode-back" href="../../../../../development/packages.html#Bcfg2.Server.Plugins.Packages.Collection.Collection.packages_to_entry">[docs]</a>    <span class="k">def</span> <span class="nf">packages_to_entry</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">pkglist</span><span class="p">,</span> <span class="n">entry</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot; Given a list of package objects as returned by</span>
<span class="sd">        :func:`packages_from_entry` or :func:`complete`, return an XML</span>
<span class="sd">        tree describing the BoundPackage entries that should be</span>
<span class="sd">        included in the client configuration. See :ref:`pkg-objects`</span>
<span class="sd">        for more details.</span>

<span class="sd">        :param pkglist: A list of packages as returned by</span>
<span class="sd">                        :func:`complete`</span>
<span class="sd">        :type pkglist: list of strings, but see :ref:`pkg-objects`</span>
<span class="sd">        :param entry: The base XML entry to add all of the Package</span>
<span class="sd">                      entries to.  This should be modified in place.</span>
<span class="sd">        :type entry: lxml.etree._Element</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">for</span> <span class="n">pkg</span> <span class="ow">in</span> <span class="n">pkglist</span><span class="p">:</span>
            <span class="n">lxml</span><span class="o">.</span><span class="n">etree</span><span class="o">.</span><span class="n">SubElement</span><span class="p">(</span><span class="n">entry</span><span class="p">,</span> <span class="s">&#39;BoundPackage&#39;</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="n">pkg</span><span class="p">,</span>
                                  <span class="n">version</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">&quot;packages&quot;</span><span class="p">,</span>
                                                             <span class="s">&quot;version&quot;</span><span class="p">,</span>
                                                             <span class="n">default</span><span class="o">=</span><span class="s">&quot;auto&quot;</span><span class="p">),</span>
                                  <span class="nb">type</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">ptype</span><span class="p">,</span> <span class="n">origin</span><span class="o">=</span><span class="s">&#39;Packages&#39;</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="Collection.get_new_packages"><a class="viewcode-back" href="../../../../../development/packages.html#Bcfg2.Server.Plugins.Packages.Collection.Collection.get_new_packages">[docs]</a>    <span class="k">def</span> <span class="nf">get_new_packages</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">initial</span><span class="p">,</span> <span class="n">complete</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot; Compute the difference between the complete package list</span>
<span class="sd">        (as returned by :func:`complete`) and the initial package list</span>
<span class="sd">        computed from the specification.  This is necessary because</span>
<span class="sd">        the format may be different between the two lists due to</span>
<span class="sd">        :func:`packages_to_entry` and :func:`packages_from_entry`. See</span>
<span class="sd">        :ref:`pkg-objects` for more details.</span>

<span class="sd">        :param initial: The initial package list</span>
<span class="sd">        :type initial: set of strings, but see :ref:`pkg-objects`</span>
<span class="sd">        :param complete: The final package list</span>
<span class="sd">        :type complete: set of strings, but see :ref:`pkg-objects`</span>
<span class="sd">        :return: set of strings, but see :ref:`pkg-objects` - the set</span>
<span class="sd">                 of packages that are in ``complete`` but not in</span>
<span class="sd">                 ``initial``</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="nb">list</span><span class="p">(</span><span class="n">complete</span><span class="o">.</span><span class="n">difference</span><span class="p">(</span><span class="n">initial</span><span class="p">))</span>
</div>
    <span class="nd">@Bcfg2.Server.Plugin.track_statistics</span><span class="p">()</span>
<div class="viewcode-block" id="Collection.complete"><a class="viewcode-back" href="../../../../../development/packages.html#Bcfg2.Server.Plugins.Packages.Collection.Collection.complete">[docs]</a>    <span class="k">def</span> <span class="nf">complete</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">packagelist</span><span class="p">):</span>  <span class="c"># pylint: disable=R0912,R0914</span>
        <span class="sd">&quot;&quot;&quot; Build a complete list of all packages and their dependencies.</span>

<span class="sd">        :param packagelist: Set of initial packages computed from the</span>
<span class="sd">                            specification.</span>
<span class="sd">        :type packagelist: set of strings, but see :ref:`pkg-objects`</span>
<span class="sd">        :returns: tuple of sets - The first element contains a set of</span>
<span class="sd">                  strings (but see :ref:`pkg-objects`) describing the</span>
<span class="sd">                  complete package list, and the second element is a</span>
<span class="sd">                  set of symbols whose dependencies could not be</span>
<span class="sd">                  resolved.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="c"># setup vpkg cache</span>
        <span class="n">pgrps</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">get_relevant_groups</span><span class="p">())</span>
        <span class="k">if</span> <span class="n">pgrps</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">virt_pkgs</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">virt_pkgs</span><span class="p">[</span><span class="n">pgrps</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_vpkgs</span><span class="p">()</span>
        <span class="n">vpkg_cache</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">virt_pkgs</span><span class="p">[</span><span class="n">pgrps</span><span class="p">]</span>

        <span class="c"># unclassified is set of unsatisfied requirements (may be pkg</span>
        <span class="c"># for vpkg)</span>
        <span class="n">unclassified</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">packagelist</span><span class="p">)</span>
        <span class="n">vpkgs</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
        <span class="n">both</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
        <span class="n">pkgs</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">packagelist</span><span class="p">)</span>

        <span class="n">packages</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
        <span class="n">examined</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
        <span class="n">unknown</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>

        <span class="n">final_pass</span> <span class="o">=</span> <span class="bp">False</span>
        <span class="n">really_done</span> <span class="o">=</span> <span class="bp">False</span>
        <span class="c"># do while unclassified or vpkgs or both or pkgs</span>
        <span class="k">while</span> <span class="n">unclassified</span> <span class="ow">or</span> <span class="n">pkgs</span> <span class="ow">or</span> <span class="n">both</span> <span class="ow">or</span> <span class="n">final_pass</span><span class="p">:</span>
            <span class="k">if</span> <span class="n">really_done</span><span class="p">:</span>
                <span class="k">break</span>
            <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">unclassified</span><span class="p">)</span> <span class="o">+</span> <span class="nb">len</span><span class="p">(</span><span class="n">pkgs</span><span class="p">)</span> <span class="o">+</span> <span class="nb">len</span><span class="p">(</span><span class="n">both</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
                <span class="c"># one more pass then exit</span>
                <span class="n">really_done</span> <span class="o">=</span> <span class="bp">True</span>

            <span class="k">while</span> <span class="n">unclassified</span><span class="p">:</span>
                <span class="n">current</span> <span class="o">=</span> <span class="n">unclassified</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>
                <span class="n">examined</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">current</span><span class="p">)</span>
                <span class="n">is_pkg</span> <span class="o">=</span> <span class="bp">False</span>
                <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_package</span><span class="p">(</span><span class="n">current</span><span class="p">):</span>
                    <span class="n">is_pkg</span> <span class="o">=</span> <span class="bp">True</span>

                <span class="n">is_vpkg</span> <span class="o">=</span> <span class="n">current</span> <span class="ow">in</span> <span class="n">vpkg_cache</span>

                <span class="k">if</span> <span class="n">is_pkg</span> <span class="ow">and</span> <span class="n">is_vpkg</span><span class="p">:</span>
                    <span class="n">both</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">current</span><span class="p">)</span>
                <span class="k">elif</span> <span class="n">is_pkg</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">is_vpkg</span><span class="p">:</span>
                    <span class="n">pkgs</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">current</span><span class="p">)</span>
                <span class="k">elif</span> <span class="n">is_vpkg</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">is_pkg</span><span class="p">:</span>
                    <span class="n">vpkgs</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">current</span><span class="p">)</span>
                <span class="k">elif</span> <span class="ow">not</span> <span class="n">is_vpkg</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">is_pkg</span><span class="p">:</span>
                    <span class="n">unknown</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">current</span><span class="p">)</span>

            <span class="k">while</span> <span class="n">pkgs</span><span class="p">:</span>
                <span class="c"># direct packages; current can be added, and all deps</span>
                <span class="c"># should be resolved</span>
                <span class="n">current</span> <span class="o">=</span> <span class="n">pkgs</span><span class="o">.</span><span class="n">pop</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">&quot;Packages: handling package requirement </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span>
                               <span class="p">(</span><span class="n">current</span><span class="p">,))</span>
                <span class="n">packages</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">current</span><span class="p">)</span>
                <span class="n">deps</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_deps</span><span class="p">(</span><span class="n">current</span><span class="p">)</span>
                <span class="n">newdeps</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">deps</span><span class="p">)</span><span class="o">.</span><span class="n">difference</span><span class="p">(</span><span class="n">examined</span><span class="p">)</span>
                <span class="k">if</span> <span class="n">newdeps</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">&quot;Packages: Package </span><span class="si">%s</span><span class="s"> added requirements </span><span class="si">%s</span><span class="s">&quot;</span>
                                   <span class="o">%</span> <span class="p">(</span><span class="n">current</span><span class="p">,</span> <span class="n">newdeps</span><span class="p">))</span>
                <span class="n">unclassified</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">newdeps</span><span class="p">)</span>

            <span class="n">satisfied_vpkgs</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
            <span class="k">for</span> <span class="n">current</span> <span class="ow">in</span> <span class="n">vpkgs</span><span class="p">:</span>
                <span class="c"># virtual dependencies, satisfied if one of N in the</span>
                <span class="c"># config, or can be forced if only one provider</span>
                <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">vpkg_cache</span><span class="p">[</span><span class="n">current</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">debug_log</span><span class="p">(</span><span class="s">&quot;Packages: requirement </span><span class="si">%s</span><span class="s"> satisfied by </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span>
                                   <span class="p">(</span><span class="n">current</span><span class="p">,</span> <span class="n">vpkg_cache</span><span class="p">[</span><span class="n">current</span><span class="p">]))</span>
                    <span class="n">unclassified</span><span class="o">.</span><span class="n">update</span><span class="p">(</span>
                        <span class="n">vpkg_cache</span><span class="p">[</span><span class="n">current</span><span class="p">]</span><span class="o">.</span><span class="n">difference</span><span class="p">(</span><span class="n">examined</span><span class="p">))</span>
                    <span class="n">satisfied_vpkgs</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">current</span><span class="p">)</span>
                <span class="k">else</span><span class="p">:</span>
                    <span class="n">satisfiers</span> <span class="o">=</span> <span class="p">[</span><span class="n">item</span> <span class="k">for</span> <span class="n">item</span> <span class="ow">in</span> <span class="n">vpkg_cache</span><span class="p">[</span><span class="n">current</span><span class="p">]</span>
                                  <span class="k">if</span> <span class="n">item</span> <span class="ow">in</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">&quot;Packages: requirement </span><span class="si">%s</span><span class="s"> satisfied by </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span>
                                   <span class="p">(</span><span class="n">current</span><span class="p">,</span> <span class="n">satisfiers</span><span class="p">))</span>
                    <span class="n">satisfied_vpkgs</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">current</span><span class="p">)</span>
            <span class="n">vpkgs</span><span class="o">.</span><span class="n">difference_update</span><span class="p">(</span><span class="n">satisfied_vpkgs</span><span class="p">)</span>

            <span class="n">satisfied_both</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
            <span class="k">for</span> <span class="n">current</span> <span class="ow">in</span> <span class="n">both</span><span class="p">:</span>
                <span class="c"># packages that are both have virtual providers as</span>
                <span class="c"># well as a package with that name. allow use of virt</span>
                <span class="c"># through explicit specification, then fall back to</span>
                <span class="c"># forcing current on last pass</span>
                <span class="n">satisfiers</span> <span class="o">=</span> <span class="p">[</span><span class="n">item</span> <span class="k">for</span> <span class="n">item</span> <span class="ow">in</span> <span class="n">vpkg_cache</span><span class="p">[</span><span class="n">current</span><span class="p">]</span>
                              <span class="k">if</span> <span class="n">item</span> <span class="ow">in</span> <span class="n">packages</span><span class="p">]</span>
                <span class="k">if</span> <span class="n">satisfiers</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">&quot;Packages: requirement </span><span class="si">%s</span><span class="s"> satisfied by </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span>
                                   <span class="p">(</span><span class="n">current</span><span class="p">,</span> <span class="n">satisfiers</span><span class="p">))</span>
                    <span class="n">satisfied_both</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">current</span><span class="p">)</span>
                <span class="k">elif</span> <span class="n">current</span> <span class="ow">in</span> <span class="n">packagelist</span> <span class="ow">or</span> <span class="n">final_pass</span><span class="p">:</span>
                    <span class="n">pkgs</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">current</span><span class="p">)</span>
                    <span class="n">satisfied_both</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">current</span><span class="p">)</span>
            <span class="n">both</span><span class="o">.</span><span class="n">difference_update</span><span class="p">(</span><span class="n">satisfied_both</span><span class="p">)</span>

            <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">unclassified</span><span class="p">)</span> <span class="o">+</span> <span class="nb">len</span><span class="p">(</span><span class="n">pkgs</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
                <span class="n">final_pass</span> <span class="o">=</span> <span class="bp">True</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="n">final_pass</span> <span class="o">=</span> <span class="bp">False</span>

            <span class="bp">self</span><span class="o">.</span><span class="n">filter_unknown</span><span class="p">(</span><span class="n">unknown</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">packages</span><span class="p">,</span> <span class="n">unknown</span>

</div></div>
<div class="viewcode-block" id="get_collection_class"><a class="viewcode-back" href="../../../../../development/packages.html#Bcfg2.Server.Plugins.Packages.Collection.get_collection_class">[docs]</a><span class="k">def</span> <span class="nf">get_collection_class</span><span class="p">(</span><span class="n">source_type</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot; Given a source type, determine the class of Collection object</span>
<span class="sd">    that should be used to contain these sources.  Note that</span>
<span class="sd">    ``source_type`` is *not* a</span>
<span class="sd">    :class:`Bcfg2.Server.Plugins.Packages.Source.Source` subclass;</span>
<span class="sd">    it&#39;s the name of a source type as given in ``sources.xml``.</span>

<span class="sd">    :param source_type: The type of source, e.g., &quot;yum&quot; or &quot;apt&quot;</span>
<span class="sd">    :type source_type: string</span>
<span class="sd">    :returns: type - the Collection subclass that should be used to</span>
<span class="sd">              instantiate an object to contain sources of the given type. &quot;&quot;&quot;</span>
    <span class="n">modname</span> <span class="o">=</span> <span class="s">&quot;Bcfg2.Server.Plugins.Packages.</span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">source_type</span><span class="o">.</span><span class="n">title</span><span class="p">()</span>
    <span class="k">try</span><span class="p">:</span>
        <span class="n">module</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">modules</span><span class="p">[</span><span class="n">modname</span><span class="p">]</span>
    <span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="n">module</span> <span class="o">=</span> <span class="nb">__import__</span><span class="p">(</span><span class="n">modname</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="o">.</span><span class="n">Packages</span>
        <span class="k">except</span> <span class="ne">ImportError</span><span class="p">:</span>
            <span class="n">msg</span> <span class="o">=</span> <span class="s">&quot;Packages: Unknown source type </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">source_type</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="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">PluginExecutionError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>

    <span class="k">try</span><span class="p">:</span>
        <span class="n">cclass</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">module</span><span class="p">,</span> <span class="n">source_type</span><span class="o">.</span><span class="n">title</span><span class="p">()</span> <span class="o">+</span> <span class="s">&quot;Collection&quot;</span><span class="p">)</span>
    <span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
        <span class="n">msg</span> <span class="o">=</span> <span class="s">&quot;Packages: No collection class found for </span><span class="si">%s</span><span class="s"> sources&quot;</span> <span class="o">%</span> \
            <span class="n">source_type</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="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">PluginExecutionError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">cclass</span></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> |&nbsp;</li>
	<!--<li><a href="../../../../../search.html">search</a> |&nbsp;</li>-->
	<li><a href="../../../../../help/index.html">help</a> |&nbsp;</li>
	<li><a href="../../../../../contents.html">documentation </a> &raquo;</li>

          <li><a href="../../../../index.html" >Module code</a> &raquo;</li>
          <li><a href="../../Plugins.html" >Bcfg2.Server.Plugins</a> &raquo;</li>
          <li><a href="../Packages.html" >Bcfg2.Server.Plugins.Packages</a> &raquo;</li> 
      </ul>
    </div>
    <div class="footer">
        &copy; 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>