Add lorax 19.7.10 (lorax-composer) Documentation under /lorax-composer/

This commit is contained in:
Brian C. Lane 2018-03-15 14:04:29 -07:00
parent 34244400cd
commit 08e80bb679
81 changed files with 32689 additions and 0 deletions

View File

@ -0,0 +1,4 @@
# Sphinx build info version 1
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
config: 972a8f4b79671d03d004b6b084c1be20
tags: fbb0d17656682115ca4d033fb2f83ba1

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,117 @@
<!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>Overview: module code &mdash; Lorax 19.7.10 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: '19.7.10',
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>
<link rel="top" title="Lorax 19.7.10 documentation" href="../index.html" />
</head>
<body>
<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">Lorax 19.7.10 documentation</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<h1>All modules for which code is available</h1>
<ul><li><a href="pylorax/__init__.html">pylorax.__init__</a></li>
<li><a href="pylorax/api.html">pylorax.api</a></li>
<ul><li><a href="pylorax/api/compose.html">pylorax.api.compose</a></li>
<li><a href="pylorax/api/config.html">pylorax.api.config</a></li>
<li><a href="pylorax/api/crossdomain.html">pylorax.api.crossdomain</a></li>
<li><a href="pylorax/api/projects.html">pylorax.api.projects</a></li>
<li><a href="pylorax/api/queue.html">pylorax.api.queue</a></li>
<li><a href="pylorax/api/recipes.html">pylorax.api.recipes</a></li>
<li><a href="pylorax/api/server.html">pylorax.api.server</a></li>
<li><a href="pylorax/api/v0.html">pylorax.api.v0</a></li>
<li><a href="pylorax/api/workspace.html">pylorax.api.workspace</a></li>
<li><a href="pylorax/api/yumbase.html">pylorax.api.yumbase</a></li>
</ul><li><a href="pylorax/base.html">pylorax.base</a></li>
<li><a href="pylorax/buildstamp.html">pylorax.buildstamp</a></li>
<li><a href="pylorax/creator.html">pylorax.creator</a></li>
<li><a href="pylorax/decorators.html">pylorax.decorators</a></li>
<li><a href="pylorax/discinfo.html">pylorax.discinfo</a></li>
<li><a href="pylorax/executils.html">pylorax.executils</a></li>
<li><a href="pylorax/imgutils.html">pylorax.imgutils</a></li>
<li><a href="pylorax/installer.html">pylorax.installer</a></li>
<li><a href="pylorax/logmonitor.html">pylorax.logmonitor</a></li>
<li><a href="pylorax/ltmpl.html">pylorax.ltmpl</a></li>
<li><a href="pylorax/sysutils.html">pylorax.sysutils</a></li>
<li><a href="pylorax/treebuilder.html">pylorax.treebuilder</a></li>
<li><a href="pylorax/treeinfo.html">pylorax.treeinfo</a></li>
<li><a href="pylorax/yumhelper.html">pylorax.yumhelper</a></li>
</ul>
</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">Lorax 19.7.10 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2017, Red Hat, Inc..
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>

View File

@ -0,0 +1,469 @@
<!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>pylorax.__init__ &mdash; Lorax 19.7.10 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: '19.7.10',
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>
<link rel="top" title="Lorax 19.7.10 documentation" href="../../index.html" />
<link rel="up" title="Module code" href="../index.html" />
</head>
<body>
<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">Lorax 19.7.10 documentation</a> &raquo;</li>
<li><a href="../index.html" accesskey="U">Module code</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<h1>Source code for pylorax.__init__</h1><div class="highlight"><pre>
<span class="c">#</span>
<span class="c"># __init__.py</span>
<span class="c">#</span>
<span class="c"># Copyright (C) 2010 Red Hat, Inc.</span>
<span class="c">#</span>
<span class="c"># This program is free software; you can redistribute it and/or modify</span>
<span class="c"># it under the terms of the GNU General Public License as published by</span>
<span class="c"># the Free Software Foundation; either version 2 of the License, or</span>
<span class="c"># (at your option) any later version.</span>
<span class="c">#</span>
<span class="c"># This program is distributed in the hope that it will be useful,</span>
<span class="c"># but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<span class="c"># MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span>
<span class="c"># GNU General Public License for more details.</span>
<span class="c">#</span>
<span class="c"># You should have received a copy of the GNU General Public License</span>
<span class="c"># along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;.</span>
<span class="c">#</span>
<span class="c"># Red Hat Author(s): Martin Gracik &lt;mgracik@redhat.com&gt;</span>
<span class="c"># David Cantrell &lt;dcantrell@redhat.com&gt;</span>
<span class="c"># Will Woods &lt;wwoods@redhat.com&gt;</span>
<span class="c"># set up logging</span>
<span class="kn">import</span> <span class="nn">logging</span>
<span class="n">logger</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s">&quot;pylorax&quot;</span><span class="p">)</span>
<span class="n">logger</span><span class="o">.</span><span class="n">addHandler</span><span class="p">(</span><span class="n">logging</span><span class="o">.</span><span class="n">NullHandler</span><span class="p">())</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">ConfigParser</span>
<span class="kn">import</span> <span class="nn">tempfile</span>
<span class="kn">import</span> <span class="nn">locale</span>
<span class="kn">from</span> <span class="nn">subprocess</span> <span class="kn">import</span> <span class="n">CalledProcessError</span>
<span class="kn">import</span> <span class="nn">selinux</span>
<span class="kn">from</span> <span class="nn">pylorax.base</span> <span class="kn">import</span> <span class="n">BaseLoraxClass</span><span class="p">,</span> <span class="n">DataHolder</span>
<span class="kn">import</span> <span class="nn">pylorax.output</span> <span class="kn">as</span> <span class="nn">output</span>
<span class="kn">import</span> <span class="nn">yum</span>
<span class="kn">import</span> <span class="nn">pylorax.ltmpl</span> <span class="kn">as</span> <span class="nn">ltmpl</span>
<span class="kn">import</span> <span class="nn">pylorax.imgutils</span> <span class="kn">as</span> <span class="nn">imgutils</span>
<span class="kn">from</span> <span class="nn">pylorax.sysutils</span> <span class="kn">import</span> <span class="n">joinpaths</span><span class="p">,</span> <span class="n">linktree</span><span class="p">,</span> <span class="n">remove</span>
<span class="kn">from</span> <span class="nn">rpmUtils.arch</span> <span class="kn">import</span> <span class="n">getBaseArch</span>
<span class="kn">from</span> <span class="nn">pylorax.treebuilder</span> <span class="kn">import</span> <span class="n">RuntimeBuilder</span><span class="p">,</span> <span class="n">TreeBuilder</span>
<span class="kn">from</span> <span class="nn">pylorax.buildstamp</span> <span class="kn">import</span> <span class="n">BuildStamp</span>
<span class="kn">from</span> <span class="nn">pylorax.treeinfo</span> <span class="kn">import</span> <span class="n">TreeInfo</span>
<span class="kn">from</span> <span class="nn">pylorax.discinfo</span> <span class="kn">import</span> <span class="n">DiscInfo</span>
<span class="kn">from</span> <span class="nn">pylorax.executils</span> <span class="kn">import</span> <span class="n">runcmd</span><span class="p">,</span> <span class="n">runcmd_output</span>
<span class="c"># get lorax version</span>
<span class="k">try</span><span class="p">:</span>
<span class="kn">import</span> <span class="nn">pylorax.version</span>
<span class="k">except</span> <span class="ne">ImportError</span><span class="p">:</span>
<span class="n">vernum</span> <span class="o">=</span> <span class="s">&quot;devel&quot;</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">vernum</span> <span class="o">=</span> <span class="n">pylorax</span><span class="o">.</span><span class="n">version</span><span class="o">.</span><span class="n">num</span>
<span class="c"># List of drivers to remove on ppc64 arch to keep initrd &lt; 32MiB</span>
<span class="n">REMOVE_PPC64_DRIVERS</span> <span class="o">=</span> <span class="s">&quot;floppy scsi_debug nouveau radeon cirrus mgag200&quot;</span>
<span class="n">REMOVE_PPC64_MODULES</span> <span class="o">=</span> <span class="s">&quot;drm plymouth&quot;</span>
<div class="viewcode-block" id="ArchData"><a class="viewcode-back" href="../../pylorax.html#pylorax.__init__.ArchData">[docs]</a><span class="k">class</span> <span class="nc">ArchData</span><span class="p">(</span><span class="n">DataHolder</span><span class="p">):</span>
<span class="n">lib64_arches</span> <span class="o">=</span> <span class="p">(</span><span class="s">&quot;x86_64&quot;</span><span class="p">,</span> <span class="s">&quot;ppc64&quot;</span><span class="p">,</span> <span class="s">&quot;ppc64le&quot;</span><span class="p">,</span> <span class="s">&quot;s390x&quot;</span><span class="p">,</span> <span class="s">&quot;ia64&quot;</span><span class="p">,</span> <span class="s">&quot;aarch64&quot;</span><span class="p">)</span>
<span class="n">bcj_arch</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">(</span><span class="n">i386</span><span class="o">=</span><span class="s">&quot;x86&quot;</span><span class="p">,</span> <span class="n">x86_64</span><span class="o">=</span><span class="s">&quot;x86&quot;</span><span class="p">,</span>
<span class="n">ppc</span><span class="o">=</span><span class="s">&quot;powerpc&quot;</span><span class="p">,</span> <span class="n">ppc64</span><span class="o">=</span><span class="s">&quot;powerpc&quot;</span><span class="p">,</span> <span class="n">ppc64le</span><span class="o">=</span><span class="s">&quot;powerpc&quot;</span><span class="p">,</span>
<span class="n">arm</span><span class="o">=</span><span class="s">&quot;arm&quot;</span><span class="p">,</span> <span class="n">armhfp</span><span class="o">=</span><span class="s">&quot;arm&quot;</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">buildarch</span><span class="p">):</span>
<span class="n">DataHolder</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">buildarch</span><span class="o">=</span><span class="n">buildarch</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">basearch</span> <span class="o">=</span> <span class="n">getBaseArch</span><span class="p">(</span><span class="n">buildarch</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">libdir</span> <span class="o">=</span> <span class="s">&quot;lib64&quot;</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">basearch</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">lib64_arches</span> <span class="k">else</span> <span class="s">&quot;lib&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">bcj</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">bcj_arch</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">basearch</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="Lorax"><a class="viewcode-back" href="../../pylorax.html#pylorax.__init__.Lorax">[docs]</a><span class="k">class</span> <span class="nc">Lorax</span><span class="p">(</span><span class="n">BaseLoraxClass</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">BaseLoraxClass</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="bp">self</span><span class="o">.</span><span class="n">_configured</span> <span class="o">=</span> <span class="bp">False</span>
<span class="bp">self</span><span class="o">.</span><span class="n">conf</span> <span class="o">=</span> <span class="bp">None</span>
<span class="bp">self</span><span class="o">.</span><span class="n">outputdir</span> <span class="o">=</span> <span class="bp">None</span>
<span class="bp">self</span><span class="o">.</span><span class="n">workdir</span> <span class="o">=</span> <span class="bp">None</span>
<span class="bp">self</span><span class="o">.</span><span class="n">inroot</span> <span class="o">=</span> <span class="bp">None</span>
<span class="bp">self</span><span class="o">.</span><span class="n">arch</span> <span class="o">=</span> <span class="bp">None</span>
<span class="bp">self</span><span class="o">.</span><span class="n">product</span> <span class="o">=</span> <span class="bp">None</span>
<span class="bp">self</span><span class="o">.</span><span class="n">debug</span> <span class="o">=</span> <span class="bp">False</span>
<span class="c"># set locale to C</span>
<span class="n">locale</span><span class="o">.</span><span class="n">setlocale</span><span class="p">(</span><span class="n">locale</span><span class="o">.</span><span class="n">LC_ALL</span><span class="p">,</span> <span class="s">&#39;C&#39;</span><span class="p">)</span>
<div class="viewcode-block" id="Lorax.configure"><a class="viewcode-back" href="../../pylorax.html#pylorax.__init__.Lorax.configure">[docs]</a> <span class="k">def</span> <span class="nf">configure</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">conf_file</span><span class="o">=</span><span class="s">&quot;/etc/lorax/lorax.conf&quot;</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">conf</span> <span class="o">=</span> <span class="n">ConfigParser</span><span class="o">.</span><span class="n">SafeConfigParser</span><span class="p">()</span>
<span class="c"># set defaults</span>
<span class="bp">self</span><span class="o">.</span><span class="n">conf</span><span class="o">.</span><span class="n">add_section</span><span class="p">(</span><span class="s">&quot;lorax&quot;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">conf</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s">&quot;lorax&quot;</span><span class="p">,</span> <span class="s">&quot;debug&quot;</span><span class="p">,</span> <span class="s">&quot;1&quot;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">conf</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s">&quot;lorax&quot;</span><span class="p">,</span> <span class="s">&quot;sharedir&quot;</span><span class="p">,</span> <span class="s">&quot;/usr/share/lorax&quot;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">conf</span><span class="o">.</span><span class="n">add_section</span><span class="p">(</span><span class="s">&quot;output&quot;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">conf</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s">&quot;output&quot;</span><span class="p">,</span> <span class="s">&quot;colors&quot;</span><span class="p">,</span> <span class="s">&quot;1&quot;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">conf</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s">&quot;output&quot;</span><span class="p">,</span> <span class="s">&quot;encoding&quot;</span><span class="p">,</span> <span class="s">&quot;utf-8&quot;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">conf</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s">&quot;output&quot;</span><span class="p">,</span> <span class="s">&quot;ignorelist&quot;</span><span class="p">,</span> <span class="s">&quot;/usr/share/lorax/ignorelist&quot;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">conf</span><span class="o">.</span><span class="n">add_section</span><span class="p">(</span><span class="s">&quot;templates&quot;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">conf</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s">&quot;templates&quot;</span><span class="p">,</span> <span class="s">&quot;ramdisk&quot;</span><span class="p">,</span> <span class="s">&quot;ramdisk.ltmpl&quot;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">conf</span><span class="o">.</span><span class="n">add_section</span><span class="p">(</span><span class="s">&quot;yum&quot;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">conf</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s">&quot;yum&quot;</span><span class="p">,</span> <span class="s">&quot;skipbroken&quot;</span><span class="p">,</span> <span class="s">&quot;0&quot;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">conf</span><span class="o">.</span><span class="n">add_section</span><span class="p">(</span><span class="s">&quot;compression&quot;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">conf</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s">&quot;compression&quot;</span><span class="p">,</span> <span class="s">&quot;type&quot;</span><span class="p">,</span> <span class="s">&quot;xz&quot;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">conf</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s">&quot;compression&quot;</span><span class="p">,</span> <span class="s">&quot;args&quot;</span><span class="p">,</span> <span class="s">&quot;&quot;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">conf</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s">&quot;compression&quot;</span><span class="p">,</span> <span class="s">&quot;bcj&quot;</span><span class="p">,</span> <span class="s">&quot;on&quot;</span><span class="p">)</span>
<span class="c"># read the config file</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">isfile</span><span class="p">(</span><span class="n">conf_file</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">conf</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="n">conf_file</span><span class="p">)</span>
<span class="c"># set up the output</span>
<span class="bp">self</span><span class="o">.</span><span class="n">debug</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">conf</span><span class="o">.</span><span class="n">getboolean</span><span class="p">(</span><span class="s">&quot;lorax&quot;</span><span class="p">,</span> <span class="s">&quot;debug&quot;</span><span class="p">)</span>
<span class="n">output_level</span> <span class="o">=</span> <span class="n">output</span><span class="o">.</span><span class="n">DEBUG</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">debug</span> <span class="k">else</span> <span class="n">output</span><span class="o">.</span><span class="n">INFO</span>
<span class="n">colors</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">conf</span><span class="o">.</span><span class="n">getboolean</span><span class="p">(</span><span class="s">&quot;output&quot;</span><span class="p">,</span> <span class="s">&quot;colors&quot;</span><span class="p">)</span>
<span class="n">encoding</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">conf</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">&quot;output&quot;</span><span class="p">,</span> <span class="s">&quot;encoding&quot;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">output</span><span class="o">.</span><span class="n">basic_config</span><span class="p">(</span><span class="n">output_level</span><span class="o">=</span><span class="n">output_level</span><span class="p">,</span>
<span class="n">colors</span><span class="o">=</span><span class="n">colors</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="n">encoding</span><span class="p">)</span>
<span class="n">ignorelist</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">conf</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">&quot;output&quot;</span><span class="p">,</span> <span class="s">&quot;ignorelist&quot;</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">isfile</span><span class="p">(</span><span class="n">ignorelist</span><span class="p">):</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">ignorelist</span><span class="p">,</span> <span class="s">&quot;r&quot;</span><span class="p">)</span> <span class="k">as</span> <span class="n">fobj</span><span class="p">:</span>
<span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">fobj</span><span class="p">:</span>
<span class="n">line</span> <span class="o">=</span> <span class="n">line</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
<span class="k">if</span> <span class="n">line</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">line</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s">&quot;#&quot;</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">output</span><span class="o">.</span><span class="n">ignore</span><span class="p">(</span><span class="n">line</span><span class="p">)</span>
<span class="c"># cron does not have sbin in PATH,</span>
<span class="c"># so we have to add it ourselves</span>
<span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="p">[</span><span class="s">&quot;PATH&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="s">&quot;{0}:/sbin:/usr/sbin&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="p">[</span><span class="s">&quot;PATH&quot;</span><span class="p">])</span>
<span class="c"># remove some environmental variables that can cause problems with package scripts</span>
<span class="n">env_remove</span> <span class="o">=</span> <span class="p">(</span><span class="s">&#39;DISPLAY&#39;</span><span class="p">,</span> <span class="s">&#39;DBUS_SESSION_BUS_ADDRESS&#39;</span><span class="p">)</span>
<span class="n">_</span> <span class="o">=</span> <span class="p">[</span><span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="n">k</span><span class="p">)</span> <span class="k">for</span> <span class="n">k</span> <span class="ow">in</span> <span class="n">env_remove</span> <span class="k">if</span> <span class="n">k</span> <span class="ow">in</span> <span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="p">]</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_configured</span> <span class="o">=</span> <span class="bp">True</span>
</div>
<div class="viewcode-block" id="Lorax.init_stream_logging"><a class="viewcode-back" href="../../pylorax.html#pylorax.__init__.Lorax.init_stream_logging">[docs]</a> <span class="k">def</span> <span class="nf">init_stream_logging</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="n">sh</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">StreamHandler</span><span class="p">()</span>
<span class="n">sh</span><span class="o">.</span><span class="n">setLevel</span><span class="p">(</span><span class="n">logging</span><span class="o">.</span><span class="n">INFO</span><span class="p">)</span>
<span class="n">logger</span><span class="o">.</span><span class="n">addHandler</span><span class="p">(</span><span class="n">sh</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="Lorax.init_file_logging"><a class="viewcode-back" href="../../pylorax.html#pylorax.__init__.Lorax.init_file_logging">[docs]</a> <span class="k">def</span> <span class="nf">init_file_logging</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">logdir</span><span class="p">,</span> <span class="n">logname</span><span class="o">=</span><span class="s">&quot;pylorax.log&quot;</span><span class="p">):</span>
<span class="n">fh</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">FileHandler</span><span class="p">(</span><span class="n">filename</span><span class="o">=</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">logdir</span><span class="p">,</span> <span class="n">logname</span><span class="p">),</span> <span class="n">mode</span><span class="o">=</span><span class="s">&quot;w&quot;</span><span class="p">)</span>
<span class="n">fh</span><span class="o">.</span><span class="n">setLevel</span><span class="p">(</span><span class="n">logging</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">)</span>
<span class="n">logger</span><span class="o">.</span><span class="n">addHandler</span><span class="p">(</span><span class="n">fh</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="Lorax.run"><a class="viewcode-back" href="../../pylorax.html#pylorax.__init__.Lorax.run">[docs]</a> <span class="k">def</span> <span class="nf">run</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">ybo</span><span class="p">,</span> <span class="n">product</span><span class="p">,</span> <span class="n">version</span><span class="p">,</span> <span class="n">release</span><span class="p">,</span> <span class="n">variant</span><span class="o">=</span><span class="s">&quot;&quot;</span><span class="p">,</span> <span class="n">bugurl</span><span class="o">=</span><span class="s">&quot;&quot;</span><span class="p">,</span>
<span class="n">isfinal</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">workdir</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">outputdir</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">buildarch</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">volid</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span>
<span class="n">domacboot</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">doupgrade</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span> <span class="n">remove_temp</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span>
<span class="n">installpkgs</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span>
<span class="n">size</span><span class="o">=</span><span class="mi">2</span><span class="p">,</span>
<span class="n">add_templates</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span>
<span class="n">add_template_vars</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span>
<span class="n">add_arch_templates</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span>
<span class="n">add_arch_template_vars</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span>
<span class="n">template_tempdir</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
<span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">_configured</span>
<span class="n">installpkgs</span> <span class="o">=</span> <span class="n">installpkgs</span> <span class="ow">or</span> <span class="p">[]</span>
<span class="k">if</span> <span class="n">domacboot</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">runcmd</span><span class="p">([</span><span class="s">&quot;rpm&quot;</span><span class="p">,</span> <span class="s">&quot;-q&quot;</span><span class="p">,</span> <span class="s">&quot;hfsplus-tools&quot;</span><span class="p">])</span>
<span class="k">except</span> <span class="n">CalledProcessError</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">critical</span><span class="p">(</span><span class="s">&quot;you need to install hfsplus-tools to create mac images&quot;</span><span class="p">)</span>
<span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="c"># set up work directory</span>
<span class="bp">self</span><span class="o">.</span><span class="n">workdir</span> <span class="o">=</span> <span class="n">workdir</span> <span class="ow">or</span> <span class="n">tempfile</span><span class="o">.</span><span class="n">mkdtemp</span><span class="p">(</span><span class="n">prefix</span><span class="o">=</span><span class="s">&quot;pylorax.work.&quot;</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">isdir</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">workdir</span><span class="p">):</span>
<span class="n">os</span><span class="o">.</span><span class="n">makedirs</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">workdir</span><span class="p">)</span>
<span class="c"># set up log directory</span>
<span class="n">logdir</span> <span class="o">=</span> <span class="s">&#39;/var/log/lorax&#39;</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">isdir</span><span class="p">(</span><span class="n">logdir</span><span class="p">):</span>
<span class="n">os</span><span class="o">.</span><span class="n">makedirs</span><span class="p">(</span><span class="n">logdir</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">init_stream_logging</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">init_file_logging</span><span class="p">(</span><span class="n">logdir</span><span class="p">)</span>
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">&quot;version is </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">vernum</span><span class="p">)</span>
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">&quot;using work directory </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">workdir</span><span class="p">)</span>
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">&quot;using log directory </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">logdir</span><span class="p">)</span>
<span class="c"># set up output directory</span>
<span class="bp">self</span><span class="o">.</span><span class="n">outputdir</span> <span class="o">=</span> <span class="n">outputdir</span> <span class="ow">or</span> <span class="n">tempfile</span><span class="o">.</span><span class="n">mkdtemp</span><span class="p">(</span><span class="n">prefix</span><span class="o">=</span><span class="s">&quot;pylorax.out.&quot;</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">isdir</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">outputdir</span><span class="p">):</span>
<span class="n">os</span><span class="o">.</span><span class="n">makedirs</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">outputdir</span><span class="p">)</span>
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">&quot;using output directory </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">outputdir</span><span class="p">)</span>
<span class="c"># do we have root privileges?</span>
<span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;checking for root privileges&quot;</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">geteuid</span><span class="p">()</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">critical</span><span class="p">(</span><span class="s">&quot;no root privileges&quot;</span><span class="p">)</span>
<span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="c"># is selinux disabled?</span>
<span class="c"># With selinux in enforcing mode the rpcbind package required for</span>
<span class="c"># dracut nfs module, which is in turn required by anaconda module,</span>
<span class="c"># will not get installed, because it&#39;s preinstall scriptlet fails,</span>
<span class="c"># resulting in an incomplete initial ramdisk image.</span>
<span class="c"># The reason is that the scriptlet runs tools from the shadow-utils</span>
<span class="c"># package in chroot, particularly groupadd and useradd to add the</span>
<span class="c"># required rpc group and rpc user. This operation fails, because</span>
<span class="c"># the selinux context on files in the chroot, that the shadow-utils</span>
<span class="c"># tools need to access (/etc/group, /etc/passwd, /etc/shadow etc.),</span>
<span class="c"># is wrong and selinux therefore disallows access to these files.</span>
<span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;checking the selinux mode&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">selinux</span><span class="o">.</span><span class="n">is_selinux_enabled</span><span class="p">()</span> <span class="ow">and</span> <span class="n">selinux</span><span class="o">.</span><span class="n">security_getenforce</span><span class="p">():</span>
<span class="n">logger</span><span class="o">.</span><span class="n">critical</span><span class="p">(</span><span class="s">&quot;selinux must be disabled or in Permissive mode&quot;</span><span class="p">)</span>
<span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="c"># do we have a proper yum base object?</span>
<span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;checking yum base object&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">ybo</span><span class="p">,</span> <span class="n">yum</span><span class="o">.</span><span class="n">YumBase</span><span class="p">):</span>
<span class="n">logger</span><span class="o">.</span><span class="n">critical</span><span class="p">(</span><span class="s">&quot;no yum base object&quot;</span><span class="p">)</span>
<span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">inroot</span> <span class="o">=</span> <span class="n">ybo</span><span class="o">.</span><span class="n">conf</span><span class="o">.</span><span class="n">installroot</span>
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">&quot;using install root: </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">inroot</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">buildarch</span><span class="p">:</span>
<span class="n">buildarch</span> <span class="o">=</span> <span class="n">get_buildarch</span><span class="p">(</span><span class="n">ybo</span><span class="p">)</span>
<span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;setting up build architecture&quot;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">arch</span> <span class="o">=</span> <span class="n">ArchData</span><span class="p">(</span><span class="n">buildarch</span><span class="p">)</span>
<span class="k">for</span> <span class="n">attr</span> <span class="ow">in</span> <span class="p">(</span><span class="s">&#39;buildarch&#39;</span><span class="p">,</span> <span class="s">&#39;basearch&#39;</span><span class="p">,</span> <span class="s">&#39;libdir&#39;</span><span class="p">):</span>
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">&quot;self.arch.</span><span class="si">%s</span><span class="s"> = </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">attr</span><span class="p">,</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">arch</span><span class="p">,</span><span class="n">attr</span><span class="p">))</span>
<span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;setting up build parameters&quot;</span><span class="p">)</span>
<span class="n">product</span> <span class="o">=</span> <span class="n">DataHolder</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="n">product</span><span class="p">,</span> <span class="n">version</span><span class="o">=</span><span class="n">version</span><span class="p">,</span> <span class="n">release</span><span class="o">=</span><span class="n">release</span><span class="p">,</span>
<span class="n">variant</span><span class="o">=</span><span class="n">variant</span><span class="p">,</span> <span class="n">bugurl</span><span class="o">=</span><span class="n">bugurl</span><span class="p">,</span> <span class="n">isfinal</span><span class="o">=</span><span class="n">isfinal</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">product</span> <span class="o">=</span> <span class="n">product</span>
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">&quot;product data: </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">product</span><span class="p">)</span>
<span class="c"># NOTE: if you change isolabel, you need to change pungi to match, or</span>
<span class="c"># the pungi images won&#39;t boot.</span>
<span class="n">isolabel</span> <span class="o">=</span> <span class="n">volid</span> <span class="ow">or</span> <span class="s">&quot;</span><span class="si">%s</span><span class="s"> </span><span class="si">%s</span><span class="s"> </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">product</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">product</span><span class="o">.</span><span class="n">version</span><span class="p">,</span>
<span class="bp">self</span><span class="o">.</span><span class="n">arch</span><span class="o">.</span><span class="n">basearch</span><span class="p">)</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">isolabel</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">32</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">fatal</span><span class="p">(</span><span class="s">&quot;the volume id cannot be longer than 32 characters&quot;</span><span class="p">)</span>
<span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="n">templatedir</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">conf</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">&quot;lorax&quot;</span><span class="p">,</span> <span class="s">&quot;sharedir&quot;</span><span class="p">)</span>
<span class="c"># NOTE: rb.root = ybo.conf.installroot (== self.inroot)</span>
<span class="n">rb</span> <span class="o">=</span> <span class="n">RuntimeBuilder</span><span class="p">(</span><span class="n">product</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">product</span><span class="p">,</span> <span class="n">arch</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">arch</span><span class="p">,</span>
<span class="n">yum</span><span class="o">=</span><span class="n">ybo</span><span class="p">,</span> <span class="n">templatedir</span><span class="o">=</span><span class="n">templatedir</span><span class="p">,</span>
<span class="n">installpkgs</span><span class="o">=</span><span class="n">installpkgs</span><span class="p">,</span>
<span class="n">add_templates</span><span class="o">=</span><span class="n">add_templates</span><span class="p">,</span>
<span class="n">add_template_vars</span><span class="o">=</span><span class="n">add_template_vars</span><span class="p">)</span>
<span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;installing runtime packages&quot;</span><span class="p">)</span>
<span class="n">rb</span><span class="o">.</span><span class="n">yum</span><span class="o">.</span><span class="n">conf</span><span class="o">.</span><span class="n">skip_broken</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">conf</span><span class="o">.</span><span class="n">getboolean</span><span class="p">(</span><span class="s">&quot;yum&quot;</span><span class="p">,</span> <span class="s">&quot;skipbroken&quot;</span><span class="p">)</span>
<span class="n">rb</span><span class="o">.</span><span class="n">install</span><span class="p">()</span>
<span class="c"># write .buildstamp</span>
<span class="n">buildstamp</span> <span class="o">=</span> <span class="n">BuildStamp</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">product</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">product</span><span class="o">.</span><span class="n">version</span><span class="p">,</span>
<span class="bp">self</span><span class="o">.</span><span class="n">product</span><span class="o">.</span><span class="n">bugurl</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">product</span><span class="o">.</span><span class="n">isfinal</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">arch</span><span class="o">.</span><span class="n">buildarch</span><span class="p">)</span>
<span class="n">buildstamp</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">inroot</span><span class="p">,</span> <span class="s">&quot;.buildstamp&quot;</span><span class="p">))</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">debug</span><span class="p">:</span>
<span class="n">rb</span><span class="o">.</span><span class="n">writepkglists</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">logdir</span><span class="p">,</span> <span class="s">&quot;pkglists&quot;</span><span class="p">))</span>
<span class="n">rb</span><span class="o">.</span><span class="n">writepkgsizes</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">logdir</span><span class="p">,</span> <span class="s">&quot;original-pkgsizes.txt&quot;</span><span class="p">))</span>
<span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;doing post-install configuration&quot;</span><span class="p">)</span>
<span class="n">rb</span><span class="o">.</span><span class="n">postinstall</span><span class="p">()</span>
<span class="c"># write .discinfo</span>
<span class="n">discinfo</span> <span class="o">=</span> <span class="n">DiscInfo</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">product</span><span class="o">.</span><span class="n">release</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">arch</span><span class="o">.</span><span class="n">basearch</span><span class="p">)</span>
<span class="n">discinfo</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">outputdir</span><span class="p">,</span> <span class="s">&quot;.discinfo&quot;</span><span class="p">))</span>
<span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;backing up installroot&quot;</span><span class="p">)</span>
<span class="n">installroot</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">workdir</span><span class="p">,</span> <span class="s">&quot;installroot&quot;</span><span class="p">)</span>
<span class="n">linktree</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">inroot</span><span class="p">,</span> <span class="n">installroot</span><span class="p">)</span>
<span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;generating kernel module metadata&quot;</span><span class="p">)</span>
<span class="n">rb</span><span class="o">.</span><span class="n">generate_module_data</span><span class="p">()</span>
<span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;cleaning unneeded files&quot;</span><span class="p">)</span>
<span class="n">rb</span><span class="o">.</span><span class="n">cleanup</span><span class="p">()</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">debug</span><span class="p">:</span>
<span class="n">rb</span><span class="o">.</span><span class="n">writepkgsizes</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">logdir</span><span class="p">,</span> <span class="s">&quot;final-pkgsizes.txt&quot;</span><span class="p">))</span>
<span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;creating the runtime image&quot;</span><span class="p">)</span>
<span class="n">runtime</span> <span class="o">=</span> <span class="s">&quot;images/install.img&quot;</span>
<span class="n">compression</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">conf</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">&quot;compression&quot;</span><span class="p">,</span> <span class="s">&quot;type&quot;</span><span class="p">)</span>
<span class="n">compressargs</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">conf</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">&quot;compression&quot;</span><span class="p">,</span> <span class="s">&quot;args&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">split</span><span class="p">()</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">conf</span><span class="o">.</span><span class="n">getboolean</span><span class="p">(</span><span class="s">&quot;compression&quot;</span><span class="p">,</span> <span class="s">&quot;bcj&quot;</span><span class="p">):</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">arch</span><span class="o">.</span><span class="n">bcj</span><span class="p">:</span>
<span class="n">compressargs</span> <span class="o">+=</span> <span class="p">[</span><span class="s">&quot;-Xbcj&quot;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">arch</span><span class="o">.</span><span class="n">bcj</span><span class="p">]</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;no BCJ filter for arch </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">arch</span><span class="o">.</span><span class="n">basearch</span><span class="p">)</span>
<span class="n">rb</span><span class="o">.</span><span class="n">create_runtime</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">installroot</span><span class="p">,</span><span class="n">runtime</span><span class="p">),</span>
<span class="n">compression</span><span class="o">=</span><span class="n">compression</span><span class="p">,</span> <span class="n">compressargs</span><span class="o">=</span><span class="n">compressargs</span><span class="p">)</span>
<span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;preparing to build output tree and boot images&quot;</span><span class="p">)</span>
<span class="n">treebuilder</span> <span class="o">=</span> <span class="n">TreeBuilder</span><span class="p">(</span><span class="n">product</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">product</span><span class="p">,</span> <span class="n">arch</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">arch</span><span class="p">,</span>
<span class="n">inroot</span><span class="o">=</span><span class="n">installroot</span><span class="p">,</span> <span class="n">outroot</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">outputdir</span><span class="p">,</span>
<span class="n">runtime</span><span class="o">=</span><span class="n">runtime</span><span class="p">,</span> <span class="n">isolabel</span><span class="o">=</span><span class="n">isolabel</span><span class="p">,</span>
<span class="n">domacboot</span><span class="o">=</span><span class="n">domacboot</span><span class="p">,</span> <span class="n">doupgrade</span><span class="o">=</span><span class="n">doupgrade</span><span class="p">,</span>
<span class="n">templatedir</span><span class="o">=</span><span class="n">templatedir</span><span class="p">,</span>
<span class="n">add_templates</span><span class="o">=</span><span class="n">add_arch_templates</span><span class="p">,</span>
<span class="n">add_template_vars</span><span class="o">=</span><span class="n">add_arch_template_vars</span><span class="p">,</span>
<span class="n">workdir</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">workdir</span><span class="p">)</span>
<span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;rebuilding initramfs images&quot;</span><span class="p">)</span>
<span class="n">dracut_args</span> <span class="o">=</span> <span class="p">[</span><span class="s">&quot;--xz&quot;</span><span class="p">,</span> <span class="s">&quot;--install&quot;</span><span class="p">,</span> <span class="s">&quot;/.buildstamp&quot;</span><span class="p">,</span> <span class="s">&quot;--no-early-microcode&quot;</span><span class="p">,</span> <span class="s">&quot;--add&quot;</span><span class="p">,</span> <span class="s">&quot;fips&quot;</span><span class="p">]</span>
<span class="n">anaconda_args</span> <span class="o">=</span> <span class="n">dracut_args</span> <span class="o">+</span> <span class="p">[</span><span class="s">&quot;--add&quot;</span><span class="p">,</span> <span class="s">&quot;anaconda pollcdrom&quot;</span><span class="p">]</span>
<span class="c"># ppc64 cannot boot an initrd &gt; 32MiB so remove some drivers</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">arch</span><span class="o">.</span><span class="n">basearch</span> <span class="ow">in</span> <span class="p">(</span><span class="s">&quot;ppc64&quot;</span><span class="p">,</span> <span class="s">&quot;ppc64le&quot;</span><span class="p">):</span>
<span class="n">dracut_args</span><span class="o">.</span><span class="n">extend</span><span class="p">([</span><span class="s">&quot;--omit-drivers&quot;</span><span class="p">,</span> <span class="n">REMOVE_PPC64_DRIVERS</span><span class="p">])</span>
<span class="c"># Only omit dracut modules from the initrd so that they&#39;re kept for</span>
<span class="c"># upgrade.img</span>
<span class="n">anaconda_args</span><span class="o">.</span><span class="n">extend</span><span class="p">([</span><span class="s">&quot;--omit&quot;</span><span class="p">,</span> <span class="n">REMOVE_PPC64_MODULES</span><span class="p">])</span>
<span class="n">treebuilder</span><span class="o">.</span><span class="n">rebuild_initrds</span><span class="p">(</span><span class="n">add_args</span><span class="o">=</span><span class="n">anaconda_args</span><span class="p">)</span>
<span class="k">if</span> <span class="n">doupgrade</span><span class="p">:</span>
<span class="c"># Build upgrade.img. It&#39;d be nice if these could coexist in the same</span>
<span class="c"># image, but that would increase the size of the anaconda initramfs,</span>
<span class="c"># which worries some people (esp. PPC tftpboot). So they&#39;re separate.</span>
<span class="k">try</span><span class="p">:</span>
<span class="c"># If possible, use the &#39;redhat-upgrade-tool&#39; plymouth theme</span>
<span class="n">themes</span> <span class="o">=</span> <span class="n">runcmd_output</span><span class="p">([</span><span class="s">&#39;plymouth-set-default-theme&#39;</span><span class="p">,</span> <span class="s">&#39;--list&#39;</span><span class="p">],</span>
<span class="n">root</span><span class="o">=</span><span class="n">installroot</span><span class="p">)</span>
<span class="k">if</span> <span class="s">&#39;redhat-upgrade-tool&#39;</span> <span class="ow">in</span> <span class="n">themes</span><span class="o">.</span><span class="n">splitlines</span><span class="p">():</span>
<span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="p">[</span><span class="s">&#39;PLYMOUTH_THEME_NAME&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s">&#39;redhat-upgrade-tool&#39;</span>
<span class="k">except</span> <span class="ne">RuntimeError</span><span class="p">:</span>
<span class="k">pass</span>
<span class="n">upgrade_args</span> <span class="o">=</span> <span class="n">dracut_args</span> <span class="o">+</span> <span class="p">[</span><span class="s">&quot;--add&quot;</span><span class="p">,</span> <span class="s">&quot;system-upgrade convertfs&quot;</span><span class="p">]</span>
<span class="n">treebuilder</span><span class="o">.</span><span class="n">rebuild_initrds</span><span class="p">(</span><span class="n">add_args</span><span class="o">=</span><span class="n">upgrade_args</span><span class="p">,</span> <span class="n">prefix</span><span class="o">=</span><span class="s">&quot;upgrade&quot;</span><span class="p">)</span>
<span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;populating output tree and building boot images&quot;</span><span class="p">)</span>
<span class="n">treebuilder</span><span class="o">.</span><span class="n">build</span><span class="p">()</span>
<span class="c"># write .treeinfo file and we&#39;re done</span>
<span class="n">treeinfo</span> <span class="o">=</span> <span class="n">TreeInfo</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">product</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">product</span><span class="o">.</span><span class="n">version</span><span class="p">,</span>
<span class="bp">self</span><span class="o">.</span><span class="n">product</span><span class="o">.</span><span class="n">variant</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">arch</span><span class="o">.</span><span class="n">basearch</span><span class="p">)</span>
<span class="k">for</span> <span class="n">section</span><span class="p">,</span> <span class="n">data</span> <span class="ow">in</span> <span class="n">treebuilder</span><span class="o">.</span><span class="n">treeinfo_data</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
<span class="n">treeinfo</span><span class="o">.</span><span class="n">add_section</span><span class="p">(</span><span class="n">section</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span>
<span class="n">treeinfo</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">outputdir</span><span class="p">,</span> <span class="s">&quot;.treeinfo&quot;</span><span class="p">))</span>
<span class="c"># cleanup</span>
<span class="k">if</span> <span class="n">remove_temp</span><span class="p">:</span>
<span class="n">remove</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">workdir</span><span class="p">)</span>
</div></div>
<div class="viewcode-block" id="get_buildarch"><a class="viewcode-back" href="../../pylorax.html#pylorax.__init__.get_buildarch">[docs]</a><span class="k">def</span> <span class="nf">get_buildarch</span><span class="p">(</span><span class="n">ybo</span><span class="p">):</span>
<span class="c"># get architecture of the available anaconda package</span>
<span class="n">buildarch</span> <span class="o">=</span> <span class="bp">None</span>
<span class="k">for</span> <span class="n">anaconda</span> <span class="ow">in</span> <span class="n">ybo</span><span class="o">.</span><span class="n">doPackageLists</span><span class="p">(</span><span class="n">patterns</span><span class="o">=</span><span class="p">[</span><span class="s">&quot;anaconda&quot;</span><span class="p">])</span><span class="o">.</span><span class="n">available</span><span class="p">:</span>
<span class="k">if</span> <span class="n">anaconda</span><span class="o">.</span><span class="n">arch</span> <span class="o">!=</span> <span class="s">&quot;src&quot;</span><span class="p">:</span>
<span class="n">buildarch</span> <span class="o">=</span> <span class="n">anaconda</span><span class="o">.</span><span class="n">arch</span>
<span class="k">break</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">buildarch</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">critical</span><span class="p">(</span><span class="s">&quot;no anaconda package in the repository&quot;</span><span class="p">)</span>
<span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="k">return</span> <span class="n">buildarch</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">Lorax 19.7.10 documentation</a> &raquo;</li>
<li><a href="../index.html" >Module code</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2017, Red Hat, Inc..
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>

View File

@ -0,0 +1,114 @@
<!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>pylorax.api &mdash; Lorax 19.7.10 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: '19.7.10',
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>
<link rel="top" title="Lorax 19.7.10 documentation" href="../../index.html" />
<link rel="up" title="Module code" href="../index.html" />
</head>
<body>
<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">Lorax 19.7.10 documentation</a> &raquo;</li>
<li><a href="../index.html" accesskey="U">Module code</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<h1>Source code for pylorax.api</h1><div class="highlight"><pre>
<span class="c">#</span>
<span class="c"># lorax-composer API server</span>
<span class="c">#</span>
<span class="c"># Copyright (C) 2017 Red Hat, Inc.</span>
<span class="c">#</span>
<span class="c"># This program is free software; you can redistribute it and/or modify</span>
<span class="c"># it under the terms of the GNU General Public License as published by</span>
<span class="c"># the Free Software Foundation; either version 2 of the License, or</span>
<span class="c"># (at your option) any later version.</span>
<span class="c">#</span>
<span class="c"># This program is distributed in the hope that it will be useful,</span>
<span class="c"># but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<span class="c"># MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span>
<span class="c"># GNU General Public License for more details.</span>
<span class="c">#</span>
<span class="c"># You should have received a copy of the GNU General Public License</span>
<span class="c"># along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;.</span>
<span class="kn">from</span> <span class="nn">pylorax.api.crossdomain</span> <span class="kn">import</span> <span class="n">crossdomain</span>
<span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span><span class="s">&quot;crossdomain&quot;</span><span class="p">]</span>
</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">Lorax 19.7.10 documentation</a> &raquo;</li>
<li><a href="../index.html" >Module code</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2017, Red Hat, Inc..
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>

View File

@ -0,0 +1,417 @@
<!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>pylorax.api.compose &mdash; Lorax 19.7.10 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: '19.7.10',
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>
<link rel="top" title="Lorax 19.7.10 documentation" href="../../../index.html" />
<link rel="up" title="pylorax.api" href="../api.html" />
</head>
<body>
<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">Lorax 19.7.10 documentation</a> &raquo;</li>
<li><a href="../../index.html" >Module code</a> &raquo;</li>
<li><a href="../api.html" accesskey="U">pylorax.api</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<h1>Source code for pylorax.api.compose</h1><div class="highlight"><pre>
<span class="c"># Copyright (C) 2018 Red Hat, Inc.</span>
<span class="c">#</span>
<span class="c"># This program is free software; you can redistribute it and/or modify</span>
<span class="c"># it under the terms of the GNU General Public License as published by</span>
<span class="c"># the Free Software Foundation; either version 2 of the License, or</span>
<span class="c"># (at your option) any later version.</span>
<span class="c">#</span>
<span class="c"># This program is distributed in the hope that it will be useful,</span>
<span class="c"># but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<span class="c"># MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span>
<span class="c"># GNU General Public License for more details.</span>
<span class="c">#</span>
<span class="c"># You should have received a copy of the GNU General Public License</span>
<span class="c"># along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;.</span>
<span class="c">#</span>
<span class="sd">&quot;&quot;&quot; Setup for composing an image</span>
<span class="sd">Adding New Output Types</span>
<span class="sd">-----------------------</span>
<span class="sd">The new output type must add a kickstart template to ./share/composer/ where the</span>
<span class="sd">name of the kickstart (without the trailing .ks) matches the entry in compose_args.</span>
<span class="sd">The kickstart should not have any url or repo entries, these will be added at build</span>
<span class="sd">time. The %packages section should be the last thing, and while it can contain mandatory</span>
<span class="sd">packages required by the output type, it should not have the trailing %end because the</span>
<span class="sd">package NEVRAs will be appended to it at build time.</span>
<span class="sd">compose_args should have a name matching the kickstart, and it should set the novirt_install</span>
<span class="sd">parameters needed to generate the desired output. Other types should be set to False.</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="kn">import</span> <span class="nn">logging</span>
<span class="n">log</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s">&quot;lorax-composer&quot;</span><span class="p">)</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">from</span> <span class="nn">glob</span> <span class="kn">import</span> <span class="n">glob</span>
<span class="kn">import</span> <span class="nn">pytoml</span> <span class="kn">as</span> <span class="nn">toml</span>
<span class="kn">import</span> <span class="nn">shutil</span>
<span class="kn">from</span> <span class="nn">uuid</span> <span class="kn">import</span> <span class="n">uuid4</span>
<span class="kn">from</span> <span class="nn">pyanaconda.simpleconfig</span> <span class="kn">import</span> <span class="n">SimpleConfigFile</span>
<span class="kn">from</span> <span class="nn">pylorax.api.projects</span> <span class="kn">import</span> <span class="n">projects_depsolve</span><span class="p">,</span> <span class="n">dep_nevra</span>
<span class="kn">from</span> <span class="nn">pylorax.api.projects</span> <span class="kn">import</span> <span class="n">ProjectsError</span>
<span class="kn">from</span> <span class="nn">pylorax.api.recipes</span> <span class="kn">import</span> <span class="n">read_recipe_and_id</span>
<span class="kn">from</span> <span class="nn">pylorax.imgutils</span> <span class="kn">import</span> <span class="n">default_image_name</span>
<span class="kn">from</span> <span class="nn">pylorax.sysutils</span> <span class="kn">import</span> <span class="n">joinpaths</span>
<div class="viewcode-block" id="repo_to_ks"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.compose.repo_to_ks">[docs]</a><span class="k">def</span> <span class="nf">repo_to_ks</span><span class="p">(</span><span class="n">r</span><span class="p">,</span> <span class="n">url</span><span class="o">=</span><span class="s">&quot;url&quot;</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot; Return a kickstart line with the correct args.</span>
<span class="sd"> Set url to &quot;baseurl&quot; if it is a repo, leave it as &quot;url&quot; for the installation url.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">cmd</span> <span class="o">=</span> <span class="s">&quot;&quot;</span>
<span class="k">if</span> <span class="n">url</span> <span class="o">==</span> <span class="s">&quot;url&quot;</span><span class="p">:</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">r</span><span class="o">.</span><span class="n">urls</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s">&quot;Cannot find a base url for </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">r</span><span class="o">.</span><span class="n">name</span><span class="p">)</span>
<span class="c"># url is passed to Anaconda on the cmdline with --repo, so it cannot support a mirror</span>
<span class="c"># If a mirror is setup yum will return the list of mirrors in .urls</span>
<span class="c"># So just use the first one.</span>
<span class="n">cmd</span> <span class="o">+=</span> <span class="s">&#39;--</span><span class="si">%s</span><span class="s">=&quot;</span><span class="si">%s</span><span class="s">&quot; &#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">r</span><span class="o">.</span><span class="n">urls</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
<span class="k">elif</span> <span class="n">r</span><span class="o">.</span><span class="n">metalink</span><span class="p">:</span>
<span class="c"># XXX Total Hack</span>
<span class="c"># RHEL7 kickstart doesn&#39;t support metalink. If the url has &#39;metalink&#39; in it, rewrite it as &#39;mirrorlist&#39;</span>
<span class="k">if</span> <span class="s">&quot;metalink&quot;</span> <span class="ow">in</span> <span class="n">r</span><span class="o">.</span><span class="n">metalink</span><span class="p">:</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;RHEL7 does not support metalink, translating to mirrorlist&quot;</span><span class="p">)</span>
<span class="n">cmd</span> <span class="o">+=</span> <span class="s">&#39;--mirrorlist=&quot;</span><span class="si">%s</span><span class="s">&quot; &#39;</span> <span class="o">%</span> <span class="n">r</span><span class="o">.</span><span class="n">metalink</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s">&quot;metalink&quot;</span><span class="p">,</span> <span class="s">&quot;mirrorlist&quot;</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">log</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s">&quot;Could not convert metalink to mirrorlist. </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">r</span><span class="o">.</span><span class="n">metalink</span><span class="p">)</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s">&quot;Cannot convert metalink to mirrorlist: </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">r</span><span class="o">.</span><span class="n">metalink</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">r</span><span class="o">.</span><span class="n">mirrorlist</span><span class="p">:</span>
<span class="n">cmd</span> <span class="o">+=</span> <span class="s">&#39;--mirrorlist=&quot;</span><span class="si">%s</span><span class="s">&quot; &#39;</span> <span class="o">%</span> <span class="n">r</span><span class="o">.</span><span class="n">mirrorlist</span>
<span class="k">elif</span> <span class="n">r</span><span class="o">.</span><span class="n">baseurl</span><span class="p">:</span>
<span class="n">cmd</span> <span class="o">+=</span> <span class="s">&#39;--</span><span class="si">%s</span><span class="s">=&quot;</span><span class="si">%s</span><span class="s">&quot; &#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">r</span><span class="o">.</span><span class="n">baseurl</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s">&quot;Repo has no baseurl or mirror&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">r</span><span class="o">.</span><span class="n">proxy</span><span class="p">:</span>
<span class="n">cmd</span> <span class="o">+=</span> <span class="s">&#39;--proxy=&quot;</span><span class="si">%s</span><span class="s">&quot; &#39;</span> <span class="o">%</span> <span class="n">r</span><span class="o">.</span><span class="n">proxy</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">r</span><span class="o">.</span><span class="n">sslverify</span><span class="p">:</span>
<span class="n">cmd</span> <span class="o">+=</span> <span class="s">&#39;--noverifyssl&#39;</span>
<span class="k">return</span> <span class="n">cmd</span>
</div>
<div class="viewcode-block" id="start_build"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.compose.start_build">[docs]</a><span class="k">def</span> <span class="nf">start_build</span><span class="p">(</span><span class="n">cfg</span><span class="p">,</span> <span class="n">yumlock</span><span class="p">,</span> <span class="n">gitlock</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">recipe_name</span><span class="p">,</span> <span class="n">compose_type</span><span class="p">,</span> <span class="n">test_mode</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot; Start the build</span>
<span class="sd"> :param cfg: Configuration object</span>
<span class="sd"> :type cfg: ComposerConfig</span>
<span class="sd"> :param yumlock: Lock and YumBase for depsolving</span>
<span class="sd"> :type yumlock: YumLock</span>
<span class="sd"> :param recipe: The recipe to build</span>
<span class="sd"> :type recipe: str</span>
<span class="sd"> :param compose_type: The type of output to create from the recipe</span>
<span class="sd"> :type compose_type: str</span>
<span class="sd"> :returns: Unique ID for the build that can be used to track its status</span>
<span class="sd"> :rtype: str</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">share_dir</span> <span class="o">=</span> <span class="n">cfg</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">&quot;composer&quot;</span><span class="p">,</span> <span class="s">&quot;share_dir&quot;</span><span class="p">)</span>
<span class="n">lib_dir</span> <span class="o">=</span> <span class="n">cfg</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">&quot;composer&quot;</span><span class="p">,</span> <span class="s">&quot;lib_dir&quot;</span><span class="p">)</span>
<span class="c"># Make sure compose_type is valid</span>
<span class="k">if</span> <span class="n">compose_type</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">compose_types</span><span class="p">(</span><span class="n">share_dir</span><span class="p">):</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s">&quot;Invalid compose type (</span><span class="si">%s</span><span class="s">), must be one of </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">compose_type</span><span class="p">,</span> <span class="n">compose_types</span><span class="p">(</span><span class="n">share_dir</span><span class="p">)))</span>
<span class="k">with</span> <span class="n">gitlock</span><span class="o">.</span><span class="n">lock</span><span class="p">:</span>
<span class="p">(</span><span class="n">commit_id</span><span class="p">,</span> <span class="n">recipe</span><span class="p">)</span> <span class="o">=</span> <span class="n">read_recipe_and_id</span><span class="p">(</span><span class="n">gitlock</span><span class="o">.</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">recipe_name</span><span class="p">)</span>
<span class="c"># Combine modules and packages and depsolve the list</span>
<span class="c"># TODO include the version/glob in the depsolving</span>
<span class="n">module_names</span> <span class="o">=</span> <span class="nb">map</span><span class="p">(</span><span class="k">lambda</span> <span class="n">m</span><span class="p">:</span> <span class="n">m</span><span class="p">[</span><span class="s">&quot;name&quot;</span><span class="p">],</span> <span class="n">recipe</span><span class="p">[</span><span class="s">&quot;modules&quot;</span><span class="p">]</span> <span class="ow">or</span> <span class="p">[])</span>
<span class="n">package_names</span> <span class="o">=</span> <span class="nb">map</span><span class="p">(</span><span class="k">lambda</span> <span class="n">p</span><span class="p">:</span> <span class="n">p</span><span class="p">[</span><span class="s">&quot;name&quot;</span><span class="p">],</span> <span class="n">recipe</span><span class="p">[</span><span class="s">&quot;packages&quot;</span><span class="p">]</span> <span class="ow">or</span> <span class="p">[])</span>
<span class="n">projects</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="nb">set</span><span class="p">(</span><span class="n">module_names</span><span class="o">+</span><span class="n">package_names</span><span class="p">),</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">n</span><span class="p">:</span> <span class="n">n</span><span class="o">.</span><span class="n">lower</span><span class="p">())</span>
<span class="n">deps</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">with</span> <span class="n">yumlock</span><span class="o">.</span><span class="n">lock</span><span class="p">:</span>
<span class="n">deps</span> <span class="o">=</span> <span class="n">projects_depsolve</span><span class="p">(</span><span class="n">yumlock</span><span class="o">.</span><span class="n">yb</span><span class="p">,</span> <span class="n">projects</span><span class="p">)</span>
<span class="k">except</span> <span class="n">ProjectsError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="n">log</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s">&quot;start_build depsolve: </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">))</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s">&quot;Problem depsolving </span><span class="si">%s</span><span class="s">: </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">recipe</span><span class="p">[</span><span class="s">&quot;name&quot;</span><span class="p">],</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">)))</span>
<span class="c"># Create the results directory</span>
<span class="n">build_id</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">uuid4</span><span class="p">())</span>
<span class="n">results_dir</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">lib_dir</span><span class="p">,</span> <span class="s">&quot;results&quot;</span><span class="p">,</span> <span class="n">build_id</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">makedirs</span><span class="p">(</span><span class="n">results_dir</span><span class="p">)</span>
<span class="c"># Write the recipe commit hash</span>
<span class="n">commit_path</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">results_dir</span><span class="p">,</span> <span class="s">&quot;COMMIT&quot;</span><span class="p">)</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">commit_path</span><span class="p">,</span> <span class="s">&quot;w&quot;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">commit_id</span><span class="p">)</span>
<span class="c"># Write the original recipe</span>
<span class="n">recipe_path</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">results_dir</span><span class="p">,</span> <span class="s">&quot;recipe.toml&quot;</span><span class="p">)</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">recipe_path</span><span class="p">,</span> <span class="s">&quot;w&quot;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">recipe</span><span class="o">.</span><span class="n">toml</span><span class="p">())</span>
<span class="c"># Write the frozen recipe</span>
<span class="n">frozen_recipe</span> <span class="o">=</span> <span class="n">recipe</span><span class="o">.</span><span class="n">freeze</span><span class="p">(</span><span class="n">deps</span><span class="p">)</span>
<span class="n">recipe_path</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">results_dir</span><span class="p">,</span> <span class="s">&quot;frozen.toml&quot;</span><span class="p">)</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">recipe_path</span><span class="p">,</span> <span class="s">&quot;w&quot;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">frozen_recipe</span><span class="o">.</span><span class="n">toml</span><span class="p">())</span>
<span class="c"># Read the kickstart template for this type and copy it into the results</span>
<span class="n">ks_template_path</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">share_dir</span><span class="p">,</span> <span class="s">&quot;composer&quot;</span><span class="p">,</span> <span class="n">compose_type</span><span class="p">)</span> <span class="o">+</span> <span class="s">&quot;.ks&quot;</span>
<span class="n">shutil</span><span class="o">.</span><span class="n">copy</span><span class="p">(</span><span class="n">ks_template_path</span><span class="p">,</span> <span class="n">results_dir</span><span class="p">)</span>
<span class="n">ks_template</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">ks_template_path</span><span class="p">,</span> <span class="s">&quot;r&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
<span class="c"># Write out the dependencies to the results dir</span>
<span class="n">deps_path</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">results_dir</span><span class="p">,</span> <span class="s">&quot;deps.toml&quot;</span><span class="p">)</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">deps_path</span><span class="p">,</span> <span class="s">&quot;w&quot;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">toml</span><span class="o">.</span><span class="n">dumps</span><span class="p">({</span><span class="s">&quot;packages&quot;</span><span class="p">:</span><span class="n">deps</span><span class="p">})</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s">&quot;UTF-8&quot;</span><span class="p">))</span>
<span class="c"># Create the final kickstart with repos and package list</span>
<span class="n">ks_path</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">results_dir</span><span class="p">,</span> <span class="s">&quot;final-kickstart.ks&quot;</span><span class="p">)</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">ks_path</span><span class="p">,</span> <span class="s">&quot;w&quot;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
<span class="k">with</span> <span class="n">yumlock</span><span class="o">.</span><span class="n">lock</span><span class="p">:</span>
<span class="n">repos</span> <span class="o">=</span> <span class="n">yumlock</span><span class="o">.</span><span class="n">yb</span><span class="o">.</span><span class="n">repos</span><span class="o">.</span><span class="n">listEnabled</span><span class="p">()</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">repos</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s">&quot;No enabled repos, canceling build.&quot;</span><span class="p">)</span>
<span class="n">ks_url</span> <span class="o">=</span> <span class="n">repo_to_ks</span><span class="p">(</span><span class="n">repos</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="s">&quot;url&quot;</span><span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">&quot;url = </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">ks_url</span><span class="p">)</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">&#39;url </span><span class="si">%s</span><span class="se">\n</span><span class="s">&#39;</span> <span class="o">%</span> <span class="n">ks_url</span><span class="p">)</span>
<span class="k">for</span> <span class="n">idx</span><span class="p">,</span> <span class="n">r</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">repos</span><span class="p">[</span><span class="mi">1</span><span class="p">:]):</span>
<span class="n">ks_repo</span> <span class="o">=</span> <span class="n">repo_to_ks</span><span class="p">(</span><span class="n">r</span><span class="p">,</span> <span class="s">&quot;baseurl&quot;</span><span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">&quot;repo composer-</span><span class="si">%s</span><span class="s"> = </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">idx</span><span class="p">,</span> <span class="n">ks_repo</span><span class="p">)</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">&#39;repo --name=&quot;composer-</span><span class="si">%s</span><span class="s">&quot; </span><span class="si">%s</span><span class="se">\n</span><span class="s">&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">idx</span><span class="p">,</span> <span class="n">ks_repo</span><span class="p">))</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">ks_template</span><span class="p">)</span>
<span class="k">for</span> <span class="n">d</span> <span class="ow">in</span> <span class="n">deps</span><span class="p">:</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">dep_nevra</span><span class="p">(</span><span class="n">d</span><span class="p">)</span><span class="o">+</span><span class="s">&quot;</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">)</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">&quot;</span><span class="si">%e</span><span class="s">nd</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">)</span>
<span class="c"># Setup the config to pass to novirt_install</span>
<span class="n">log_dir</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">results_dir</span><span class="p">,</span> <span class="s">&quot;logs/&quot;</span><span class="p">)</span>
<span class="n">cfg_args</span> <span class="o">=</span> <span class="n">compose_args</span><span class="p">(</span><span class="n">compose_type</span><span class="p">)</span>
<span class="c"># Get the title, project, and release version from the host</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="s">&quot;/etc/os-release&quot;</span><span class="p">):</span>
<span class="n">log</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s">&quot;/etc/os-release is missing, cannot determine product or release version&quot;</span><span class="p">)</span>
<span class="n">os_release</span> <span class="o">=</span> <span class="n">SimpleConfigFile</span><span class="p">(</span><span class="s">&quot;/etc/os-release&quot;</span><span class="p">)</span>
<span class="n">os_release</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
<span class="n">log</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">&quot;os_release = </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">os_release</span><span class="p">)</span>
<span class="n">cfg_args</span><span class="p">[</span><span class="s">&quot;title&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">os_release</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">&quot;PRETTY_NAME&quot;</span><span class="p">)</span>
<span class="n">cfg_args</span><span class="p">[</span><span class="s">&quot;project&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">os_release</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>
<span class="n">cfg_args</span><span class="p">[</span><span class="s">&quot;releasever&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">os_release</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">&quot;VERSION_ID&quot;</span><span class="p">)</span>
<span class="n">cfg_args</span><span class="p">[</span><span class="s">&quot;volid&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="s">&quot;&quot;</span>
<span class="n">cfg_args</span><span class="o">.</span><span class="n">update</span><span class="p">({</span>
<span class="s">&quot;compression&quot;</span><span class="p">:</span> <span class="s">&quot;xz&quot;</span><span class="p">,</span>
<span class="s">&quot;compress_args&quot;</span><span class="p">:</span> <span class="p">[],</span>
<span class="s">&quot;ks&quot;</span><span class="p">:</span> <span class="p">[</span><span class="n">ks_path</span><span class="p">],</span>
<span class="s">&quot;project&quot;</span><span class="p">:</span> <span class="s">&quot;Red Hat Enterprise Linux&quot;</span><span class="p">,</span>
<span class="s">&quot;releasever&quot;</span><span class="p">:</span> <span class="s">&quot;7&quot;</span><span class="p">,</span>
<span class="s">&quot;logfile&quot;</span><span class="p">:</span> <span class="n">log_dir</span>
<span class="p">})</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">results_dir</span><span class="p">,</span> <span class="s">&quot;config.toml&quot;</span><span class="p">),</span> <span class="s">&quot;w&quot;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">toml</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">cfg_args</span><span class="p">)</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s">&quot;UTF-8&quot;</span><span class="p">))</span>
<span class="c"># Set the initial status</span>
<span class="nb">open</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">results_dir</span><span class="p">,</span> <span class="s">&quot;STATUS&quot;</span><span class="p">),</span> <span class="s">&quot;w&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">&quot;WAITING&quot;</span><span class="p">)</span>
<span class="c"># Set the test mode, if requested</span>
<span class="k">if</span> <span class="n">test_mode</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
<span class="nb">open</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">results_dir</span><span class="p">,</span> <span class="s">&quot;TEST&quot;</span><span class="p">),</span> <span class="s">&quot;w&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">&quot;</span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">test_mode</span><span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;Adding </span><span class="si">%s</span><span class="s"> with recipe </span><span class="si">%s</span><span class="s"> output type </span><span class="si">%s</span><span class="s"> to compose queue&quot;</span><span class="p">,</span> <span class="n">build_id</span><span class="p">,</span> <span class="n">recipe</span><span class="p">[</span><span class="s">&quot;name&quot;</span><span class="p">],</span> <span class="n">compose_type</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">symlink</span><span class="p">(</span><span class="n">results_dir</span><span class="p">,</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">lib_dir</span><span class="p">,</span> <span class="s">&quot;queue/new/&quot;</span><span class="p">,</span> <span class="n">build_id</span><span class="p">))</span>
<span class="k">return</span> <span class="n">build_id</span>
<span class="c"># Supported output types</span></div>
<div class="viewcode-block" id="compose_types"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.compose.compose_types">[docs]</a><span class="k">def</span> <span class="nf">compose_types</span><span class="p">(</span><span class="n">share_dir</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot; Returns a list of the supported output types</span>
<span class="sd"> The output types come from the kickstart names in /usr/share/lorax/composer/*ks</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">return</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">ks</span><span class="p">)[:</span><span class="o">-</span><span class="mi">3</span><span class="p">]</span> <span class="k">for</span> <span class="n">ks</span> <span class="ow">in</span> <span class="n">glob</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">share_dir</span><span class="p">,</span> <span class="s">&quot;composer/*.ks&quot;</span><span class="p">))]</span>
</div>
<div class="viewcode-block" id="compose_args"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.compose.compose_args">[docs]</a><span class="k">def</span> <span class="nf">compose_args</span><span class="p">(</span><span class="n">compose_type</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot; Returns the settings to pass to novirt_install for the compose type</span>
<span class="sd"> :param compose_type: The type of compose to create, from `compose_types()`</span>
<span class="sd"> :type compose_type: str</span>
<span class="sd"> This will return a dict of options that match the ArgumentParser options for livemedia-creator.</span>
<span class="sd"> These are the ones the define the type of output, it&#39;s filename, etc.</span>
<span class="sd"> Other options will be filled in by `make_compose()`</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">_MAP</span> <span class="o">=</span> <span class="p">{</span><span class="s">&quot;tar&quot;</span><span class="p">:</span> <span class="p">{</span><span class="s">&quot;make_iso&quot;</span><span class="p">:</span> <span class="bp">False</span><span class="p">,</span>
<span class="s">&quot;make_disk&quot;</span><span class="p">:</span> <span class="bp">False</span><span class="p">,</span>
<span class="s">&quot;make_fsimage&quot;</span><span class="p">:</span> <span class="bp">False</span><span class="p">,</span>
<span class="s">&quot;make_appliance&quot;</span><span class="p">:</span> <span class="bp">False</span><span class="p">,</span>
<span class="s">&quot;make_ami&quot;</span><span class="p">:</span> <span class="bp">False</span><span class="p">,</span>
<span class="s">&quot;make_tar&quot;</span><span class="p">:</span> <span class="bp">True</span><span class="p">,</span>
<span class="s">&quot;make_pxe_live&quot;</span><span class="p">:</span> <span class="bp">False</span><span class="p">,</span>
<span class="s">&quot;make_ostree_live&quot;</span><span class="p">:</span> <span class="bp">False</span><span class="p">,</span>
<span class="s">&quot;ostree&quot;</span><span class="p">:</span> <span class="bp">False</span><span class="p">,</span>
<span class="s">&quot;live_rootfs_keep_size&quot;</span><span class="p">:</span> <span class="bp">False</span><span class="p">,</span>
<span class="s">&quot;live_rootfs_size&quot;</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span>
<span class="s">&quot;qcow2&quot;</span><span class="p">:</span> <span class="bp">False</span><span class="p">,</span>
<span class="s">&quot;qcow2_arg&quot;</span><span class="p">:</span> <span class="p">[],</span>
<span class="s">&quot;image_name&quot;</span><span class="p">:</span> <span class="n">default_image_name</span><span class="p">(</span><span class="s">&quot;xz&quot;</span><span class="p">,</span> <span class="s">&quot;root.tar&quot;</span><span class="p">),</span>
<span class="s">&quot;image_only&quot;</span><span class="p">:</span> <span class="bp">True</span><span class="p">,</span>
<span class="s">&quot;app_name&quot;</span><span class="p">:</span> <span class="bp">None</span><span class="p">,</span>
<span class="s">&quot;app_template&quot;</span><span class="p">:</span> <span class="bp">None</span><span class="p">,</span>
<span class="s">&quot;app_file&quot;</span><span class="p">:</span> <span class="bp">None</span>
<span class="p">},</span>
<span class="s">&quot;live-iso&quot;</span><span class="p">:</span> <span class="p">{</span><span class="s">&quot;make_iso&quot;</span><span class="p">:</span> <span class="bp">True</span><span class="p">,</span>
<span class="s">&quot;make_disk&quot;</span><span class="p">:</span> <span class="bp">False</span><span class="p">,</span>
<span class="s">&quot;make_fsimage&quot;</span><span class="p">:</span> <span class="bp">False</span><span class="p">,</span>
<span class="s">&quot;make_appliance&quot;</span><span class="p">:</span> <span class="bp">False</span><span class="p">,</span>
<span class="s">&quot;make_ami&quot;</span><span class="p">:</span> <span class="bp">False</span><span class="p">,</span>
<span class="s">&quot;make_tar&quot;</span><span class="p">:</span> <span class="bp">False</span><span class="p">,</span>
<span class="s">&quot;make_pxe_live&quot;</span><span class="p">:</span> <span class="bp">False</span><span class="p">,</span>
<span class="s">&quot;make_ostree_live&quot;</span><span class="p">:</span> <span class="bp">False</span><span class="p">,</span>
<span class="s">&quot;ostree&quot;</span><span class="p">:</span> <span class="bp">False</span><span class="p">,</span>
<span class="s">&quot;live_rootfs_keep_size&quot;</span><span class="p">:</span> <span class="bp">False</span><span class="p">,</span>
<span class="s">&quot;live_rootfs_size&quot;</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span>
<span class="s">&quot;qcow2&quot;</span><span class="p">:</span> <span class="bp">False</span><span class="p">,</span>
<span class="s">&quot;qcow2_arg&quot;</span><span class="p">:</span> <span class="p">[],</span>
<span class="s">&quot;image_name&quot;</span><span class="p">:</span> <span class="s">&quot;live.iso&quot;</span><span class="p">,</span>
<span class="s">&quot;fs_label&quot;</span><span class="p">:</span> <span class="s">&quot;Anaconda&quot;</span><span class="p">,</span> <span class="c"># Live booting may expect this to be &#39;Anaconda&#39;</span>
<span class="s">&quot;image_only&quot;</span><span class="p">:</span> <span class="bp">False</span><span class="p">,</span>
<span class="s">&quot;app_name&quot;</span><span class="p">:</span> <span class="bp">None</span><span class="p">,</span>
<span class="s">&quot;app_template&quot;</span><span class="p">:</span> <span class="bp">None</span><span class="p">,</span>
<span class="s">&quot;app_file&quot;</span><span class="p">:</span> <span class="bp">None</span>
<span class="p">},</span>
<span class="s">&quot;partitioned-disk&quot;</span><span class="p">:</span> <span class="p">{</span><span class="s">&quot;make_iso&quot;</span><span class="p">:</span> <span class="bp">False</span><span class="p">,</span>
<span class="s">&quot;make_disk&quot;</span><span class="p">:</span> <span class="bp">True</span><span class="p">,</span>
<span class="s">&quot;make_fsimage&quot;</span><span class="p">:</span> <span class="bp">False</span><span class="p">,</span>
<span class="s">&quot;make_appliance&quot;</span><span class="p">:</span> <span class="bp">False</span><span class="p">,</span>
<span class="s">&quot;make_ami&quot;</span><span class="p">:</span> <span class="bp">False</span><span class="p">,</span>
<span class="s">&quot;make_tar&quot;</span><span class="p">:</span> <span class="bp">False</span><span class="p">,</span>
<span class="s">&quot;make_pxe_live&quot;</span><span class="p">:</span> <span class="bp">False</span><span class="p">,</span>
<span class="s">&quot;make_ostree_live&quot;</span><span class="p">:</span> <span class="bp">False</span><span class="p">,</span>
<span class="s">&quot;ostree&quot;</span><span class="p">:</span> <span class="bp">False</span><span class="p">,</span>
<span class="s">&quot;live_rootfs_keep_size&quot;</span><span class="p">:</span> <span class="bp">False</span><span class="p">,</span>
<span class="s">&quot;live_rootfs_size&quot;</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span>
<span class="s">&quot;qcow2&quot;</span><span class="p">:</span> <span class="bp">False</span><span class="p">,</span>
<span class="s">&quot;qcow2_arg&quot;</span><span class="p">:</span> <span class="p">[],</span>
<span class="s">&quot;image_name&quot;</span><span class="p">:</span> <span class="s">&quot;disk.img&quot;</span><span class="p">,</span>
<span class="s">&quot;fs_label&quot;</span><span class="p">:</span> <span class="s">&quot;&quot;</span><span class="p">,</span>
<span class="s">&quot;image_only&quot;</span><span class="p">:</span> <span class="bp">True</span><span class="p">,</span>
<span class="s">&quot;app_name&quot;</span><span class="p">:</span> <span class="bp">None</span><span class="p">,</span>
<span class="s">&quot;app_template&quot;</span><span class="p">:</span> <span class="bp">None</span><span class="p">,</span>
<span class="s">&quot;app_file&quot;</span><span class="p">:</span> <span class="bp">None</span>
<span class="p">},</span>
<span class="p">}</span>
<span class="k">return</span> <span class="n">_MAP</span><span class="p">[</span><span class="n">compose_type</span><span class="p">]</span>
</div>
<div class="viewcode-block" id="move_compose_results"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.compose.move_compose_results">[docs]</a><span class="k">def</span> <span class="nf">move_compose_results</span><span class="p">(</span><span class="n">cfg</span><span class="p">,</span> <span class="n">results_dir</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Move the final image to the results_dir and cleanup the unneeded compose files</span>
<span class="sd"> :param cfg: Build configuration</span>
<span class="sd"> :type cfg: DataHolder</span>
<span class="sd"> :param results_dir: Directory to put the results into</span>
<span class="sd"> :type results_dir: str</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">cfg</span><span class="p">[</span><span class="s">&quot;make_tar&quot;</span><span class="p">]:</span>
<span class="n">shutil</span><span class="o">.</span><span class="n">move</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">cfg</span><span class="p">[</span><span class="s">&quot;result_dir&quot;</span><span class="p">],</span> <span class="n">cfg</span><span class="p">[</span><span class="s">&quot;image_name&quot;</span><span class="p">]),</span> <span class="n">results_dir</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">cfg</span><span class="p">[</span><span class="s">&quot;make_iso&quot;</span><span class="p">]:</span>
<span class="c"># Output from live iso is always a boot.iso under images/, move and rename it</span>
<span class="n">shutil</span><span class="o">.</span><span class="n">move</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">cfg</span><span class="p">[</span><span class="s">&quot;result_dir&quot;</span><span class="p">],</span> <span class="s">&quot;images/boot.iso&quot;</span><span class="p">),</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">results_dir</span><span class="p">,</span> <span class="n">cfg</span><span class="p">[</span><span class="s">&quot;image_name&quot;</span><span class="p">]))</span>
<span class="k">elif</span> <span class="n">cfg</span><span class="p">[</span><span class="s">&quot;make_disk&quot;</span><span class="p">]:</span>
<span class="n">shutil</span><span class="o">.</span><span class="n">move</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">cfg</span><span class="p">[</span><span class="s">&quot;result_dir&quot;</span><span class="p">],</span> <span class="n">cfg</span><span class="p">[</span><span class="s">&quot;image_name&quot;</span><span class="p">]),</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">results_dir</span><span class="p">,</span> <span class="n">cfg</span><span class="p">[</span><span class="s">&quot;image_name&quot;</span><span class="p">]))</span>
<span class="c"># Cleanup the compose directory, but only if it looks like a compose directory</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">basename</span><span class="p">(</span><span class="n">cfg</span><span class="p">[</span><span class="s">&quot;result_dir&quot;</span><span class="p">])</span> <span class="o">==</span> <span class="s">&quot;compose&quot;</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">cfg</span><span class="p">[</span><span class="s">&quot;result_dir&quot;</span><span class="p">])</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">log</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s">&quot;Incorrect compose directory, not cleaning up&quot;</span><span class="p">)</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">Lorax 19.7.10 documentation</a> &raquo;</li>
<li><a href="../../index.html" >Module code</a> &raquo;</li>
<li><a href="../api.html" >pylorax.api</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2017, Red Hat, Inc..
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>

View File

@ -0,0 +1,202 @@
<!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>pylorax.api.config &mdash; Lorax 19.7.10 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: '19.7.10',
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>
<link rel="top" title="Lorax 19.7.10 documentation" href="../../../index.html" />
<link rel="up" title="pylorax.api" href="../api.html" />
</head>
<body>
<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">Lorax 19.7.10 documentation</a> &raquo;</li>
<li><a href="../../index.html" >Module code</a> &raquo;</li>
<li><a href="../api.html" accesskey="U">pylorax.api</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<h1>Source code for pylorax.api.config</h1><div class="highlight"><pre>
<span class="c">#</span>
<span class="c"># Copyright (C) 2017 Red Hat, Inc.</span>
<span class="c">#</span>
<span class="c"># This program is free software; you can redistribute it and/or modify</span>
<span class="c"># it under the terms of the GNU General Public License as published by</span>
<span class="c"># the Free Software Foundation; either version 2 of the License, or</span>
<span class="c"># (at your option) any later version.</span>
<span class="c">#</span>
<span class="c"># This program is distributed in the hope that it will be useful,</span>
<span class="c"># but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<span class="c"># MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span>
<span class="c"># GNU General Public License for more details.</span>
<span class="c">#</span>
<span class="c"># You should have received a copy of the GNU General Public License</span>
<span class="c"># along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;.</span>
<span class="c">#</span>
<span class="kn">import</span> <span class="nn">ConfigParser</span>
<span class="kn">import</span> <span class="nn">grp</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">from</span> <span class="nn">pylorax.sysutils</span> <span class="kn">import</span> <span class="n">joinpaths</span>
<div class="viewcode-block" id="ComposerConfig"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.config.ComposerConfig">[docs]</a><span class="k">class</span> <span class="nc">ComposerConfig</span><span class="p">(</span><span class="n">ConfigParser</span><span class="o">.</span><span class="n">SafeConfigParser</span><span class="p">):</span>
<div class="viewcode-block" id="ComposerConfig.get_default"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.config.ComposerConfig.get_default">[docs]</a> <span class="k">def</span> <span class="nf">get_default</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">section</span><span class="p">,</span> <span class="n">option</span><span class="p">,</span> <span class="n">default</span><span class="p">):</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">section</span><span class="p">,</span> <span class="n">option</span><span class="p">)</span>
<span class="k">except</span> <span class="n">ConfigParser</span><span class="o">.</span><span class="n">Error</span><span class="p">:</span>
<span class="k">return</span> <span class="n">default</span>
</div></div>
<div class="viewcode-block" id="configure"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.config.configure">[docs]</a><span class="k">def</span> <span class="nf">configure</span><span class="p">(</span><span class="n">conf_file</span><span class="o">=</span><span class="s">&quot;/etc/lorax/composer.conf&quot;</span><span class="p">,</span> <span class="n">root_dir</span><span class="o">=</span><span class="s">&quot;/&quot;</span><span class="p">,</span> <span class="n">test_config</span><span class="o">=</span><span class="bp">False</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;lorax-composer configuration</span>
<span class="sd"> :param conf_file: Path to the config file overriding the default settings</span>
<span class="sd"> :type conf_file: str</span>
<span class="sd"> :param root_dir: Directory to prepend to paths, defaults to /</span>
<span class="sd"> :type root_dir: str</span>
<span class="sd"> :param test_config: Set to True to skip reading conf_file</span>
<span class="sd"> :type test_config: bool</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">conf</span> <span class="o">=</span> <span class="n">ComposerConfig</span><span class="p">()</span>
<span class="c"># set defaults</span>
<span class="n">conf</span><span class="o">.</span><span class="n">add_section</span><span class="p">(</span><span class="s">&quot;composer&quot;</span><span class="p">)</span>
<span class="n">conf</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s">&quot;composer&quot;</span><span class="p">,</span> <span class="s">&quot;share_dir&quot;</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">realpath</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">root_dir</span><span class="p">,</span> <span class="s">&quot;/usr/share/lorax/&quot;</span><span class="p">)))</span>
<span class="n">conf</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s">&quot;composer&quot;</span><span class="p">,</span> <span class="s">&quot;lib_dir&quot;</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">realpath</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">root_dir</span><span class="p">,</span> <span class="s">&quot;/var/lib/lorax/composer/&quot;</span><span class="p">)))</span>
<span class="n">conf</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s">&quot;composer&quot;</span><span class="p">,</span> <span class="s">&quot;yum_conf&quot;</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">realpath</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">root_dir</span><span class="p">,</span> <span class="s">&quot;/var/tmp/composer/yum.conf&quot;</span><span class="p">)))</span>
<span class="n">conf</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s">&quot;composer&quot;</span><span class="p">,</span> <span class="s">&quot;repo_dir&quot;</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">realpath</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">root_dir</span><span class="p">,</span> <span class="s">&quot;/var/tmp/composer/repos.d/&quot;</span><span class="p">)))</span>
<span class="n">conf</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s">&quot;composer&quot;</span><span class="p">,</span> <span class="s">&quot;cache_dir&quot;</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">realpath</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">root_dir</span><span class="p">,</span> <span class="s">&quot;/var/tmp/composer/cache/&quot;</span><span class="p">)))</span>
<span class="n">conf</span><span class="o">.</span><span class="n">add_section</span><span class="p">(</span><span class="s">&quot;users&quot;</span><span class="p">)</span>
<span class="n">conf</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s">&quot;users&quot;</span><span class="p">,</span> <span class="s">&quot;root&quot;</span><span class="p">,</span> <span class="s">&quot;1&quot;</span><span class="p">)</span>
<span class="c"># Enable all available repo files by default</span>
<span class="n">conf</span><span class="o">.</span><span class="n">add_section</span><span class="p">(</span><span class="s">&quot;repos&quot;</span><span class="p">)</span>
<span class="n">conf</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s">&quot;repos&quot;</span><span class="p">,</span> <span class="s">&quot;use_system_repos&quot;</span><span class="p">,</span> <span class="s">&quot;1&quot;</span><span class="p">)</span>
<span class="n">conf</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s">&quot;repos&quot;</span><span class="p">,</span> <span class="s">&quot;enabled&quot;</span><span class="p">,</span> <span class="s">&quot;*&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">test_config</span><span class="p">:</span>
<span class="c"># read the config file</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">isfile</span><span class="p">(</span><span class="n">conf_file</span><span class="p">):</span>
<span class="n">conf</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="n">conf_file</span><span class="p">)</span>
<span class="k">return</span> <span class="n">conf</span>
</div>
<div class="viewcode-block" id="make_yum_dirs"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.config.make_yum_dirs">[docs]</a><span class="k">def</span> <span class="nf">make_yum_dirs</span><span class="p">(</span><span class="n">conf</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Make any missing yum directories</span>
<span class="sd"> :param conf: The configuration to use</span>
<span class="sd"> :type conf: ComposerConfig</span>
<span class="sd"> :returns: None</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="p">[</span><span class="s">&quot;yum_conf&quot;</span><span class="p">,</span> <span class="s">&quot;repo_dir&quot;</span><span class="p">,</span> <span class="s">&quot;cache_dir&quot;</span><span class="p">]:</span>
<span class="n">p_dir</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">dirname</span><span class="p">(</span><span class="n">conf</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">&quot;composer&quot;</span><span class="p">,</span> <span class="n">p</span><span class="p">))</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">p_dir</span><span class="p">):</span>
<span class="n">os</span><span class="o">.</span><span class="n">makedirs</span><span class="p">(</span><span class="n">p_dir</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="make_queue_dirs"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.config.make_queue_dirs">[docs]</a><span class="k">def</span> <span class="nf">make_queue_dirs</span><span class="p">(</span><span class="n">conf</span><span class="p">,</span> <span class="n">gid</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Make any missing queue directories</span>
<span class="sd"> :param conf: The configuration to use</span>
<span class="sd"> :type conf: ComposerConfig</span>
<span class="sd"> :param gid: Group ID that has access to the queue directories</span>
<span class="sd"> :type gid: int</span>
<span class="sd"> :returns: list of errors</span>
<span class="sd"> :rtype: list of str</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">errors</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">lib_dir</span> <span class="o">=</span> <span class="n">conf</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">&quot;composer&quot;</span><span class="p">,</span> <span class="s">&quot;lib_dir&quot;</span><span class="p">)</span>
<span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="p">[</span><span class="s">&quot;queue/run&quot;</span><span class="p">,</span> <span class="s">&quot;queue/new&quot;</span><span class="p">,</span> <span class="s">&quot;results&quot;</span><span class="p">]:</span>
<span class="n">p_dir</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">lib_dir</span><span class="p">,</span> <span class="n">p</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">p_dir</span><span class="p">):</span>
<span class="n">orig_umask</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">umask</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">makedirs</span><span class="p">(</span><span class="n">p_dir</span><span class="p">,</span> <span class="mi">0</span><span class="n">o771</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">chown</span><span class="p">(</span><span class="n">p_dir</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">gid</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">umask</span><span class="p">(</span><span class="n">orig_umask</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">p_stat</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">stat</span><span class="p">(</span><span class="n">p_dir</span><span class="p">)</span>
<span class="k">if</span> <span class="n">p_stat</span><span class="o">.</span><span class="n">st_mode</span> <span class="o">&amp;</span> <span class="mi">0</span><span class="n">o006</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span>
<span class="n">errors</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s">&quot;Incorrect permissions on </span><span class="si">%s</span><span class="s">, no o+rw permissions are allowed.&quot;</span> <span class="o">%</span> <span class="n">p_dir</span><span class="p">)</span>
<span class="k">if</span> <span class="n">p_stat</span><span class="o">.</span><span class="n">st_gid</span> <span class="o">!=</span> <span class="n">gid</span> <span class="ow">or</span> <span class="n">p_stat</span><span class="o">.</span><span class="n">st_uid</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span>
<span class="n">gr_name</span> <span class="o">=</span> <span class="n">grp</span><span class="o">.</span><span class="n">getgrgid</span><span class="p">(</span><span class="n">gid</span><span class="p">)</span><span class="o">.</span><span class="n">gr_name</span>
<span class="n">errors</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s">&quot;</span><span class="si">%s</span><span class="s"> should be owned by root:</span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">p_dir</span><span class="p">,</span> <span class="n">gr_name</span><span class="p">))</span>
<span class="k">return</span> <span class="n">errors</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">Lorax 19.7.10 documentation</a> &raquo;</li>
<li><a href="../../index.html" >Module code</a> &raquo;</li>
<li><a href="../api.html" >pylorax.api</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2017, Red Hat, Inc..
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>

View File

@ -0,0 +1,160 @@
<!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>pylorax.api.crossdomain &mdash; Lorax 19.7.10 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: '19.7.10',
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>
<link rel="top" title="Lorax 19.7.10 documentation" href="../../../index.html" />
<link rel="up" title="pylorax.api" href="../api.html" />
</head>
<body>
<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">Lorax 19.7.10 documentation</a> &raquo;</li>
<li><a href="../../index.html" >Module code</a> &raquo;</li>
<li><a href="../api.html" accesskey="U">pylorax.api</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<h1>Source code for pylorax.api.crossdomain</h1><div class="highlight"><pre>
<span class="c">#</span>
<span class="c"># Copyright (C) 2017 Red Hat, Inc.</span>
<span class="c">#</span>
<span class="c"># This program is free software; you can redistribute it and/or modify</span>
<span class="c"># it under the terms of the GNU General Public License as published by</span>
<span class="c"># the Free Software Foundation; either version 2 of the License, or</span>
<span class="c"># (at your option) any later version.</span>
<span class="c">#</span>
<span class="c"># This program is distributed in the hope that it will be useful,</span>
<span class="c"># but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<span class="c"># MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span>
<span class="c"># GNU General Public License for more details.</span>
<span class="c">#</span>
<span class="c"># You should have received a copy of the GNU General Public License</span>
<span class="c"># along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;.</span>
<span class="c">#</span>
<span class="c"># crossdomain decorator from - http://flask.pocoo.org/snippets/56/</span>
<span class="kn">from</span> <span class="nn">datetime</span> <span class="kn">import</span> <span class="n">timedelta</span>
<span class="kn">from</span> <span class="nn">flask</span> <span class="kn">import</span> <span class="n">make_response</span><span class="p">,</span> <span class="n">request</span><span class="p">,</span> <span class="n">current_app</span>
<span class="kn">from</span> <span class="nn">functools</span> <span class="kn">import</span> <span class="n">update_wrapper</span>
<div class="viewcode-block" id="crossdomain"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.crossdomain.crossdomain">[docs]</a><span class="k">def</span> <span class="nf">crossdomain</span><span class="p">(</span><span class="n">origin</span><span class="p">,</span> <span class="n">methods</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">headers</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span>
<span class="n">max_age</span><span class="o">=</span><span class="mi">21600</span><span class="p">,</span> <span class="n">attach_to_all</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span>
<span class="n">automatic_options</span><span class="o">=</span><span class="bp">True</span><span class="p">):</span>
<span class="k">if</span> <span class="n">methods</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span>
<span class="n">methods</span> <span class="o">=</span> <span class="s">&#39;, &#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="nb">sorted</span><span class="p">(</span><span class="n">x</span><span class="o">.</span><span class="n">upper</span><span class="p">()</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">methods</span><span class="p">))</span>
<span class="k">if</span> <span class="n">headers</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span> <span class="ow">and</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">headers</span><span class="p">,</span> <span class="nb">basestring</span><span class="p">):</span>
<span class="n">headers</span> <span class="o">=</span> <span class="s">&#39;, &#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">x</span><span class="o">.</span><span class="n">upper</span><span class="p">()</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">headers</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">origin</span><span class="p">,</span> <span class="nb">list</span><span class="p">):</span>
<span class="n">origin</span> <span class="o">=</span> <span class="p">[</span><span class="n">origin</span><span class="p">]</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">max_age</span><span class="p">,</span> <span class="n">timedelta</span><span class="p">):</span>
<span class="n">max_age</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">max_age</span><span class="o">.</span><span class="n">total_seconds</span><span class="p">())</span>
<span class="k">def</span> <span class="nf">get_methods</span><span class="p">():</span>
<span class="k">if</span> <span class="n">methods</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span>
<span class="k">return</span> <span class="n">methods</span>
<span class="n">options_resp</span> <span class="o">=</span> <span class="n">current_app</span><span class="o">.</span><span class="n">make_default_options_response</span><span class="p">()</span>
<span class="k">return</span> <span class="n">options_resp</span><span class="o">.</span><span class="n">headers</span><span class="p">[</span><span class="s">&#39;allow&#39;</span><span class="p">]</span>
<span class="k">def</span> <span class="nf">decorator</span><span class="p">(</span><span class="n">f</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">wrapped_function</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="k">if</span> <span class="n">automatic_options</span> <span class="ow">and</span> <span class="n">request</span><span class="o">.</span><span class="n">method</span> <span class="o">==</span> <span class="s">&#39;OPTIONS&#39;</span><span class="p">:</span>
<span class="n">resp</span> <span class="o">=</span> <span class="n">current_app</span><span class="o">.</span><span class="n">make_default_options_response</span><span class="p">()</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">resp</span> <span class="o">=</span> <span class="n">make_response</span><span class="p">(</span><span class="n">f</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">))</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">attach_to_all</span> <span class="ow">and</span> <span class="n">request</span><span class="o">.</span><span class="n">method</span> <span class="o">!=</span> <span class="s">&#39;OPTIONS&#39;</span><span class="p">:</span>
<span class="k">return</span> <span class="n">resp</span>
<span class="n">h</span> <span class="o">=</span> <span class="n">resp</span><span class="o">.</span><span class="n">headers</span>
<span class="n">h</span><span class="o">.</span><span class="n">extend</span><span class="p">([(</span><span class="s">&quot;Access-Control-Allow-Origin&quot;</span><span class="p">,</span> <span class="n">orig</span><span class="p">)</span> <span class="k">for</span> <span class="n">orig</span> <span class="ow">in</span> <span class="n">origin</span><span class="p">])</span>
<span class="n">h</span><span class="p">[</span><span class="s">&#39;Access-Control-Allow-Methods&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">get_methods</span><span class="p">()</span>
<span class="n">h</span><span class="p">[</span><span class="s">&#39;Access-Control-Max-Age&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">max_age</span><span class="p">)</span>
<span class="k">if</span> <span class="n">headers</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span>
<span class="n">h</span><span class="p">[</span><span class="s">&#39;Access-Control-Allow-Headers&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">headers</span>
<span class="k">return</span> <span class="n">resp</span>
<span class="n">f</span><span class="o">.</span><span class="n">provide_automatic_options</span> <span class="o">=</span> <span class="bp">False</span>
<span class="n">f</span><span class="o">.</span><span class="n">required_methods</span> <span class="o">=</span> <span class="p">[</span><span class="s">&#39;OPTIONS&#39;</span><span class="p">]</span>
<span class="k">return</span> <span class="n">update_wrapper</span><span class="p">(</span><span class="n">wrapped_function</span><span class="p">,</span> <span class="n">f</span><span class="p">)</span>
<span class="k">return</span> <span class="n">decorator</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">Lorax 19.7.10 documentation</a> &raquo;</li>
<li><a href="../../index.html" >Module code</a> &raquo;</li>
<li><a href="../api.html" >pylorax.api</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2017, Red Hat, Inc..
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>

View File

@ -0,0 +1,359 @@
<!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>pylorax.api.projects &mdash; Lorax 19.7.10 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: '19.7.10',
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>
<link rel="top" title="Lorax 19.7.10 documentation" href="../../../index.html" />
<link rel="up" title="pylorax.api" href="../api.html" />
</head>
<body>
<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">Lorax 19.7.10 documentation</a> &raquo;</li>
<li><a href="../../index.html" >Module code</a> &raquo;</li>
<li><a href="../api.html" accesskey="U">pylorax.api</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<h1>Source code for pylorax.api.projects</h1><div class="highlight"><pre>
<span class="c">#</span>
<span class="c"># Copyright (C) 2017 Red Hat, Inc.</span>
<span class="c">#</span>
<span class="c"># This program is free software; you can redistribute it and/or modify</span>
<span class="c"># it under the terms of the GNU General Public License as published by</span>
<span class="c"># the Free Software Foundation; either version 2 of the License, or</span>
<span class="c"># (at your option) any later version.</span>
<span class="c">#</span>
<span class="c"># This program is distributed in the hope that it will be useful,</span>
<span class="c"># but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<span class="c"># MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span>
<span class="c"># GNU General Public License for more details.</span>
<span class="c">#</span>
<span class="c"># You should have received a copy of the GNU General Public License</span>
<span class="c"># along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;.</span>
<span class="c">#</span>
<span class="kn">import</span> <span class="nn">logging</span>
<span class="n">log</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s">&quot;lorax-composer&quot;</span><span class="p">)</span>
<span class="kn">import</span> <span class="nn">time</span>
<span class="kn">from</span> <span class="nn">yum.Errors</span> <span class="kn">import</span> <span class="n">YumBaseError</span>
<span class="n">TIME_FORMAT</span> <span class="o">=</span> <span class="s">&quot;%Y-%m-</span><span class="si">%d</span><span class="s">T%H:%M:%S&quot;</span>
<div class="viewcode-block" id="ProjectsError"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.projects.ProjectsError">[docs]</a><span class="k">class</span> <span class="nc">ProjectsError</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
<span class="k">pass</span>
</div>
<div class="viewcode-block" id="api_time"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.projects.api_time">[docs]</a><span class="k">def</span> <span class="nf">api_time</span><span class="p">(</span><span class="n">t</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Convert time since epoch to a string</span>
<span class="sd"> :param t: Seconds since epoch</span>
<span class="sd"> :type t: int</span>
<span class="sd"> :returns: Time string</span>
<span class="sd"> :rtype: str</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">return</span> <span class="n">time</span><span class="o">.</span><span class="n">strftime</span><span class="p">(</span><span class="n">TIME_FORMAT</span><span class="p">,</span> <span class="n">time</span><span class="o">.</span><span class="n">localtime</span><span class="p">(</span><span class="n">t</span><span class="p">))</span>
</div>
<div class="viewcode-block" id="api_changelog"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.projects.api_changelog">[docs]</a><span class="k">def</span> <span class="nf">api_changelog</span><span class="p">(</span><span class="n">changelog</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Convert the changelog to a string</span>
<span class="sd"> :param changelog: A list of time, author, string tuples.</span>
<span class="sd"> :type changelog: tuple</span>
<span class="sd"> :returns: The most recent changelog text or &quot;&quot;</span>
<span class="sd"> :rtype: str</span>
<span class="sd"> This returns only the most recent changelog entry.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">entry</span> <span class="o">=</span> <span class="n">changelog</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">2</span><span class="p">]</span>
<span class="k">except</span> <span class="ne">IndexError</span><span class="p">:</span>
<span class="n">entry</span> <span class="o">=</span> <span class="s">&quot;&quot;</span>
<span class="k">return</span> <span class="n">entry</span>
</div>
<div class="viewcode-block" id="yaps_to_project"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.projects.yaps_to_project">[docs]</a><span class="k">def</span> <span class="nf">yaps_to_project</span><span class="p">(</span><span class="n">yaps</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Extract the details from a YumAvailablePackageSqlite object</span>
<span class="sd"> :param yaps: Yum object with package details</span>
<span class="sd"> :type yaps: YumAvailablePackageSqlite</span>
<span class="sd"> :returns: A dict with the name, summary, description, and url.</span>
<span class="sd"> :rtype: dict</span>
<span class="sd"> upstream_vcs is hard-coded to UPSTREAM_VCS</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">return</span> <span class="p">{</span><span class="s">&quot;name&quot;</span><span class="p">:</span> <span class="n">yaps</span><span class="o">.</span><span class="n">name</span><span class="p">,</span>
<span class="s">&quot;summary&quot;</span><span class="p">:</span> <span class="n">yaps</span><span class="o">.</span><span class="n">summary</span><span class="p">,</span>
<span class="s">&quot;description&quot;</span><span class="p">:</span> <span class="n">yaps</span><span class="o">.</span><span class="n">description</span><span class="p">,</span>
<span class="s">&quot;homepage&quot;</span><span class="p">:</span> <span class="n">yaps</span><span class="o">.</span><span class="n">url</span><span class="p">,</span>
<span class="s">&quot;upstream_vcs&quot;</span><span class="p">:</span> <span class="s">&quot;UPSTREAM_VCS&quot;</span><span class="p">}</span>
</div>
<div class="viewcode-block" id="yaps_to_project_info"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.projects.yaps_to_project_info">[docs]</a><span class="k">def</span> <span class="nf">yaps_to_project_info</span><span class="p">(</span><span class="n">yaps</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Extract the details from a YumAvailablePackageSqlite object</span>
<span class="sd"> :param yaps: Yum object with package details</span>
<span class="sd"> :type yaps: YumAvailablePackageSqlite</span>
<span class="sd"> :returns: A dict with the project details, as well as epoch, release, arch, build_time, changelog, ...</span>
<span class="sd"> :rtype: dict</span>
<span class="sd"> metadata entries are hard-coded to {}</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">build</span> <span class="o">=</span> <span class="p">{</span><span class="s">&quot;epoch&quot;</span><span class="p">:</span> <span class="n">yaps</span><span class="o">.</span><span class="n">epoch</span><span class="p">,</span>
<span class="s">&quot;release&quot;</span><span class="p">:</span> <span class="n">yaps</span><span class="o">.</span><span class="n">release</span><span class="p">,</span>
<span class="s">&quot;arch&quot;</span><span class="p">:</span> <span class="n">yaps</span><span class="o">.</span><span class="n">arch</span><span class="p">,</span>
<span class="s">&quot;build_time&quot;</span><span class="p">:</span> <span class="n">api_time</span><span class="p">(</span><span class="n">yaps</span><span class="o">.</span><span class="n">buildtime</span><span class="p">),</span>
<span class="s">&quot;changelog&quot;</span><span class="p">:</span> <span class="n">api_changelog</span><span class="p">(</span><span class="n">yaps</span><span class="o">.</span><span class="n">returnChangelog</span><span class="p">()),</span>
<span class="s">&quot;build_config_ref&quot;</span><span class="p">:</span> <span class="s">&quot;BUILD_CONFIG_REF&quot;</span><span class="p">,</span>
<span class="s">&quot;build_env_ref&quot;</span><span class="p">:</span> <span class="s">&quot;BUILD_ENV_REF&quot;</span><span class="p">,</span>
<span class="s">&quot;metadata&quot;</span><span class="p">:</span> <span class="p">{},</span>
<span class="s">&quot;source&quot;</span><span class="p">:</span> <span class="p">{</span><span class="s">&quot;license&quot;</span><span class="p">:</span> <span class="n">yaps</span><span class="o">.</span><span class="n">license</span><span class="p">,</span>
<span class="s">&quot;version&quot;</span><span class="p">:</span> <span class="n">yaps</span><span class="o">.</span><span class="n">version</span><span class="p">,</span>
<span class="s">&quot;source_ref&quot;</span><span class="p">:</span> <span class="s">&quot;SOURCE_REF&quot;</span><span class="p">,</span>
<span class="s">&quot;metadata&quot;</span><span class="p">:</span> <span class="p">{}}}</span>
<span class="k">return</span> <span class="p">{</span><span class="s">&quot;name&quot;</span><span class="p">:</span> <span class="n">yaps</span><span class="o">.</span><span class="n">name</span><span class="p">,</span>
<span class="s">&quot;summary&quot;</span><span class="p">:</span> <span class="n">yaps</span><span class="o">.</span><span class="n">summary</span><span class="p">,</span>
<span class="s">&quot;description&quot;</span><span class="p">:</span> <span class="n">yaps</span><span class="o">.</span><span class="n">description</span><span class="p">,</span>
<span class="s">&quot;homepage&quot;</span><span class="p">:</span> <span class="n">yaps</span><span class="o">.</span><span class="n">url</span><span class="p">,</span>
<span class="s">&quot;upstream_vcs&quot;</span><span class="p">:</span> <span class="s">&quot;UPSTREAM_VCS&quot;</span><span class="p">,</span>
<span class="s">&quot;builds&quot;</span><span class="p">:</span> <span class="p">[</span><span class="n">build</span><span class="p">]}</span>
</div>
<div class="viewcode-block" id="tm_to_dep"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.projects.tm_to_dep">[docs]</a><span class="k">def</span> <span class="nf">tm_to_dep</span><span class="p">(</span><span class="n">tm</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Extract the info from a TransactionMember object</span>
<span class="sd"> :param tm: A Yum transaction object</span>
<span class="sd"> :type tm: TransactionMember</span>
<span class="sd"> :returns: A dict with name, epoch, version, release, arch</span>
<span class="sd"> :rtype: dict</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">return</span> <span class="p">{</span><span class="s">&quot;name&quot;</span><span class="p">:</span> <span class="n">tm</span><span class="o">.</span><span class="n">name</span><span class="p">,</span>
<span class="s">&quot;epoch&quot;</span><span class="p">:</span> <span class="n">tm</span><span class="o">.</span><span class="n">epoch</span><span class="p">,</span>
<span class="s">&quot;version&quot;</span><span class="p">:</span> <span class="n">tm</span><span class="o">.</span><span class="n">version</span><span class="p">,</span>
<span class="s">&quot;release&quot;</span><span class="p">:</span> <span class="n">tm</span><span class="o">.</span><span class="n">release</span><span class="p">,</span>
<span class="s">&quot;arch&quot;</span><span class="p">:</span> <span class="n">tm</span><span class="o">.</span><span class="n">arch</span><span class="p">}</span>
</div>
<div class="viewcode-block" id="yaps_to_module"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.projects.yaps_to_module">[docs]</a><span class="k">def</span> <span class="nf">yaps_to_module</span><span class="p">(</span><span class="n">yaps</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Extract the name from a YumAvailablePackageSqlite object</span>
<span class="sd"> :param yaps: Yum object with package details</span>
<span class="sd"> :type yaps: YumAvailablePackageSqlite</span>
<span class="sd"> :returns: A dict with name, and group_type</span>
<span class="sd"> :rtype: dict</span>
<span class="sd"> group_type is hard-coded to &quot;rpm&quot;</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">return</span> <span class="p">{</span><span class="s">&quot;name&quot;</span><span class="p">:</span> <span class="n">yaps</span><span class="o">.</span><span class="n">name</span><span class="p">,</span>
<span class="s">&quot;group_type&quot;</span><span class="p">:</span> <span class="s">&quot;rpm&quot;</span><span class="p">}</span>
</div>
<div class="viewcode-block" id="dep_evra"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.projects.dep_evra">[docs]</a><span class="k">def</span> <span class="nf">dep_evra</span><span class="p">(</span><span class="n">dep</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return the epoch:version-release.arch for the dep</span>
<span class="sd"> :param dep: dependency dict</span>
<span class="sd"> :type dep: dict</span>
<span class="sd"> :returns: epoch:version-release.arch</span>
<span class="sd"> :rtype: str</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">dep</span><span class="p">[</span><span class="s">&quot;epoch&quot;</span><span class="p">]</span> <span class="o">==</span> <span class="s">&quot;0&quot;</span><span class="p">:</span>
<span class="k">return</span> <span class="n">dep</span><span class="p">[</span><span class="s">&quot;version&quot;</span><span class="p">]</span><span class="o">+</span><span class="s">&quot;-&quot;</span><span class="o">+</span><span class="n">dep</span><span class="p">[</span><span class="s">&quot;release&quot;</span><span class="p">]</span><span class="o">+</span><span class="s">&quot;.&quot;</span><span class="o">+</span><span class="n">dep</span><span class="p">[</span><span class="s">&quot;arch&quot;</span><span class="p">]</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="n">dep</span><span class="p">[</span><span class="s">&quot;epoch&quot;</span><span class="p">]</span><span class="o">+</span><span class="s">&quot;:&quot;</span><span class="o">+</span><span class="n">dep</span><span class="p">[</span><span class="s">&quot;version&quot;</span><span class="p">]</span><span class="o">+</span><span class="s">&quot;-&quot;</span><span class="o">+</span><span class="n">dep</span><span class="p">[</span><span class="s">&quot;release&quot;</span><span class="p">]</span><span class="o">+</span><span class="s">&quot;.&quot;</span><span class="o">+</span><span class="n">dep</span><span class="p">[</span><span class="s">&quot;arch&quot;</span><span class="p">]</span>
</div>
<div class="viewcode-block" id="dep_nevra"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.projects.dep_nevra">[docs]</a><span class="k">def</span> <span class="nf">dep_nevra</span><span class="p">(</span><span class="n">dep</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return the name-epoch:version-release.arch&quot;&quot;&quot;</span>
<span class="k">return</span> <span class="n">dep</span><span class="p">[</span><span class="s">&quot;name&quot;</span><span class="p">]</span><span class="o">+</span><span class="s">&quot;-&quot;</span><span class="o">+</span><span class="n">dep_evra</span><span class="p">(</span><span class="n">dep</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="projects_list"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.projects.projects_list">[docs]</a><span class="k">def</span> <span class="nf">projects_list</span><span class="p">(</span><span class="n">yb</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return a list of projects</span>
<span class="sd"> :param yb: yum base object</span>
<span class="sd"> :type yb: YumBase</span>
<span class="sd"> :returns: List of project info dicts with name, summary, description, homepage, upstream_vcs</span>
<span class="sd"> :rtype: list of dicts</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">ybl</span> <span class="o">=</span> <span class="n">yb</span><span class="o">.</span><span class="n">doPackageLists</span><span class="p">(</span><span class="n">pkgnarrow</span><span class="o">=</span><span class="s">&quot;available&quot;</span><span class="p">,</span> <span class="n">showdups</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>
<span class="k">except</span> <span class="n">YumBaseError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">ProjectsError</span><span class="p">(</span><span class="s">&quot;There was a problem listing projects: </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">))</span>
<span class="k">finally</span><span class="p">:</span>
<span class="n">yb</span><span class="o">.</span><span class="n">closeRpmDB</span><span class="p">()</span>
<span class="k">return</span> <span class="nb">sorted</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="n">yaps_to_project</span><span class="p">,</span> <span class="n">ybl</span><span class="o">.</span><span class="n">available</span><span class="p">),</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">p</span><span class="p">:</span> <span class="n">p</span><span class="p">[</span><span class="s">&quot;name&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">lower</span><span class="p">())</span>
</div>
<div class="viewcode-block" id="projects_info"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.projects.projects_info">[docs]</a><span class="k">def</span> <span class="nf">projects_info</span><span class="p">(</span><span class="n">yb</span><span class="p">,</span> <span class="n">project_names</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return details about specific projects</span>
<span class="sd"> :param yb: yum base object</span>
<span class="sd"> :type yb: YumBase</span>
<span class="sd"> :param project_names: List of names of projects to get info about</span>
<span class="sd"> :type project_names: str</span>
<span class="sd"> :returns: List of project info dicts with yaps_to_project as well as epoch, version, release, etc.</span>
<span class="sd"> :rtype: list of dicts</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">ybl</span> <span class="o">=</span> <span class="n">yb</span><span class="o">.</span><span class="n">doPackageLists</span><span class="p">(</span><span class="n">pkgnarrow</span><span class="o">=</span><span class="s">&quot;available&quot;</span><span class="p">,</span> <span class="n">patterns</span><span class="o">=</span><span class="n">project_names</span><span class="p">,</span> <span class="n">showdups</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>
<span class="k">except</span> <span class="n">YumBaseError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">ProjectsError</span><span class="p">(</span><span class="s">&quot;There was a problem with info for </span><span class="si">%s</span><span class="s">: </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">project_names</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">)))</span>
<span class="k">finally</span><span class="p">:</span>
<span class="n">yb</span><span class="o">.</span><span class="n">closeRpmDB</span><span class="p">()</span>
<span class="k">return</span> <span class="nb">sorted</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="n">yaps_to_project_info</span><span class="p">,</span> <span class="n">ybl</span><span class="o">.</span><span class="n">available</span><span class="p">),</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">p</span><span class="p">:</span> <span class="n">p</span><span class="p">[</span><span class="s">&quot;name&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">lower</span><span class="p">())</span>
</div>
<div class="viewcode-block" id="projects_depsolve"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.projects.projects_depsolve">[docs]</a><span class="k">def</span> <span class="nf">projects_depsolve</span><span class="p">(</span><span class="n">yb</span><span class="p">,</span> <span class="n">project_names</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return the dependencies for a list of projects</span>
<span class="sd"> :param yb: yum base object</span>
<span class="sd"> :type yb: YumBase</span>
<span class="sd"> :param project_names: The projects to find the dependencies for</span>
<span class="sd"> :type project_names: List of Strings</span>
<span class="sd"> :returns: NEVRA&#39;s of the project and its dependencies</span>
<span class="sd"> :rtype: list of dicts</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">try</span><span class="p">:</span>
<span class="c"># This resets the transaction</span>
<span class="n">yb</span><span class="o">.</span><span class="n">closeRpmDB</span><span class="p">()</span>
<span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">project_names</span><span class="p">:</span>
<span class="n">yb</span><span class="o">.</span><span class="n">install</span><span class="p">(</span><span class="n">pattern</span><span class="o">=</span><span class="n">p</span><span class="p">)</span>
<span class="p">(</span><span class="n">rc</span><span class="p">,</span> <span class="n">msg</span><span class="p">)</span> <span class="o">=</span> <span class="n">yb</span><span class="o">.</span><span class="n">buildTransaction</span><span class="p">()</span>
<span class="k">if</span> <span class="n">rc</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">]:</span>
<span class="k">raise</span> <span class="n">ProjectsError</span><span class="p">(</span><span class="s">&quot;There was a problem depsolving </span><span class="si">%s</span><span class="s">: </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">project_names</span><span class="p">,</span> <span class="n">msg</span><span class="p">))</span>
<span class="n">yb</span><span class="o">.</span><span class="n">tsInfo</span><span class="o">.</span><span class="n">makelists</span><span class="p">()</span>
<span class="n">deps</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="n">tm_to_dep</span><span class="p">,</span> <span class="n">yb</span><span class="o">.</span><span class="n">tsInfo</span><span class="o">.</span><span class="n">installed</span> <span class="o">+</span> <span class="n">yb</span><span class="o">.</span><span class="n">tsInfo</span><span class="o">.</span><span class="n">depinstalled</span><span class="p">),</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">p</span><span class="p">:</span> <span class="n">p</span><span class="p">[</span><span class="s">&quot;name&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">lower</span><span class="p">())</span>
<span class="k">except</span> <span class="n">YumBaseError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">ProjectsError</span><span class="p">(</span><span class="s">&quot;There was a problem depsolving </span><span class="si">%s</span><span class="s">: </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">project_names</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">)))</span>
<span class="k">finally</span><span class="p">:</span>
<span class="n">yb</span><span class="o">.</span><span class="n">closeRpmDB</span><span class="p">()</span>
<span class="k">return</span> <span class="n">deps</span>
</div>
<div class="viewcode-block" id="modules_list"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.projects.modules_list">[docs]</a><span class="k">def</span> <span class="nf">modules_list</span><span class="p">(</span><span class="n">yb</span><span class="p">,</span> <span class="n">module_names</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return a list of modules</span>
<span class="sd"> :param yb: yum base object</span>
<span class="sd"> :type yb: YumBase</span>
<span class="sd"> :param offset: Number of modules to skip</span>
<span class="sd"> :type limit: int</span>
<span class="sd"> :param limit: Maximum number of modules to return</span>
<span class="sd"> :type limit: int</span>
<span class="sd"> :returns: List of module information and total count</span>
<span class="sd"> :rtype: tuple of a list of dicts and an Int</span>
<span class="sd"> Modules don&#39;t exist in RHEL7 so this only returns projects</span>
<span class="sd"> and sets the type to &quot;rpm&quot;</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">ybl</span> <span class="o">=</span> <span class="n">yb</span><span class="o">.</span><span class="n">doPackageLists</span><span class="p">(</span><span class="n">pkgnarrow</span><span class="o">=</span><span class="s">&quot;available&quot;</span><span class="p">,</span> <span class="n">patterns</span><span class="o">=</span><span class="n">module_names</span><span class="p">,</span> <span class="n">showdups</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>
<span class="k">except</span> <span class="n">YumBaseError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">ProjectsError</span><span class="p">(</span><span class="s">&quot;There was a problem listing modules: </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">))</span>
<span class="k">finally</span><span class="p">:</span>
<span class="n">yb</span><span class="o">.</span><span class="n">closeRpmDB</span><span class="p">()</span>
<span class="k">return</span> <span class="nb">sorted</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="n">yaps_to_module</span><span class="p">,</span> <span class="n">ybl</span><span class="o">.</span><span class="n">available</span><span class="p">),</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">p</span><span class="p">:</span> <span class="n">p</span><span class="p">[</span><span class="s">&quot;name&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">lower</span><span class="p">())</span>
</div>
<div class="viewcode-block" id="modules_info"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.projects.modules_info">[docs]</a><span class="k">def</span> <span class="nf">modules_info</span><span class="p">(</span><span class="n">yb</span><span class="p">,</span> <span class="n">module_names</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return details about a module, including dependencies</span>
<span class="sd"> :param yb: yum base object</span>
<span class="sd"> :type yb: YumBase</span>
<span class="sd"> :param module_names: Names of the modules to get info about</span>
<span class="sd"> :type module_names: str</span>
<span class="sd"> :returns: List of dicts with module details and dependencies.</span>
<span class="sd"> :rtype: list of dicts</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">try</span><span class="p">:</span>
<span class="c"># Get the info about each module</span>
<span class="n">ybl</span> <span class="o">=</span> <span class="n">yb</span><span class="o">.</span><span class="n">doPackageLists</span><span class="p">(</span><span class="n">pkgnarrow</span><span class="o">=</span><span class="s">&quot;available&quot;</span><span class="p">,</span> <span class="n">patterns</span><span class="o">=</span><span class="n">module_names</span><span class="p">,</span> <span class="n">showdups</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>
<span class="k">except</span> <span class="n">YumBaseError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">ProjectsError</span><span class="p">(</span><span class="s">&quot;There was a problem with info for </span><span class="si">%s</span><span class="s">: </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">module_names</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">)))</span>
<span class="k">finally</span><span class="p">:</span>
<span class="n">yb</span><span class="o">.</span><span class="n">closeRpmDB</span><span class="p">()</span>
<span class="n">modules</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="n">yaps_to_project</span><span class="p">,</span> <span class="n">ybl</span><span class="o">.</span><span class="n">available</span><span class="p">),</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">p</span><span class="p">:</span> <span class="n">p</span><span class="p">[</span><span class="s">&quot;name&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">lower</span><span class="p">())</span>
<span class="c"># Add the dependency info to each one</span>
<span class="k">for</span> <span class="n">module</span> <span class="ow">in</span> <span class="n">modules</span><span class="p">:</span>
<span class="n">module</span><span class="p">[</span><span class="s">&quot;dependencies&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">projects_depsolve</span><span class="p">(</span><span class="n">yb</span><span class="p">,</span> <span class="p">[</span><span class="n">module</span><span class="p">[</span><span class="s">&quot;name&quot;</span><span class="p">]])</span>
<span class="k">return</span> <span class="n">modules</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">Lorax 19.7.10 documentation</a> &raquo;</li>
<li><a href="../../index.html" >Module code</a> &raquo;</li>
<li><a href="../api.html" >pylorax.api</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2017, Red Hat, Inc..
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>

View File

@ -0,0 +1,659 @@
<!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>pylorax.api.queue &mdash; Lorax 19.7.10 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: '19.7.10',
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>
<link rel="top" title="Lorax 19.7.10 documentation" href="../../../index.html" />
<link rel="up" title="pylorax.api" href="../api.html" />
</head>
<body>
<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">Lorax 19.7.10 documentation</a> &raquo;</li>
<li><a href="../../index.html" >Module code</a> &raquo;</li>
<li><a href="../api.html" accesskey="U">pylorax.api</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<h1>Source code for pylorax.api.queue</h1><div class="highlight"><pre>
<span class="c"># Copyright (C) 2018 Red Hat, Inc.</span>
<span class="c">#</span>
<span class="c"># This program is free software; you can redistribute it and/or modify</span>
<span class="c"># it under the terms of the GNU General Public License as published by</span>
<span class="c"># the Free Software Foundation; either version 2 of the License, or</span>
<span class="c"># (at your option) any later version.</span>
<span class="c">#</span>
<span class="c"># This program is distributed in the hope that it will be useful,</span>
<span class="c"># but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<span class="c"># MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span>
<span class="c"># GNU General Public License for more details.</span>
<span class="c">#</span>
<span class="c"># You should have received a copy of the GNU General Public License</span>
<span class="c"># along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;.</span>
<span class="c">#</span>
<span class="sd">&quot;&quot;&quot; Functions to monitor compose queue and run anaconda&quot;&quot;&quot;</span>
<span class="kn">import</span> <span class="nn">logging</span>
<span class="n">log</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s">&quot;pylorax&quot;</span><span class="p">)</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">grp</span>
<span class="kn">from</span> <span class="nn">glob</span> <span class="kn">import</span> <span class="n">glob</span>
<span class="kn">import</span> <span class="nn">multiprocessing</span> <span class="kn">as</span> <span class="nn">mp</span>
<span class="kn">import</span> <span class="nn">pytoml</span> <span class="kn">as</span> <span class="nn">toml</span>
<span class="kn">import</span> <span class="nn">pwd</span>
<span class="kn">import</span> <span class="nn">shutil</span>
<span class="kn">import</span> <span class="nn">subprocess</span>
<span class="kn">from</span> <span class="nn">subprocess</span> <span class="kn">import</span> <span class="n">Popen</span><span class="p">,</span> <span class="n">PIPE</span>
<span class="kn">import</span> <span class="nn">time</span>
<span class="kn">from</span> <span class="nn">pylorax.api.compose</span> <span class="kn">import</span> <span class="n">move_compose_results</span>
<span class="kn">from</span> <span class="nn">pylorax.api.recipes</span> <span class="kn">import</span> <span class="n">recipe_from_file</span>
<span class="kn">from</span> <span class="nn">pylorax.base</span> <span class="kn">import</span> <span class="n">DataHolder</span>
<span class="kn">from</span> <span class="nn">pylorax.creator</span> <span class="kn">import</span> <span class="n">run_creator</span>
<span class="kn">from</span> <span class="nn">pylorax.sysutils</span> <span class="kn">import</span> <span class="n">joinpaths</span>
<div class="viewcode-block" id="start_queue_monitor"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.queue.start_queue_monitor">[docs]</a><span class="k">def</span> <span class="nf">start_queue_monitor</span><span class="p">(</span><span class="n">cfg</span><span class="p">,</span> <span class="n">uid</span><span class="p">,</span> <span class="n">gid</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Start the queue monitor as a mp process</span>
<span class="sd"> :param cfg: Configuration settings</span>
<span class="sd"> :type cfg: ComposerConfig</span>
<span class="sd"> :param uid: User ID that owns the queue</span>
<span class="sd"> :type uid: int</span>
<span class="sd"> :param gid: Group ID that owns the queue</span>
<span class="sd"> :type gid: int</span>
<span class="sd"> :returns: None</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">lib_dir</span> <span class="o">=</span> <span class="n">cfg</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">&quot;composer&quot;</span><span class="p">,</span> <span class="s">&quot;lib_dir&quot;</span><span class="p">)</span>
<span class="n">share_dir</span> <span class="o">=</span> <span class="n">cfg</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">&quot;composer&quot;</span><span class="p">,</span> <span class="s">&quot;share_dir&quot;</span><span class="p">)</span>
<span class="n">monitor_cfg</span> <span class="o">=</span> <span class="n">DataHolder</span><span class="p">(</span><span class="n">composer_dir</span><span class="o">=</span><span class="n">lib_dir</span><span class="p">,</span> <span class="n">share_dir</span><span class="o">=</span><span class="n">share_dir</span><span class="p">,</span> <span class="n">uid</span><span class="o">=</span><span class="n">uid</span><span class="p">,</span> <span class="n">gid</span><span class="o">=</span><span class="n">gid</span><span class="p">)</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">mp</span><span class="o">.</span><span class="n">Process</span><span class="p">(</span><span class="n">target</span><span class="o">=</span><span class="n">monitor</span><span class="p">,</span> <span class="n">args</span><span class="o">=</span><span class="p">(</span><span class="n">monitor_cfg</span><span class="p">,))</span>
<span class="n">p</span><span class="o">.</span><span class="n">daemon</span> <span class="o">=</span> <span class="bp">True</span>
<span class="n">p</span><span class="o">.</span><span class="n">start</span><span class="p">()</span>
</div>
<div class="viewcode-block" id="monitor"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.queue.monitor">[docs]</a><span class="k">def</span> <span class="nf">monitor</span><span class="p">(</span><span class="n">cfg</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Monitor the queue for new compose requests</span>
<span class="sd"> :param cfg: Configuration settings</span>
<span class="sd"> :type cfg: DataHolder</span>
<span class="sd"> :returns: Does not return</span>
<span class="sd"> The queue has 2 subdirectories, new and run. When a compose is ready to be run</span>
<span class="sd"> a symlink to the uniquely named results directory should be placed in ./queue/new/</span>
<span class="sd"> When the it is ready to be run (it is checked every 30 seconds or after a previous</span>
<span class="sd"> compose is finished) the symlink will be moved into ./queue/run/ and a STATUS file</span>
<span class="sd"> will be created in the results directory.</span>
<span class="sd"> STATUS can contain one of: RUNNING, FINISHED, FAILED</span>
<span class="sd"> If the system is restarted while a compose is running it will move any old symlinks</span>
<span class="sd"> from ./queue/run/ to ./queue/new/ and rerun them.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">def</span> <span class="nf">queue_sort</span><span class="p">(</span><span class="n">uuid</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Sort the queue entries by their mtime, not their names&quot;&quot;&quot;</span>
<span class="k">return</span> <span class="n">os</span><span class="o">.</span><span class="n">stat</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">cfg</span><span class="o">.</span><span class="n">composer_dir</span><span class="p">,</span> <span class="s">&quot;queue/new&quot;</span><span class="p">,</span> <span class="n">uuid</span><span class="p">))</span><span class="o">.</span><span class="n">st_mtime</span>
<span class="c"># Move any symlinks in the run queue back to the new queue</span>
<span class="k">for</span> <span class="n">link</span> <span class="ow">in</span> <span class="n">os</span><span class="o">.</span><span class="n">listdir</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">cfg</span><span class="o">.</span><span class="n">composer_dir</span><span class="p">,</span> <span class="s">&quot;queue/run&quot;</span><span class="p">)):</span>
<span class="n">src</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">cfg</span><span class="o">.</span><span class="n">composer_dir</span><span class="p">,</span> <span class="s">&quot;queue/run&quot;</span><span class="p">,</span> <span class="n">link</span><span class="p">)</span>
<span class="n">dst</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">cfg</span><span class="o">.</span><span class="n">composer_dir</span><span class="p">,</span> <span class="s">&quot;queue/new&quot;</span><span class="p">,</span> <span class="n">link</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">rename</span><span class="p">(</span><span class="n">src</span><span class="p">,</span> <span class="n">dst</span><span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">&quot;Moved unfinished compose </span><span class="si">%s</span><span class="s"> back to new state&quot;</span><span class="p">,</span> <span class="n">src</span><span class="p">)</span>
<span class="k">while</span> <span class="bp">True</span><span class="p">:</span>
<span class="n">uuids</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">listdir</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">cfg</span><span class="o">.</span><span class="n">composer_dir</span><span class="p">,</span> <span class="s">&quot;queue/new&quot;</span><span class="p">)),</span> <span class="n">key</span><span class="o">=</span><span class="n">queue_sort</span><span class="p">)</span>
<span class="c"># Pick the oldest and move it into ./run/</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">uuids</span><span class="p">:</span>
<span class="c"># No composes left to process, sleep for a bit</span>
<span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mi">30</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">src</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">cfg</span><span class="o">.</span><span class="n">composer_dir</span><span class="p">,</span> <span class="s">&quot;queue/new&quot;</span><span class="p">,</span> <span class="n">uuids</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
<span class="n">dst</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">cfg</span><span class="o">.</span><span class="n">composer_dir</span><span class="p">,</span> <span class="s">&quot;queue/run&quot;</span><span class="p">,</span> <span class="n">uuids</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">os</span><span class="o">.</span><span class="n">rename</span><span class="p">(</span><span class="n">src</span><span class="p">,</span> <span class="n">dst</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">OSError</span><span class="p">:</span>
<span class="c"># The symlink may vanish if uuid_cancel() has been called</span>
<span class="k">continue</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;Starting new compose: </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">dst</span><span class="p">)</span>
<span class="nb">open</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">dst</span><span class="p">,</span> <span class="s">&quot;STATUS&quot;</span><span class="p">),</span> <span class="s">&quot;w&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">&quot;RUNNING</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">make_compose</span><span class="p">(</span><span class="n">cfg</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">realpath</span><span class="p">(</span><span class="n">dst</span><span class="p">))</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;Finished building </span><span class="si">%s</span><span class="s">, results are in </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">dst</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">realpath</span><span class="p">(</span><span class="n">dst</span><span class="p">))</span>
<span class="nb">open</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">dst</span><span class="p">,</span> <span class="s">&quot;STATUS&quot;</span><span class="p">),</span> <span class="s">&quot;w&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">&quot;FINISHED</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="kn">import</span> <span class="nn">traceback</span>
<span class="n">log</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s">&quot;traceback: </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">traceback</span><span class="o">.</span><span class="n">format_exc</span><span class="p">())</span>
<span class="c"># TODO - Write the error message to an ERROR-LOG file to include with the status</span>
<span class="c"># log.error(&quot;Error running compose: %s&quot;, e)</span>
<span class="nb">open</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">dst</span><span class="p">,</span> <span class="s">&quot;STATUS&quot;</span><span class="p">),</span> <span class="s">&quot;w&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">&quot;FAILED</span><span class="se">\n</span><span class="s">&quot;</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">dst</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="make_compose"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.queue.make_compose">[docs]</a><span class="k">def</span> <span class="nf">make_compose</span><span class="p">(</span><span class="n">cfg</span><span class="p">,</span> <span class="n">results_dir</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Run anaconda with the final-kickstart.ks from results_dir</span>
<span class="sd"> :param cfg: Configuration settings</span>
<span class="sd"> :type cfg: DataHolder</span>
<span class="sd"> :param results_dir: The directory containing the metadata and results for the build</span>
<span class="sd"> :type results_dir: str</span>
<span class="sd"> :returns: Nothing</span>
<span class="sd"> :raises: May raise various exceptions</span>
<span class="sd"> This takes the final-kickstart.ks, and the settings in config.toml and runs Anaconda</span>
<span class="sd"> in no-virt mode (directly on the host operating system). Exceptions should be caught</span>
<span class="sd"> at the higer level.</span>
<span class="sd"> If there is a failure, the build artifacts will be cleaned up, and any logs will be</span>
<span class="sd"> moved into logs/anaconda/ and their ownership will be set to the user from the cfg</span>
<span class="sd"> object.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c"># Check on the ks&#39;s presence</span>
<span class="n">ks_path</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">results_dir</span><span class="p">,</span> <span class="s">&quot;final-kickstart.ks&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">ks_path</span><span class="p">):</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s">&quot;Missing kickstart file at </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">ks_path</span><span class="p">)</span>
<span class="c"># The anaconda logs are copied into ./anaconda/ in this directory</span>
<span class="n">log_dir</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">results_dir</span><span class="p">,</span> <span class="s">&quot;logs/&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">log_dir</span><span class="p">):</span>
<span class="n">os</span><span class="o">.</span><span class="n">makedirs</span><span class="p">(</span><span class="n">log_dir</span><span class="p">)</span>
<span class="c"># Load the compose configuration</span>
<span class="n">cfg_path</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">results_dir</span><span class="p">,</span> <span class="s">&quot;config.toml&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">cfg_path</span><span class="p">):</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s">&quot;Missing config.toml for </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">results_dir</span><span class="p">)</span>
<span class="n">cfg_dict</span> <span class="o">=</span> <span class="n">toml</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="nb">open</span><span class="p">(</span><span class="n">cfg_path</span><span class="p">,</span> <span class="s">&quot;r&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">read</span><span class="p">())</span>
<span class="c"># The keys in cfg_dict correspond to the arguments setup in livemedia-creator</span>
<span class="c"># keys that define what to build should be setup in compose_args, and keys with</span>
<span class="c"># defaults should be setup here.</span>
<span class="c"># Make sure that image_name contains no path components</span>
<span class="n">cfg_dict</span><span class="p">[</span><span class="s">&quot;image_name&quot;</span><span class="p">]</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">basename</span><span class="p">(</span><span class="n">cfg_dict</span><span class="p">[</span><span class="s">&quot;image_name&quot;</span><span class="p">])</span>
<span class="c"># Only support novirt installation, set some other defaults</span>
<span class="n">cfg_dict</span><span class="p">[</span><span class="s">&quot;no_virt&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="bp">True</span>
<span class="n">cfg_dict</span><span class="p">[</span><span class="s">&quot;disk_image&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="bp">None</span>
<span class="n">cfg_dict</span><span class="p">[</span><span class="s">&quot;fs_image&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="bp">None</span>
<span class="n">cfg_dict</span><span class="p">[</span><span class="s">&quot;keep_image&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="bp">False</span>
<span class="n">cfg_dict</span><span class="p">[</span><span class="s">&quot;domacboot&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="bp">False</span>
<span class="n">cfg_dict</span><span class="p">[</span><span class="s">&quot;anaconda_args&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="s">&quot;&quot;</span>
<span class="n">cfg_dict</span><span class="p">[</span><span class="s">&quot;proxy&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="s">&quot;&quot;</span>
<span class="n">cfg_dict</span><span class="p">[</span><span class="s">&quot;armplatform&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="s">&quot;&quot;</span>
<span class="n">cfg_dict</span><span class="p">[</span><span class="s">&quot;squashfs_args&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="bp">None</span>
<span class="n">cfg_dict</span><span class="p">[</span><span class="s">&quot;lorax_templates&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">cfg</span><span class="o">.</span><span class="n">share_dir</span>
<span class="n">cfg_dict</span><span class="p">[</span><span class="s">&quot;tmp&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="s">&quot;/var/tmp/&quot;</span>
<span class="n">cfg_dict</span><span class="p">[</span><span class="s">&quot;dracut_args&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="bp">None</span> <span class="c"># Use default args for dracut</span>
<span class="c"># Compose things in a temporary directory inside the results directory</span>
<span class="n">cfg_dict</span><span class="p">[</span><span class="s">&quot;result_dir&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">results_dir</span><span class="p">,</span> <span class="s">&quot;compose&quot;</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">makedirs</span><span class="p">(</span><span class="n">cfg_dict</span><span class="p">[</span><span class="s">&quot;result_dir&quot;</span><span class="p">])</span>
<span class="n">install_cfg</span> <span class="o">=</span> <span class="n">DataHolder</span><span class="p">(</span><span class="o">**</span><span class="n">cfg_dict</span><span class="p">)</span>
<span class="c"># Some kludges for the 99-copy-logs %post, failure in it will crash the build</span>
<span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="p">[</span><span class="s">&quot;/tmp/NOSAVE_INPUT_KS&quot;</span><span class="p">,</span> <span class="s">&quot;/tmp/NOSAVE_LOGS&quot;</span><span class="p">]:</span>
<span class="nb">open</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="s">&quot;w&quot;</span><span class="p">)</span>
<span class="c"># Placing a CANCEL file in the results directory will make execWithRedirect send anaconda a SIGTERM</span>
<span class="k">def</span> <span class="nf">cancel_build</span><span class="p">():</span>
<span class="k">return</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">joinpaths</span><span class="p">(</span><span class="n">results_dir</span><span class="p">,</span> <span class="s">&quot;CANCEL&quot;</span><span class="p">))</span>
<span class="n">log</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">&quot;cfg = </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">install_cfg</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">test_path</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">results_dir</span><span class="p">,</span> <span class="s">&quot;TEST&quot;</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">exists</span><span class="p">(</span><span class="n">test_path</span><span class="p">):</span>
<span class="c"># Pretend to run the compose</span>
<span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">test_mode</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="nb">open</span><span class="p">(</span><span class="n">test_path</span><span class="p">,</span> <span class="s">&quot;r&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">read</span><span class="p">())</span>
<span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
<span class="n">test_mode</span> <span class="o">=</span> <span class="mi">1</span>
<span class="k">if</span> <span class="n">test_mode</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s">&quot;TESTING FAILED compose&quot;</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="nb">open</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">results_dir</span><span class="p">,</span> <span class="n">install_cfg</span><span class="o">.</span><span class="n">image_name</span><span class="p">),</span> <span class="s">&quot;w&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">&quot;TEST IMAGE&quot;</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">run_creator</span><span class="p">(</span><span class="n">install_cfg</span><span class="p">,</span> <span class="n">callback_func</span><span class="o">=</span><span class="n">cancel_build</span><span class="p">)</span>
<span class="c"># Extract the results of the compose into results_dir and cleanup the compose directory</span>
<span class="n">move_compose_results</span><span class="p">(</span><span class="n">install_cfg</span><span class="p">,</span> <span class="n">results_dir</span><span class="p">)</span>
<span class="k">finally</span><span class="p">:</span>
<span class="c"># Make sure that everything under the results directory is owned by the user</span>
<span class="n">user</span> <span class="o">=</span> <span class="n">pwd</span><span class="o">.</span><span class="n">getpwuid</span><span class="p">(</span><span class="n">cfg</span><span class="o">.</span><span class="n">uid</span><span class="p">)</span><span class="o">.</span><span class="n">pw_name</span>
<span class="n">group</span> <span class="o">=</span> <span class="n">grp</span><span class="o">.</span><span class="n">getgrgid</span><span class="p">(</span><span class="n">cfg</span><span class="o">.</span><span class="n">gid</span><span class="p">)</span><span class="o">.</span><span class="n">gr_name</span>
<span class="n">log</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">&quot;Install finished, chowning results to </span><span class="si">%s</span><span class="s">:</span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">user</span><span class="p">,</span> <span class="n">group</span><span class="p">)</span>
<span class="n">subprocess</span><span class="o">.</span><span class="n">call</span><span class="p">([</span><span class="s">&quot;chown&quot;</span><span class="p">,</span> <span class="s">&quot;-R&quot;</span><span class="p">,</span> <span class="s">&quot;</span><span class="si">%s</span><span class="s">:</span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">user</span><span class="p">,</span> <span class="n">group</span><span class="p">),</span> <span class="n">results_dir</span><span class="p">])</span>
</div>
<div class="viewcode-block" id="get_compose_type"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.queue.get_compose_type">[docs]</a><span class="k">def</span> <span class="nf">get_compose_type</span><span class="p">(</span><span class="n">results_dir</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return the type of composition.</span>
<span class="sd"> :param results_dir: The directory containing the metadata and results for the build</span>
<span class="sd"> :type results_dir: str</span>
<span class="sd"> :returns: The type of compose (eg. &#39;tar&#39;)</span>
<span class="sd"> :rtype: str</span>
<span class="sd"> :raises: RuntimeError if no kickstart template can be found.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c"># Should only be 2 kickstarts, the final-kickstart.ks and the template</span>
<span class="n">t</span> <span class="o">=</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">ks</span><span class="p">)[:</span><span class="o">-</span><span class="mi">3</span><span class="p">]</span> <span class="k">for</span> <span class="n">ks</span> <span class="ow">in</span> <span class="n">glob</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">results_dir</span><span class="p">,</span> <span class="s">&quot;*.ks&quot;</span><span class="p">))</span>
<span class="k">if</span> <span class="s">&quot;final-kickstart&quot;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">ks</span><span class="p">]</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">t</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">1</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s">&quot;Cannot find ks template for build </span><span class="si">%s</span><span class="s">&quot;</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">basename</span><span class="p">(</span><span class="n">results_dir</span><span class="p">))</span>
<span class="k">return</span> <span class="n">t</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
</div>
<div class="viewcode-block" id="compose_detail"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.queue.compose_detail">[docs]</a><span class="k">def</span> <span class="nf">compose_detail</span><span class="p">(</span><span class="n">results_dir</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return details about the build.</span>
<span class="sd"> :param results_dir: The directory containing the metadata and results for the build</span>
<span class="sd"> :type results_dir: str</span>
<span class="sd"> :returns: A dictionary with details about the compose</span>
<span class="sd"> :rtype: dict</span>
<span class="sd"> The following details are included in the dict:</span>
<span class="sd"> * id - The uuid of the comoposition</span>
<span class="sd"> * queue_status - The final status of the composition (FINISHED or FAILED)</span>
<span class="sd"> * timestamp - The time of the last status change</span>
<span class="sd"> * compose_type - The type of output generated (tar, iso, etc.)</span>
<span class="sd"> * recipe - Recipe name</span>
<span class="sd"> * version - Recipe version</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c"># Just in case it went away</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">results_dir</span><span class="p">):</span>
<span class="k">return</span> <span class="p">{}</span>
<span class="n">build_id</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">basename</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">abspath</span><span class="p">(</span><span class="n">results_dir</span><span class="p">))</span>
<span class="n">status</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">results_dir</span><span class="p">,</span> <span class="s">&quot;STATUS&quot;</span><span class="p">))</span><span class="o">.</span><span class="n">read</span><span class="p">()</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
<span class="n">mtime</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">stat</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">results_dir</span><span class="p">,</span> <span class="s">&quot;STATUS&quot;</span><span class="p">))</span><span class="o">.</span><span class="n">st_mtime</span>
<span class="n">recipe</span> <span class="o">=</span> <span class="n">recipe_from_file</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">results_dir</span><span class="p">,</span> <span class="s">&quot;recipe.toml&quot;</span><span class="p">))</span>
<span class="n">compose_type</span> <span class="o">=</span> <span class="n">get_compose_type</span><span class="p">(</span><span class="n">results_dir</span><span class="p">)</span>
<span class="k">return</span> <span class="p">{</span><span class="s">&quot;id&quot;</span><span class="p">:</span> <span class="n">build_id</span><span class="p">,</span>
<span class="s">&quot;queue_status&quot;</span><span class="p">:</span> <span class="n">status</span><span class="p">,</span>
<span class="s">&quot;timestamp&quot;</span><span class="p">:</span> <span class="n">mtime</span><span class="p">,</span>
<span class="s">&quot;compose_type&quot;</span><span class="p">:</span> <span class="n">compose_type</span><span class="p">,</span>
<span class="s">&quot;recipe&quot;</span><span class="p">:</span> <span class="n">recipe</span><span class="p">[</span><span class="s">&quot;name&quot;</span><span class="p">],</span>
<span class="s">&quot;version&quot;</span><span class="p">:</span> <span class="n">recipe</span><span class="p">[</span><span class="s">&quot;version&quot;</span><span class="p">]</span>
<span class="p">}</span>
</div>
<div class="viewcode-block" id="queue_status"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.queue.queue_status">[docs]</a><span class="k">def</span> <span class="nf">queue_status</span><span class="p">(</span><span class="n">cfg</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return details about what is in the queue.</span>
<span class="sd"> :param cfg: Configuration settings</span>
<span class="sd"> :type cfg: ComposerConfig</span>
<span class="sd"> :returns: A list of the new composes, and a list of the running composes</span>
<span class="sd"> :rtype: dict</span>
<span class="sd"> This returns a dict with 2 lists. &quot;new&quot; is the list of uuids that are waiting to be built,</span>
<span class="sd"> and &quot;run&quot; has the uuids that are being built (currently limited to 1 at a time).</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">queue_dir</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">cfg</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">&quot;composer&quot;</span><span class="p">,</span> <span class="s">&quot;lib_dir&quot;</span><span class="p">),</span> <span class="s">&quot;queue&quot;</span><span class="p">)</span>
<span class="n">new_queue</span> <span class="o">=</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">realpath</span><span class="p">(</span><span class="n">p</span><span class="p">)</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">glob</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">queue_dir</span><span class="p">,</span> <span class="s">&quot;new/*&quot;</span><span class="p">))]</span>
<span class="n">run_queue</span> <span class="o">=</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">realpath</span><span class="p">(</span><span class="n">p</span><span class="p">)</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">glob</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">queue_dir</span><span class="p">,</span> <span class="s">&quot;run/*&quot;</span><span class="p">))]</span>
<span class="k">return</span> <span class="p">{</span>
<span class="s">&quot;new&quot;</span><span class="p">:</span> <span class="p">[</span><span class="n">compose_detail</span><span class="p">(</span><span class="n">n</span><span class="p">)</span> <span class="k">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="n">new_queue</span><span class="p">],</span>
<span class="s">&quot;run&quot;</span><span class="p">:</span> <span class="p">[</span><span class="n">compose_detail</span><span class="p">(</span><span class="n">r</span><span class="p">)</span> <span class="k">for</span> <span class="n">r</span> <span class="ow">in</span> <span class="n">run_queue</span><span class="p">]</span>
<span class="p">}</span>
</div>
<div class="viewcode-block" id="uuid_status"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.queue.uuid_status">[docs]</a><span class="k">def</span> <span class="nf">uuid_status</span><span class="p">(</span><span class="n">cfg</span><span class="p">,</span> <span class="n">uuid</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return the details of a specific UUID compose</span>
<span class="sd"> :param cfg: Configuration settings</span>
<span class="sd"> :type cfg: ComposerConfig</span>
<span class="sd"> :param uuid: The UUID of the build</span>
<span class="sd"> :type uuid: str</span>
<span class="sd"> :returns: Details about the build</span>
<span class="sd"> :rtype: dict or None</span>
<span class="sd"> Returns the same dict as `compose_details()`</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">uuid_dir</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">cfg</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">&quot;composer&quot;</span><span class="p">,</span> <span class="s">&quot;lib_dir&quot;</span><span class="p">),</span> <span class="s">&quot;results&quot;</span><span class="p">,</span> <span class="n">uuid</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">exists</span><span class="p">(</span><span class="n">uuid_dir</span><span class="p">):</span>
<span class="k">return</span> <span class="n">compose_detail</span><span class="p">(</span><span class="n">uuid_dir</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="bp">None</span>
</div>
<div class="viewcode-block" id="build_status"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.queue.build_status">[docs]</a><span class="k">def</span> <span class="nf">build_status</span><span class="p">(</span><span class="n">cfg</span><span class="p">,</span> <span class="n">status_filter</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return the details of finished or failed builds</span>
<span class="sd"> :param cfg: Configuration settings</span>
<span class="sd"> :type cfg: ComposerConfig</span>
<span class="sd"> :param status_filter: What builds to return. None == all, &quot;FINISHED&quot;, or &quot;FAILED&quot;</span>
<span class="sd"> :type status_filter: str</span>
<span class="sd"> :returns: A list of the build details (from compose_details)</span>
<span class="sd"> :rtype: list of dicts</span>
<span class="sd"> This returns a list of build details for each of the matching builds on the</span>
<span class="sd"> system. It does not return the status of builds that have not been finished.</span>
<span class="sd"> Use queue_status() for those.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">status_filter</span><span class="p">:</span>
<span class="n">status_filter</span> <span class="o">=</span> <span class="p">[</span><span class="n">status_filter</span><span class="p">]</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">status_filter</span> <span class="o">=</span> <span class="p">[</span><span class="s">&quot;FINISHED&quot;</span><span class="p">,</span> <span class="s">&quot;FAILED&quot;</span><span class="p">]</span>
<span class="n">results</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">result_dir</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">cfg</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">&quot;composer&quot;</span><span class="p">,</span> <span class="s">&quot;lib_dir&quot;</span><span class="p">),</span> <span class="s">&quot;results&quot;</span><span class="p">)</span>
<span class="k">for</span> <span class="n">build</span> <span class="ow">in</span> <span class="n">glob</span><span class="p">(</span><span class="n">result_dir</span> <span class="o">+</span> <span class="s">&quot;/*&quot;</span><span class="p">):</span>
<span class="n">log</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">&quot;Checking status of build </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">build</span><span class="p">)</span>
<span class="n">status</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">build</span><span class="p">,</span> <span class="s">&quot;STATUS&quot;</span><span class="p">),</span> <span class="s">&quot;r&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">read</span><span class="p">()</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
<span class="k">if</span> <span class="n">status</span> <span class="ow">in</span> <span class="n">status_filter</span><span class="p">:</span>
<span class="n">results</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">compose_detail</span><span class="p">(</span><span class="n">build</span><span class="p">))</span>
<span class="k">return</span> <span class="n">results</span>
</div>
<div class="viewcode-block" id="uuid_cancel"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.queue.uuid_cancel">[docs]</a><span class="k">def</span> <span class="nf">uuid_cancel</span><span class="p">(</span><span class="n">cfg</span><span class="p">,</span> <span class="n">uuid</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Cancel a build and delete its results</span>
<span class="sd"> :param cfg: Configuration settings</span>
<span class="sd"> :type cfg: ComposerConfig</span>
<span class="sd"> :param uuid: The UUID of the build</span>
<span class="sd"> :type uuid: str</span>
<span class="sd"> :returns: True if it was canceled and deleted</span>
<span class="sd"> :rtype: bool</span>
<span class="sd"> Only call this if the build status is WAITING or RUNNING</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c"># This status can change (and probably will) while it is in the middle of doing this:</span>
<span class="c"># It can move from WAITING -&gt; RUNNING or it can move from RUNNING -&gt; FINISHED|FAILED</span>
<span class="c"># If it is in WAITING remove the symlink and then check to make sure it didn&#39;t show up</span>
<span class="c"># in RUNNING</span>
<span class="n">queue_dir</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">cfg</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">&quot;composer&quot;</span><span class="p">,</span> <span class="s">&quot;lib_dir&quot;</span><span class="p">),</span> <span class="s">&quot;queue&quot;</span><span class="p">)</span>
<span class="n">uuid_new</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">queue_dir</span><span class="p">,</span> <span class="s">&quot;new&quot;</span><span class="p">,</span> <span class="n">uuid</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">exists</span><span class="p">(</span><span class="n">uuid_new</span><span class="p">):</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">os</span><span class="o">.</span><span class="n">unlink</span><span class="p">(</span><span class="n">uuid_new</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">OSError</span><span class="p">:</span>
<span class="c"># The symlink may vanish if the queue monitor started the build</span>
<span class="k">pass</span>
<span class="n">uuid_run</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">queue_dir</span><span class="p">,</span> <span class="s">&quot;run&quot;</span><span class="p">,</span> <span class="n">uuid</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">uuid_run</span><span class="p">):</span>
<span class="c"># Successfully removed it before the build started</span>
<span class="k">return</span> <span class="n">uuid_delete</span><span class="p">(</span><span class="n">cfg</span><span class="p">,</span> <span class="n">uuid</span><span class="p">)</span>
<span class="c"># Tell the build to stop running</span>
<span class="n">cancel_path</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">cfg</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">&quot;composer&quot;</span><span class="p">,</span> <span class="s">&quot;lib_dir&quot;</span><span class="p">),</span> <span class="s">&quot;results&quot;</span><span class="p">,</span> <span class="n">uuid</span><span class="p">,</span> <span class="s">&quot;CANCEL&quot;</span><span class="p">)</span>
<span class="nb">open</span><span class="p">(</span><span class="n">cancel_path</span><span class="p">,</span> <span class="s">&quot;w&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">&quot;</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">)</span>
<span class="c"># Wait for status to move to FAILED</span>
<span class="n">started</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span>
<span class="k">while</span> <span class="bp">True</span><span class="p">:</span>
<span class="n">status</span> <span class="o">=</span> <span class="n">uuid_status</span><span class="p">(</span><span class="n">cfg</span><span class="p">,</span> <span class="n">uuid</span><span class="p">)</span>
<span class="k">if</span> <span class="n">status</span><span class="p">[</span><span class="s">&quot;queue_status&quot;</span><span class="p">]</span> <span class="o">==</span> <span class="s">&quot;FAILED&quot;</span><span class="p">:</span>
<span class="k">break</span>
<span class="c"># Is this taking too long? Exit anyway and try to cleanup.</span>
<span class="k">if</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o">&gt;</span> <span class="n">started</span> <span class="o">+</span> <span class="p">(</span><span class="mi">10</span> <span class="o">*</span> <span class="mi">60</span><span class="p">):</span>
<span class="n">log</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s">&quot;Failed to cancel the build of </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">uuid</span><span class="p">)</span>
<span class="k">break</span>
<span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>
<span class="c"># Remove the partial results</span>
<span class="n">uuid_delete</span><span class="p">(</span><span class="n">cfg</span><span class="p">,</span> <span class="n">uuid</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="uuid_delete"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.queue.uuid_delete">[docs]</a><span class="k">def</span> <span class="nf">uuid_delete</span><span class="p">(</span><span class="n">cfg</span><span class="p">,</span> <span class="n">uuid</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Delete all of the results from a compose</span>
<span class="sd"> :param cfg: Configuration settings</span>
<span class="sd"> :type cfg: ComposerConfig</span>
<span class="sd"> :param uuid: The UUID of the build</span>
<span class="sd"> :type uuid: str</span>
<span class="sd"> :returns: True if it was deleted</span>
<span class="sd"> :rtype: bool</span>
<span class="sd"> :raises: This will raise an error if the delete failed</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">uuid_dir</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">cfg</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">&quot;composer&quot;</span><span class="p">,</span> <span class="s">&quot;lib_dir&quot;</span><span class="p">),</span> <span class="s">&quot;results&quot;</span><span class="p">,</span> <span class="n">uuid</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">uuid_dir</span> <span class="ow">or</span> <span class="nb">len</span><span class="p">(</span><span class="n">uuid_dir</span><span class="p">)</span> <span class="o">&lt;</span> <span class="mi">10</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s">&quot;Directory length is too short: </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">uuid_dir</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">uuid_dir</span><span class="p">)</span>
<span class="k">return</span> <span class="bp">True</span>
</div>
<div class="viewcode-block" id="uuid_info"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.queue.uuid_info">[docs]</a><span class="k">def</span> <span class="nf">uuid_info</span><span class="p">(</span><span class="n">cfg</span><span class="p">,</span> <span class="n">uuid</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return information about the composition</span>
<span class="sd"> :param cfg: Configuration settings</span>
<span class="sd"> :type cfg: ComposerConfig</span>
<span class="sd"> :param uuid: The UUID of the build</span>
<span class="sd"> :type uuid: str</span>
<span class="sd"> :returns: dictionary of information about the composition</span>
<span class="sd"> :rtype: dict</span>
<span class="sd"> :raises: RuntimeError if there was a problem</span>
<span class="sd"> This will return a dict with the following fields populated:</span>
<span class="sd"> * id - The uuid of the comoposition</span>
<span class="sd"> * config - containing the configuration settings used to run Anaconda</span>
<span class="sd"> * recipe - The depsolved recipe used to generate the kickstart</span>
<span class="sd"> * commit - The (local) git commit hash for the recipe used</span>
<span class="sd"> * deps - The NEVRA of all of the dependencies used in the composition</span>
<span class="sd"> * compose_type - The type of output generated (tar, iso, etc.)</span>
<span class="sd"> * queue_status - The final status of the composition (FINISHED or FAILED)</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">uuid_dir</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">cfg</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">&quot;composer&quot;</span><span class="p">,</span> <span class="s">&quot;lib_dir&quot;</span><span class="p">),</span> <span class="s">&quot;results&quot;</span><span class="p">,</span> <span class="n">uuid</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">uuid_dir</span><span class="p">):</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s">&quot;</span><span class="si">%s</span><span class="s"> is not a valid build_id&quot;</span> <span class="o">%</span> <span class="n">uuid</span><span class="p">)</span>
<span class="c"># Load the compose configuration</span>
<span class="n">cfg_path</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">uuid_dir</span><span class="p">,</span> <span class="s">&quot;config.toml&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">cfg_path</span><span class="p">):</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s">&quot;Missing config.toml for </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">uuid</span><span class="p">)</span>
<span class="n">cfg_dict</span> <span class="o">=</span> <span class="n">toml</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="nb">open</span><span class="p">(</span><span class="n">cfg_path</span><span class="p">,</span> <span class="s">&quot;r&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">read</span><span class="p">())</span>
<span class="n">frozen_path</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">uuid_dir</span><span class="p">,</span> <span class="s">&quot;frozen.toml&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">frozen_path</span><span class="p">):</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s">&quot;Missing frozen.toml for </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">uuid</span><span class="p">)</span>
<span class="n">frozen_dict</span> <span class="o">=</span> <span class="n">toml</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="nb">open</span><span class="p">(</span><span class="n">frozen_path</span><span class="p">,</span> <span class="s">&quot;r&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">read</span><span class="p">())</span>
<span class="n">deps_path</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">uuid_dir</span><span class="p">,</span> <span class="s">&quot;deps.toml&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">deps_path</span><span class="p">):</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s">&quot;Missing deps.toml for </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">uuid</span><span class="p">)</span>
<span class="n">deps_dict</span> <span class="o">=</span> <span class="n">toml</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="nb">open</span><span class="p">(</span><span class="n">deps_path</span><span class="p">,</span> <span class="s">&quot;r&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">read</span><span class="p">())</span>
<span class="n">compose_type</span> <span class="o">=</span> <span class="n">get_compose_type</span><span class="p">(</span><span class="n">uuid_dir</span><span class="p">)</span>
<span class="n">status</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">uuid_dir</span><span class="p">,</span> <span class="s">&quot;STATUS&quot;</span><span class="p">))</span><span class="o">.</span><span class="n">read</span><span class="p">()</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
<span class="n">commit_path</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">uuid_dir</span><span class="p">,</span> <span class="s">&quot;COMMIT&quot;</span><span class="p">)</span>
<span class="n">commit_id</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">commit_path</span><span class="p">,</span> <span class="s">&quot;r&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">read</span><span class="p">()</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
<span class="k">return</span> <span class="p">{</span><span class="s">&quot;id&quot;</span><span class="p">:</span> <span class="n">uuid</span><span class="p">,</span>
<span class="s">&quot;config&quot;</span><span class="p">:</span> <span class="n">cfg_dict</span><span class="p">,</span>
<span class="s">&quot;recipe&quot;</span><span class="p">:</span> <span class="n">frozen_dict</span><span class="p">,</span>
<span class="s">&quot;commit&quot;</span><span class="p">:</span> <span class="n">commit_id</span><span class="p">,</span>
<span class="s">&quot;deps&quot;</span><span class="p">:</span> <span class="n">deps_dict</span><span class="p">,</span>
<span class="s">&quot;compose_type&quot;</span><span class="p">:</span> <span class="n">compose_type</span><span class="p">,</span>
<span class="s">&quot;queue_status&quot;</span><span class="p">:</span> <span class="n">status</span>
<span class="p">}</span>
</div>
<div class="viewcode-block" id="uuid_tar"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.queue.uuid_tar">[docs]</a><span class="k">def</span> <span class="nf">uuid_tar</span><span class="p">(</span><span class="n">cfg</span><span class="p">,</span> <span class="n">uuid</span><span class="p">,</span> <span class="n">metadata</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">image</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">logs</span><span class="o">=</span><span class="bp">False</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return a tar of the build data</span>
<span class="sd"> :param cfg: Configuration settings</span>
<span class="sd"> :type cfg: ComposerConfig</span>
<span class="sd"> :param uuid: The UUID of the build</span>
<span class="sd"> :type uuid: str</span>
<span class="sd"> :param metadata: Set to true to include all the metadata needed to reproduce the build</span>
<span class="sd"> :type metadata: bool</span>
<span class="sd"> :param image: Set to true to include the output image</span>
<span class="sd"> :type image: bool</span>
<span class="sd"> :param logs: Set to true to include the logs from the build</span>
<span class="sd"> :type logs: bool</span>
<span class="sd"> :returns: A stream of bytes from tar</span>
<span class="sd"> :rtype: A generator</span>
<span class="sd"> :raises: RuntimeError if there was a problem (eg. missing config file)</span>
<span class="sd"> This yields an uncompressed tar&#39;s data to the caller. It includes</span>
<span class="sd"> the selected data to the caller by returning the Popen stdout from the tar process.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">uuid_dir</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">cfg</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">&quot;composer&quot;</span><span class="p">,</span> <span class="s">&quot;lib_dir&quot;</span><span class="p">),</span> <span class="s">&quot;results&quot;</span><span class="p">,</span> <span class="n">uuid</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">uuid_dir</span><span class="p">):</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s">&quot;</span><span class="si">%s</span><span class="s"> is not a valid build_id&quot;</span> <span class="o">%</span> <span class="n">uuid</span><span class="p">)</span>
<span class="c"># Load the compose configuration</span>
<span class="n">cfg_path</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">uuid_dir</span><span class="p">,</span> <span class="s">&quot;config.toml&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">cfg_path</span><span class="p">):</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s">&quot;Missing config.toml for </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">uuid</span><span class="p">)</span>
<span class="n">cfg_dict</span> <span class="o">=</span> <span class="n">toml</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="nb">open</span><span class="p">(</span><span class="n">cfg_path</span><span class="p">,</span> <span class="s">&quot;r&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">read</span><span class="p">())</span>
<span class="n">image_name</span> <span class="o">=</span> <span class="n">cfg_dict</span><span class="p">[</span><span class="s">&quot;image_name&quot;</span><span class="p">]</span>
<span class="k">def</span> <span class="nf">include_file</span><span class="p">(</span><span class="n">f</span><span class="p">):</span>
<span class="k">if</span> <span class="n">f</span><span class="o">.</span><span class="n">endswith</span><span class="p">(</span><span class="s">&quot;/logs&quot;</span><span class="p">):</span>
<span class="k">return</span> <span class="n">logs</span>
<span class="k">if</span> <span class="n">f</span><span class="o">.</span><span class="n">endswith</span><span class="p">(</span><span class="n">image_name</span><span class="p">):</span>
<span class="k">return</span> <span class="n">image</span>
<span class="k">return</span> <span class="n">metadata</span>
<span class="n">filenames</span> <span class="o">=</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">f</span><span class="p">)</span> <span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">glob</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">uuid_dir</span><span class="p">,</span> <span class="s">&quot;*&quot;</span><span class="p">))</span> <span class="k">if</span> <span class="n">include_file</span><span class="p">(</span><span class="n">f</span><span class="p">)]</span>
<span class="n">tar</span> <span class="o">=</span> <span class="n">Popen</span><span class="p">([</span><span class="s">&quot;tar&quot;</span><span class="p">,</span> <span class="s">&quot;-C&quot;</span><span class="p">,</span> <span class="n">uuid_dir</span><span class="p">,</span> <span class="s">&quot;-cf-&quot;</span><span class="p">]</span> <span class="o">+</span> <span class="n">filenames</span><span class="p">,</span> <span class="n">stdout</span><span class="o">=</span><span class="n">PIPE</span><span class="p">)</span>
<span class="k">return</span> <span class="n">tar</span><span class="o">.</span><span class="n">stdout</span>
</div>
<div class="viewcode-block" id="uuid_image"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.queue.uuid_image">[docs]</a><span class="k">def</span> <span class="nf">uuid_image</span><span class="p">(</span><span class="n">cfg</span><span class="p">,</span> <span class="n">uuid</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return the filename and full path of the build&#39;s image file</span>
<span class="sd"> :param cfg: Configuration settings</span>
<span class="sd"> :type cfg: ComposerConfig</span>
<span class="sd"> :param uuid: The UUID of the build</span>
<span class="sd"> :type uuid: str</span>
<span class="sd"> :returns: The image filename and full path</span>
<span class="sd"> :rtype: tuple of strings</span>
<span class="sd"> :raises: RuntimeError if there was a problem (eg. invalid uuid, missing config file)</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">uuid_dir</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">cfg</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">&quot;composer&quot;</span><span class="p">,</span> <span class="s">&quot;lib_dir&quot;</span><span class="p">),</span> <span class="s">&quot;results&quot;</span><span class="p">,</span> <span class="n">uuid</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">uuid_dir</span><span class="p">):</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s">&quot;</span><span class="si">%s</span><span class="s"> is not a valid build_id&quot;</span> <span class="o">%</span> <span class="n">uuid</span><span class="p">)</span>
<span class="c"># Load the compose configuration</span>
<span class="n">cfg_path</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">uuid_dir</span><span class="p">,</span> <span class="s">&quot;config.toml&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">cfg_path</span><span class="p">):</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s">&quot;Missing config.toml for </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">uuid</span><span class="p">)</span>
<span class="n">cfg_dict</span> <span class="o">=</span> <span class="n">toml</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="nb">open</span><span class="p">(</span><span class="n">cfg_path</span><span class="p">,</span> <span class="s">&quot;r&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">read</span><span class="p">())</span>
<span class="n">image_name</span> <span class="o">=</span> <span class="n">cfg_dict</span><span class="p">[</span><span class="s">&quot;image_name&quot;</span><span class="p">]</span>
<span class="k">return</span> <span class="p">(</span><span class="n">image_name</span><span class="p">,</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">uuid_dir</span><span class="p">,</span> <span class="n">image_name</span><span class="p">))</span>
</div>
<div class="viewcode-block" id="uuid_log"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.queue.uuid_log">[docs]</a><span class="k">def</span> <span class="nf">uuid_log</span><span class="p">(</span><span class="n">cfg</span><span class="p">,</span> <span class="n">uuid</span><span class="p">,</span> <span class="n">size</span><span class="o">=</span><span class="mi">1024</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return `size` kbytes from the end of the anaconda.log</span>
<span class="sd"> :param cfg: Configuration settings</span>
<span class="sd"> :type cfg: ComposerConfig</span>
<span class="sd"> :param uuid: The UUID of the build</span>
<span class="sd"> :type uuid: str</span>
<span class="sd"> :param size: Number of kbytes to read. Default is 1024</span>
<span class="sd"> :type size: int</span>
<span class="sd"> :returns: Up to `size` kbytes from the end of the log</span>
<span class="sd"> :rtype: str</span>
<span class="sd"> :raises: RuntimeError if there was a problem (eg. no log file available)</span>
<span class="sd"> This function tries to return lines from the end of the log, it will</span>
<span class="sd"> attempt to start on a line boundry, and may return less than `size` kbytes.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">uuid_dir</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">cfg</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">&quot;composer&quot;</span><span class="p">,</span> <span class="s">&quot;lib_dir&quot;</span><span class="p">),</span> <span class="s">&quot;results&quot;</span><span class="p">,</span> <span class="n">uuid</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">uuid_dir</span><span class="p">):</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s">&quot;</span><span class="si">%s</span><span class="s"> is not a valid build_id&quot;</span> <span class="o">%</span> <span class="n">uuid</span><span class="p">)</span>
<span class="c"># While a build is running the logs will be in /tmp/anaconda.log and when it</span>
<span class="c"># has finished they will be in the results directory</span>
<span class="n">status</span> <span class="o">=</span> <span class="n">uuid_status</span><span class="p">(</span><span class="n">cfg</span><span class="p">,</span> <span class="n">uuid</span><span class="p">)</span>
<span class="k">if</span> <span class="n">status</span><span class="p">[</span><span class="s">&quot;queue_status&quot;</span><span class="p">]</span> <span class="o">==</span> <span class="s">&quot;RUNNING&quot;</span><span class="p">:</span>
<span class="n">log_path</span> <span class="o">=</span> <span class="s">&quot;/tmp/anaconda.log&quot;</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">log_path</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">uuid_dir</span><span class="p">,</span> <span class="s">&quot;logs&quot;</span><span class="p">,</span> <span class="s">&quot;anaconda&quot;</span><span class="p">,</span> <span class="s">&quot;anaconda.log&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">log_path</span><span class="p">):</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s">&quot;No anaconda.log available.&quot;</span><span class="p">)</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">log_path</span><span class="p">,</span> <span class="s">&quot;r&quot;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
<span class="n">f</span><span class="o">.</span><span class="n">seek</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
<span class="n">end</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">tell</span><span class="p">()</span>
<span class="k">if</span> <span class="n">end</span> <span class="o">&lt;</span> <span class="mi">1024</span> <span class="o">*</span> <span class="n">size</span><span class="p">:</span>
<span class="n">f</span><span class="o">.</span><span class="n">seek</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">f</span><span class="o">.</span><span class="n">seek</span><span class="p">(</span><span class="n">end</span> <span class="o">-</span> <span class="p">(</span><span class="mi">1024</span> <span class="o">*</span> <span class="n">size</span><span class="p">))</span>
<span class="c"># Find the start of the next line and return the rest</span>
<span class="n">f</span><span class="o">.</span><span class="n">readline</span><span class="p">()</span>
<span class="k">return</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">()</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">Lorax 19.7.10 documentation</a> &raquo;</li>
<li><a href="../../index.html" >Module code</a> &raquo;</li>
<li><a href="../api.html" >pylorax.api</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2017, Red Hat, Inc..
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>

View File

@ -0,0 +1,978 @@
<!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>pylorax.api.recipes &mdash; Lorax 19.7.10 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: '19.7.10',
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>
<link rel="top" title="Lorax 19.7.10 documentation" href="../../../index.html" />
<link rel="up" title="pylorax.api" href="../api.html" />
</head>
<body>
<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">Lorax 19.7.10 documentation</a> &raquo;</li>
<li><a href="../../index.html" >Module code</a> &raquo;</li>
<li><a href="../api.html" accesskey="U">pylorax.api</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<h1>Source code for pylorax.api.recipes</h1><div class="highlight"><pre>
<span class="c">#</span>
<span class="c"># Copyright (C) 2017 Red Hat, Inc.</span>
<span class="c">#</span>
<span class="c"># This program is free software; you can redistribute it and/or modify</span>
<span class="c"># it under the terms of the GNU General Public License as published by</span>
<span class="c"># the Free Software Foundation; either version 2 of the License, or</span>
<span class="c"># (at your option) any later version.</span>
<span class="c">#</span>
<span class="c"># This program is distributed in the hope that it will be useful,</span>
<span class="c"># but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<span class="c"># MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span>
<span class="c"># GNU General Public License for more details.</span>
<span class="c">#</span>
<span class="c"># You should have received a copy of the GNU General Public License</span>
<span class="c"># along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;.</span>
<span class="c">#</span>
<span class="kn">import</span> <span class="nn">gi</span>
<span class="n">gi</span><span class="o">.</span><span class="n">require_version</span><span class="p">(</span><span class="s">&quot;Ggit&quot;</span><span class="p">,</span> <span class="s">&quot;1.0&quot;</span><span class="p">)</span>
<span class="kn">from</span> <span class="nn">gi.repository</span> <span class="kn">import</span> <span class="n">Ggit</span> <span class="k">as</span> <span class="n">Git</span>
<span class="kn">from</span> <span class="nn">gi.repository</span> <span class="kn">import</span> <span class="n">Gio</span>
<span class="kn">from</span> <span class="nn">gi.repository</span> <span class="kn">import</span> <span class="n">GLib</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">pytoml</span> <span class="kn">as</span> <span class="nn">toml</span>
<span class="kn">import</span> <span class="nn">semantic_version</span> <span class="kn">as</span> <span class="nn">semver</span>
<span class="kn">from</span> <span class="nn">pylorax.api.projects</span> <span class="kn">import</span> <span class="n">dep_evra</span>
<span class="kn">from</span> <span class="nn">pylorax.base</span> <span class="kn">import</span> <span class="n">DataHolder</span>
<span class="kn">from</span> <span class="nn">pylorax.sysutils</span> <span class="kn">import</span> <span class="n">joinpaths</span>
<div class="viewcode-block" id="CommitTimeValError"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.CommitTimeValError">[docs]</a><span class="k">class</span> <span class="nc">CommitTimeValError</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
<span class="k">pass</span>
</div>
<div class="viewcode-block" id="RecipeFileError"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.RecipeFileError">[docs]</a><span class="k">class</span> <span class="nc">RecipeFileError</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
<span class="k">pass</span>
</div>
<div class="viewcode-block" id="RecipeError"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.RecipeError">[docs]</a><span class="k">class</span> <span class="nc">RecipeError</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
<span class="k">pass</span>
</div>
<div class="viewcode-block" id="Recipe"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.Recipe">[docs]</a><span class="k">class</span> <span class="nc">Recipe</span><span class="p">(</span><span class="nb">dict</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;A Recipe of package and modules</span>
<span class="sd"> This is a subclass of dict that enforces the constructor arguments</span>
<span class="sd"> and adds a .filename property to return the recipe&#39;s filename,</span>
<span class="sd"> and a .toml() function to return the recipe as a TOML string.</span>
<span class="sd"> &quot;&quot;&quot;</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">name</span><span class="p">,</span> <span class="n">description</span><span class="p">,</span> <span class="n">version</span><span class="p">,</span> <span class="n">modules</span><span class="p">,</span> <span class="n">packages</span><span class="p">):</span>
<span class="c"># Check that version is empty or semver compatible</span>
<span class="k">if</span> <span class="n">version</span><span class="p">:</span>
<span class="n">semver</span><span class="o">.</span><span class="n">Version</span><span class="p">(</span><span class="n">version</span><span class="p">)</span>
<span class="c"># Make sure modules and packages are listed by their case-insensitive names</span>
<span class="k">if</span> <span class="n">modules</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span>
<span class="n">modules</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">modules</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">m</span><span class="p">:</span> <span class="n">m</span><span class="p">[</span><span class="s">&quot;name&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">lower</span><span class="p">())</span>
<span class="k">if</span> <span class="n">packages</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span>
<span class="n">packages</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">packages</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">p</span><span class="p">:</span> <span class="n">p</span><span class="p">[</span><span class="s">&quot;name&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">lower</span><span class="p">())</span>
<span class="nb">dict</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">name</span><span class="o">=</span><span class="n">name</span><span class="p">,</span>
<span class="n">description</span><span class="o">=</span><span class="n">description</span><span class="p">,</span>
<span class="n">version</span><span class="o">=</span><span class="n">version</span><span class="p">,</span>
<span class="n">modules</span><span class="o">=</span><span class="n">modules</span><span class="p">,</span>
<span class="n">packages</span><span class="o">=</span><span class="n">packages</span><span class="p">)</span>
<span class="nd">@property</span>
<div class="viewcode-block" id="Recipe.package_names"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.Recipe.package_names">[docs]</a> <span class="k">def</span> <span class="nf">package_names</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return the names of the packages&quot;&quot;&quot;</span>
<span class="k">return</span> <span class="nb">map</span><span class="p">(</span><span class="k">lambda</span> <span class="n">p</span><span class="p">:</span> <span class="n">p</span><span class="p">[</span><span class="s">&quot;name&quot;</span><span class="p">],</span> <span class="bp">self</span><span class="p">[</span><span class="s">&quot;packages&quot;</span><span class="p">]</span> <span class="ow">or</span> <span class="p">[])</span>
</div>
<span class="nd">@property</span>
<div class="viewcode-block" id="Recipe.module_names"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.Recipe.module_names">[docs]</a> <span class="k">def</span> <span class="nf">module_names</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return the names of the modules&quot;&quot;&quot;</span>
<span class="k">return</span> <span class="nb">map</span><span class="p">(</span><span class="k">lambda</span> <span class="n">m</span><span class="p">:</span> <span class="n">m</span><span class="p">[</span><span class="s">&quot;name&quot;</span><span class="p">],</span> <span class="bp">self</span><span class="p">[</span><span class="s">&quot;modules&quot;</span><span class="p">]</span> <span class="ow">or</span> <span class="p">[])</span>
</div>
<span class="nd">@property</span>
<div class="viewcode-block" id="Recipe.filename"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.Recipe.filename">[docs]</a> <span class="k">def</span> <span class="nf">filename</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return the Recipe&#39;s filename</span>
<span class="sd"> Replaces spaces in the name with &#39;-&#39; and appends .toml</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">return</span> <span class="n">recipe_filename</span><span class="p">(</span><span class="bp">self</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="Recipe.toml"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.Recipe.toml">[docs]</a> <span class="k">def</span> <span class="nf">toml</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return the Recipe in TOML format&quot;&quot;&quot;</span>
<span class="k">return</span> <span class="n">toml</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s">&quot;UTF-8&quot;</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="Recipe.bump_version"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.Recipe.bump_version">[docs]</a> <span class="k">def</span> <span class="nf">bump_version</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">old_version</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;semver recipe version number bump</span>
<span class="sd"> :param old_version: An optional old version number</span>
<span class="sd"> :type old_version: str</span>
<span class="sd"> :returns: The new version number or None</span>
<span class="sd"> :rtype: str</span>
<span class="sd"> :raises: ValueError</span>
<span class="sd"> If neither have a version, 0.0.1 is returned</span>
<span class="sd"> If there is no old version the new version is checked and returned</span>
<span class="sd"> If there is no new version, but there is a old one, bump its patch level</span>
<span class="sd"> If the old and new versions are the same, bump the patch level</span>
<span class="sd"> If they are different, check and return the new version</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">new_version</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">&quot;version&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">new_version</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">old_version</span><span class="p">:</span>
<span class="bp">self</span><span class="p">[</span><span class="s">&quot;version&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="s">&quot;0.0.1&quot;</span>
<span class="k">elif</span> <span class="n">new_version</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">old_version</span><span class="p">:</span>
<span class="n">semver</span><span class="o">.</span><span class="n">Version</span><span class="p">(</span><span class="n">new_version</span><span class="p">)</span>
<span class="bp">self</span><span class="p">[</span><span class="s">&quot;version&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">new_version</span>
<span class="k">elif</span> <span class="ow">not</span> <span class="n">new_version</span> <span class="ow">or</span> <span class="n">new_version</span> <span class="o">==</span> <span class="n">old_version</span><span class="p">:</span>
<span class="n">new_version</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">semver</span><span class="o">.</span><span class="n">Version</span><span class="p">(</span><span class="n">old_version</span><span class="p">)</span><span class="o">.</span><span class="n">next_patch</span><span class="p">())</span>
<span class="bp">self</span><span class="p">[</span><span class="s">&quot;version&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">new_version</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">semver</span><span class="o">.</span><span class="n">Version</span><span class="p">(</span><span class="n">new_version</span><span class="p">)</span>
<span class="bp">self</span><span class="p">[</span><span class="s">&quot;version&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">new_version</span>
<span class="c"># Return the new version</span>
<span class="k">return</span> <span class="nb">str</span><span class="p">(</span><span class="n">semver</span><span class="o">.</span><span class="n">Version</span><span class="p">(</span><span class="bp">self</span><span class="p">[</span><span class="s">&quot;version&quot;</span><span class="p">]))</span>
</div>
<div class="viewcode-block" id="Recipe.freeze"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.Recipe.freeze">[docs]</a> <span class="k">def</span> <span class="nf">freeze</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">deps</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot; Return a new Recipe with full module and package NEVRA</span>
<span class="sd"> :param deps: A list of dependency NEVRA to use to fill in the modules and packages</span>
<span class="sd"> :type deps: list(</span>
<span class="sd"> :returns: A new Recipe object</span>
<span class="sd"> :rtype: Recipe</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">module_names</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">module_names</span>
<span class="n">package_names</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">package_names</span>
<span class="n">new_modules</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">new_packages</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">dep</span> <span class="ow">in</span> <span class="n">deps</span><span class="p">:</span>
<span class="k">if</span> <span class="n">dep</span><span class="p">[</span><span class="s">&quot;name&quot;</span><span class="p">]</span> <span class="ow">in</span> <span class="n">package_names</span><span class="p">:</span>
<span class="n">new_packages</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">RecipePackage</span><span class="p">(</span><span class="n">dep</span><span class="p">[</span><span class="s">&quot;name&quot;</span><span class="p">],</span> <span class="n">dep_evra</span><span class="p">(</span><span class="n">dep</span><span class="p">)))</span>
<span class="k">elif</span> <span class="n">dep</span><span class="p">[</span><span class="s">&quot;name&quot;</span><span class="p">]</span> <span class="ow">in</span> <span class="n">module_names</span><span class="p">:</span>
<span class="n">new_modules</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">RecipeModule</span><span class="p">(</span><span class="n">dep</span><span class="p">[</span><span class="s">&quot;name&quot;</span><span class="p">],</span> <span class="n">dep_evra</span><span class="p">(</span><span class="n">dep</span><span class="p">)))</span>
<span class="k">return</span> <span class="n">Recipe</span><span class="p">(</span><span class="bp">self</span><span class="p">[</span><span class="s">&quot;name&quot;</span><span class="p">],</span> <span class="bp">self</span><span class="p">[</span><span class="s">&quot;description&quot;</span><span class="p">],</span> <span class="bp">self</span><span class="p">[</span><span class="s">&quot;version&quot;</span><span class="p">],</span>
<span class="n">new_modules</span><span class="p">,</span> <span class="n">new_packages</span><span class="p">)</span>
</div></div>
<div class="viewcode-block" id="RecipeModule"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.RecipeModule">[docs]</a><span class="k">class</span> <span class="nc">RecipeModule</span><span class="p">(</span><span class="nb">dict</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">name</span><span class="p">,</span> <span class="n">version</span><span class="p">):</span>
<span class="nb">dict</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">name</span><span class="o">=</span><span class="n">name</span><span class="p">,</span> <span class="n">version</span><span class="o">=</span><span class="n">version</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="RecipePackage"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.RecipePackage">[docs]</a><span class="k">class</span> <span class="nc">RecipePackage</span><span class="p">(</span><span class="n">RecipeModule</span><span class="p">):</span>
<span class="k">pass</span>
</div>
<div class="viewcode-block" id="recipe_from_file"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.recipe_from_file">[docs]</a><span class="k">def</span> <span class="nf">recipe_from_file</span><span class="p">(</span><span class="n">recipe_path</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return a recipe file as a Recipe object</span>
<span class="sd"> :param recipe_path: Path to the recipe fila</span>
<span class="sd"> :type recipe_path: str</span>
<span class="sd"> :returns: A Recipe object</span>
<span class="sd"> :rtype: Recipe</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">recipe_path</span><span class="p">,</span> <span class="s">&#39;rb&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
<span class="k">return</span> <span class="n">recipe_from_toml</span><span class="p">(</span><span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">())</span>
</div>
<div class="viewcode-block" id="recipe_from_toml"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.recipe_from_toml">[docs]</a><span class="k">def</span> <span class="nf">recipe_from_toml</span><span class="p">(</span><span class="n">recipe_str</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Create a Recipe object from a toml string.</span>
<span class="sd"> :param recipe_str: The Recipe TOML string</span>
<span class="sd"> :type recipe_str: str</span>
<span class="sd"> :returns: A Recipe object</span>
<span class="sd"> :rtype: Recipe</span>
<span class="sd"> :raises: TomlError</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">recipe_dict</span> <span class="o">=</span> <span class="n">toml</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">recipe_str</span><span class="p">)</span>
<span class="k">return</span> <span class="n">recipe_from_dict</span><span class="p">(</span><span class="n">recipe_dict</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="recipe_from_dict"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.recipe_from_dict">[docs]</a><span class="k">def</span> <span class="nf">recipe_from_dict</span><span class="p">(</span><span class="n">recipe_dict</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Create a Recipe object from a plain dict.</span>
<span class="sd"> :param recipe_dict: A plain dict of the recipe</span>
<span class="sd"> :type recipe_dict: dict</span>
<span class="sd"> :returns: A Recipe object</span>
<span class="sd"> :rtype: Recipe</span>
<span class="sd"> :raises: RecipeError</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c"># Make RecipeModule objects from the toml</span>
<span class="c"># The TOML may not have modules or packages in it. Set them to None in this case</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">if</span> <span class="n">recipe_dict</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">&quot;modules&quot;</span><span class="p">):</span>
<span class="n">modules</span> <span class="o">=</span> <span class="p">[</span><span class="n">RecipeModule</span><span class="p">(</span><span class="n">m</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> <span class="n">m</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">&quot;version&quot;</span><span class="p">))</span> <span class="k">for</span> <span class="n">m</span> <span class="ow">in</span> <span class="n">recipe_dict</span><span class="p">[</span><span class="s">&quot;modules&quot;</span><span class="p">]]</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">modules</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">if</span> <span class="n">recipe_dict</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="n">packages</span> <span class="o">=</span> <span class="p">[</span><span class="n">RecipePackage</span><span class="p">(</span><span class="n">p</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> <span class="n">p</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">&quot;version&quot;</span><span class="p">))</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">recipe_dict</span><span class="p">[</span><span class="s">&quot;packages&quot;</span><span class="p">]]</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">packages</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">name</span> <span class="o">=</span> <span class="n">recipe_dict</span><span class="p">[</span><span class="s">&quot;name&quot;</span><span class="p">]</span>
<span class="n">description</span> <span class="o">=</span> <span class="n">recipe_dict</span><span class="p">[</span><span class="s">&quot;description&quot;</span><span class="p">]</span>
<span class="n">version</span> <span class="o">=</span> <span class="n">recipe_dict</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">&quot;version&quot;</span><span class="p">,</span> <span class="bp">None</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">KeyError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">RecipeError</span><span class="p">(</span><span class="s">&quot;There was a problem parsing the recipe: </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">))</span>
<span class="k">return</span> <span class="n">Recipe</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">description</span><span class="p">,</span> <span class="n">version</span><span class="p">,</span> <span class="n">modules</span><span class="p">,</span> <span class="n">packages</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="gfile"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.gfile">[docs]</a><span class="k">def</span> <span class="nf">gfile</span><span class="p">(</span><span class="n">path</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Convert a string path to GFile for use with Git&quot;&quot;&quot;</span>
<span class="k">return</span> <span class="n">Gio</span><span class="o">.</span><span class="n">file_new_for_path</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="recipe_filename"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.recipe_filename">[docs]</a><span class="k">def</span> <span class="nf">recipe_filename</span><span class="p">(</span><span class="n">name</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return the toml filename for a recipe</span>
<span class="sd"> Replaces spaces with &#39;-&#39; and appends &#39;.toml&#39;</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c"># XXX Raise and error if this is empty?</span>
<span class="k">return</span> <span class="n">name</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s">&quot; &quot;</span><span class="p">,</span> <span class="s">&quot;-&quot;</span><span class="p">)</span> <span class="o">+</span> <span class="s">&quot;.toml&quot;</span>
</div>
<div class="viewcode-block" id="head_commit"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.head_commit">[docs]</a><span class="k">def</span> <span class="nf">head_commit</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Get the branch&#39;s HEAD Commit Object</span>
<span class="sd"> :param repo: Open repository</span>
<span class="sd"> :type repo: Git.Repository</span>
<span class="sd"> :param branch: Branch name</span>
<span class="sd"> :type branch: str</span>
<span class="sd"> :returns: Branch&#39;s head commit</span>
<span class="sd"> :rtype: Git.Commit</span>
<span class="sd"> :raises: Can raise errors from Ggit</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">branch_obj</span> <span class="o">=</span> <span class="n">repo</span><span class="o">.</span><span class="n">lookup_branch</span><span class="p">(</span><span class="n">branch</span><span class="p">,</span> <span class="n">Git</span><span class="o">.</span><span class="n">BranchType</span><span class="o">.</span><span class="n">LOCAL</span><span class="p">)</span>
<span class="n">commit_id</span> <span class="o">=</span> <span class="n">branch_obj</span><span class="o">.</span><span class="n">get_target</span><span class="p">()</span>
<span class="k">return</span> <span class="n">repo</span><span class="o">.</span><span class="n">lookup</span><span class="p">(</span><span class="n">commit_id</span><span class="p">,</span> <span class="n">Git</span><span class="o">.</span><span class="n">Commit</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="prepare_commit"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.prepare_commit">[docs]</a><span class="k">def</span> <span class="nf">prepare_commit</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">builder</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Prepare for a commit</span>
<span class="sd"> :param repo: Open repository</span>
<span class="sd"> :type repo: Git.Repository</span>
<span class="sd"> :param branch: Branch name</span>
<span class="sd"> :type branch: str</span>
<span class="sd"> :param builder: instance of TreeBuilder</span>
<span class="sd"> :type builder: TreeBuilder</span>
<span class="sd"> :returns: (Tree, Sig, Ref)</span>
<span class="sd"> :rtype: tuple</span>
<span class="sd"> :raises: Can raise errors from Ggit</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">tree_id</span> <span class="o">=</span> <span class="n">builder</span><span class="o">.</span><span class="n">write</span><span class="p">()</span>
<span class="n">tree</span> <span class="o">=</span> <span class="n">repo</span><span class="o">.</span><span class="n">lookup</span><span class="p">(</span><span class="n">tree_id</span><span class="p">,</span> <span class="n">Git</span><span class="o">.</span><span class="n">Tree</span><span class="p">)</span>
<span class="n">sig</span> <span class="o">=</span> <span class="n">Git</span><span class="o">.</span><span class="n">Signature</span><span class="o">.</span><span class="n">new_now</span><span class="p">(</span><span class="s">&quot;bdcs-api-server&quot;</span><span class="p">,</span> <span class="s">&quot;user-email&quot;</span><span class="p">)</span>
<span class="n">ref</span> <span class="o">=</span> <span class="s">&quot;refs/heads/</span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">branch</span>
<span class="k">return</span> <span class="p">(</span><span class="n">tree</span><span class="p">,</span> <span class="n">sig</span><span class="p">,</span> <span class="n">ref</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="open_or_create_repo"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.open_or_create_repo">[docs]</a><span class="k">def</span> <span class="nf">open_or_create_repo</span><span class="p">(</span><span class="n">path</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Open an existing repo, or create a new one</span>
<span class="sd"> :param path: path to recipe directory</span>
<span class="sd"> :type path: string</span>
<span class="sd"> :returns: A repository object</span>
<span class="sd"> :rtype: Git.Repository</span>
<span class="sd"> :raises: Can raise errors from Ggit</span>
<span class="sd"> A bare git repo will be created in the git directory of the specified path.</span>
<span class="sd"> If a repo already exists it will be opened and returned instead of</span>
<span class="sd"> creating a new one.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">Git</span><span class="o">.</span><span class="n">init</span><span class="p">()</span>
<span class="n">git_path</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="s">&quot;git&quot;</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">exists</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">git_path</span><span class="p">,</span> <span class="s">&quot;HEAD&quot;</span><span class="p">)):</span>
<span class="k">return</span> <span class="n">Git</span><span class="o">.</span><span class="n">Repository</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="n">gfile</span><span class="p">(</span><span class="n">git_path</span><span class="p">))</span>
<span class="n">repo</span> <span class="o">=</span> <span class="n">Git</span><span class="o">.</span><span class="n">Repository</span><span class="o">.</span><span class="n">init_repository</span><span class="p">(</span><span class="n">gfile</span><span class="p">(</span><span class="n">git_path</span><span class="p">),</span> <span class="bp">True</span><span class="p">)</span>
<span class="c"># Make an initial empty commit</span>
<span class="n">sig</span> <span class="o">=</span> <span class="n">Git</span><span class="o">.</span><span class="n">Signature</span><span class="o">.</span><span class="n">new_now</span><span class="p">(</span><span class="s">&quot;bdcs-api-server&quot;</span><span class="p">,</span> <span class="s">&quot;user-email&quot;</span><span class="p">)</span>
<span class="n">tree_id</span> <span class="o">=</span> <span class="n">repo</span><span class="o">.</span><span class="n">get_index</span><span class="p">()</span><span class="o">.</span><span class="n">write_tree</span><span class="p">()</span>
<span class="n">tree</span> <span class="o">=</span> <span class="n">repo</span><span class="o">.</span><span class="n">lookup</span><span class="p">(</span><span class="n">tree_id</span><span class="p">,</span> <span class="n">Git</span><span class="o">.</span><span class="n">Tree</span><span class="p">)</span>
<span class="n">repo</span><span class="o">.</span><span class="n">create_commit</span><span class="p">(</span><span class="s">&quot;HEAD&quot;</span><span class="p">,</span> <span class="n">sig</span><span class="p">,</span> <span class="n">sig</span><span class="p">,</span> <span class="s">&quot;UTF-8&quot;</span><span class="p">,</span> <span class="s">&quot;Initial Recipe repository commit&quot;</span><span class="p">,</span> <span class="n">tree</span><span class="p">,</span> <span class="p">[])</span>
<span class="k">return</span> <span class="n">repo</span>
</div>
<div class="viewcode-block" id="write_commit"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.write_commit">[docs]</a><span class="k">def</span> <span class="nf">write_commit</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">filename</span><span class="p">,</span> <span class="n">message</span><span class="p">,</span> <span class="n">content</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Make a new commit to a repository&#39;s branch</span>
<span class="sd"> :param repo: Open repository</span>
<span class="sd"> :type repo: Git.Repository</span>
<span class="sd"> :param branch: Branch name</span>
<span class="sd"> :type branch: str</span>
<span class="sd"> :param filename: full path of the file to add</span>
<span class="sd"> :type filename: str</span>
<span class="sd"> :param message: The commit message</span>
<span class="sd"> :type message: str</span>
<span class="sd"> :param content: The data to write</span>
<span class="sd"> :type content: str</span>
<span class="sd"> :returns: OId of the new commit</span>
<span class="sd"> :rtype: Git.OId</span>
<span class="sd"> :raises: Can raise errors from Ggit</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">parent_commit</span> <span class="o">=</span> <span class="n">head_commit</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">)</span>
<span class="k">except</span> <span class="n">GLib</span><span class="o">.</span><span class="n">GError</span><span class="p">:</span>
<span class="c"># Branch doesn&#39;t exist, make a new one based on master</span>
<span class="n">master_head</span> <span class="o">=</span> <span class="n">head_commit</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="s">&quot;master&quot;</span><span class="p">)</span>
<span class="n">repo</span><span class="o">.</span><span class="n">create_branch</span><span class="p">(</span><span class="n">branch</span><span class="p">,</span> <span class="n">master_head</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
<span class="n">parent_commit</span> <span class="o">=</span> <span class="n">head_commit</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">)</span>
<span class="n">parent_commit</span> <span class="o">=</span> <span class="n">head_commit</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">)</span>
<span class="n">blob_id</span> <span class="o">=</span> <span class="n">repo</span><span class="o">.</span><span class="n">create_blob_from_buffer</span><span class="p">(</span><span class="n">content</span><span class="p">)</span>
<span class="c"># Use treebuilder to make a new entry for this filename and blob</span>
<span class="n">parent_tree</span> <span class="o">=</span> <span class="n">parent_commit</span><span class="o">.</span><span class="n">get_tree</span><span class="p">()</span>
<span class="n">builder</span> <span class="o">=</span> <span class="n">repo</span><span class="o">.</span><span class="n">create_tree_builder_from_tree</span><span class="p">(</span><span class="n">parent_tree</span><span class="p">)</span>
<span class="n">builder</span><span class="o">.</span><span class="n">insert</span><span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="n">blob_id</span><span class="p">,</span> <span class="n">Git</span><span class="o">.</span><span class="n">FileMode</span><span class="o">.</span><span class="n">BLOB</span><span class="p">)</span>
<span class="p">(</span><span class="n">tree</span><span class="p">,</span> <span class="n">sig</span><span class="p">,</span> <span class="n">ref</span><span class="p">)</span> <span class="o">=</span> <span class="n">prepare_commit</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">builder</span><span class="p">)</span>
<span class="k">return</span> <span class="n">repo</span><span class="o">.</span><span class="n">create_commit</span><span class="p">(</span><span class="n">ref</span><span class="p">,</span> <span class="n">sig</span><span class="p">,</span> <span class="n">sig</span><span class="p">,</span> <span class="s">&quot;UTF-8&quot;</span><span class="p">,</span> <span class="n">message</span><span class="p">,</span> <span class="n">tree</span><span class="p">,</span> <span class="p">[</span><span class="n">parent_commit</span><span class="p">])</span>
</div>
<div class="viewcode-block" id="read_commit_spec"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.read_commit_spec">[docs]</a><span class="k">def</span> <span class="nf">read_commit_spec</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">spec</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return the raw content of the blob specified by the spec</span>
<span class="sd"> :param repo: Open repository</span>
<span class="sd"> :type repo: Git.Repository</span>
<span class="sd"> :param spec: Git revparse spec</span>
<span class="sd"> :type spec: str</span>
<span class="sd"> :returns: Contents of the commit</span>
<span class="sd"> :rtype: str</span>
<span class="sd"> :raises: Can raise errors from Ggit</span>
<span class="sd"> eg. To read the README file from master the spec is &quot;master:README&quot;</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">commit_id</span> <span class="o">=</span> <span class="n">repo</span><span class="o">.</span><span class="n">revparse</span><span class="p">(</span><span class="n">spec</span><span class="p">)</span><span class="o">.</span><span class="n">get_id</span><span class="p">()</span>
<span class="n">blob</span> <span class="o">=</span> <span class="n">repo</span><span class="o">.</span><span class="n">lookup</span><span class="p">(</span><span class="n">commit_id</span><span class="p">,</span> <span class="n">Git</span><span class="o">.</span><span class="n">Blob</span><span class="p">)</span>
<span class="k">return</span> <span class="n">blob</span><span class="o">.</span><span class="n">get_raw_content</span><span class="p">()</span>
</div>
<div class="viewcode-block" id="read_commit"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.read_commit">[docs]</a><span class="k">def</span> <span class="nf">read_commit</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">filename</span><span class="p">,</span> <span class="n">commit</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return the contents of a file on a specific branch or commit.</span>
<span class="sd"> :param repo: Open repository</span>
<span class="sd"> :type repo: Git.Repository</span>
<span class="sd"> :param branch: Branch name</span>
<span class="sd"> :type branch: str</span>
<span class="sd"> :param filename: filename to read</span>
<span class="sd"> :type filename: str</span>
<span class="sd"> :param commit: Optional commit hash</span>
<span class="sd"> :type commit: str</span>
<span class="sd"> :returns: The commit id, and the contents of the commit</span>
<span class="sd"> :rtype: tuple(str, str)</span>
<span class="sd"> :raises: Can raise errors from Ggit</span>
<span class="sd"> If no commit is passed the master:filename is returned, otherwise it will be</span>
<span class="sd"> commit:filename</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">commit</span><span class="p">:</span>
<span class="c"># Find the most recent commit for filename on the selected branch</span>
<span class="n">commits</span> <span class="o">=</span> <span class="n">list_commits</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">filename</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">commits</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">RecipeError</span><span class="p">(</span><span class="s">&quot;No commits for </span><span class="si">%s</span><span class="s"> on the </span><span class="si">%s</span><span class="s"> branch.&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="n">branch</span><span class="p">))</span>
<span class="n">commit</span> <span class="o">=</span> <span class="n">commits</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">commit</span>
<span class="k">return</span> <span class="p">(</span><span class="n">commit</span><span class="p">,</span> <span class="n">read_commit_spec</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="s">&quot;</span><span class="si">%s</span><span class="s">:</span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">commit</span><span class="p">,</span> <span class="n">filename</span><span class="p">)))</span>
</div>
<div class="viewcode-block" id="read_recipe_commit"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.read_recipe_commit">[docs]</a><span class="k">def</span> <span class="nf">read_recipe_commit</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">recipe_name</span><span class="p">,</span> <span class="n">commit</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Read a recipe commit from git and return a Recipe object</span>
<span class="sd"> :param repo: Open repository</span>
<span class="sd"> :type repo: Git.Repository</span>
<span class="sd"> :param branch: Branch name</span>
<span class="sd"> :type branch: str</span>
<span class="sd"> :param recipe_name: Recipe name to read</span>
<span class="sd"> :type recipe_name: str</span>
<span class="sd"> :param commit: Optional commit hash</span>
<span class="sd"> :type commit: str</span>
<span class="sd"> :returns: A Recipe object</span>
<span class="sd"> :rtype: Recipe</span>
<span class="sd"> :raises: Can raise errors from Ggit</span>
<span class="sd"> If no commit is passed the master:filename is returned, otherwise it will be</span>
<span class="sd"> commit:filename</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="p">(</span><span class="n">_</span><span class="p">,</span> <span class="n">recipe_toml</span><span class="p">)</span> <span class="o">=</span> <span class="n">read_commit</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">recipe_filename</span><span class="p">(</span><span class="n">recipe_name</span><span class="p">),</span> <span class="n">commit</span><span class="p">)</span>
<span class="k">return</span> <span class="n">recipe_from_toml</span><span class="p">(</span><span class="n">recipe_toml</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="read_recipe_and_id"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.read_recipe_and_id">[docs]</a><span class="k">def</span> <span class="nf">read_recipe_and_id</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">recipe_name</span><span class="p">,</span> <span class="n">commit</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Read a recipe commit and its id from git</span>
<span class="sd"> :param repo: Open repository</span>
<span class="sd"> :type repo: Git.Repository</span>
<span class="sd"> :param branch: Branch name</span>
<span class="sd"> :type branch: str</span>
<span class="sd"> :param recipe_name: Recipe name to read</span>
<span class="sd"> :type recipe_name: str</span>
<span class="sd"> :param commit: Optional commit hash</span>
<span class="sd"> :type commit: str</span>
<span class="sd"> :returns: The commit id, and a Recipe object</span>
<span class="sd"> :rtype: tuple(str, Recipe)</span>
<span class="sd"> :raises: Can raise errors from Ggit</span>
<span class="sd"> If no commit is passed the master:filename is returned, otherwise it will be</span>
<span class="sd"> commit:filename</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="p">(</span><span class="n">commit_id</span><span class="p">,</span> <span class="n">recipe_toml</span><span class="p">)</span> <span class="o">=</span> <span class="n">read_commit</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">recipe_filename</span><span class="p">(</span><span class="n">recipe_name</span><span class="p">),</span> <span class="n">commit</span><span class="p">)</span>
<span class="k">return</span> <span class="p">(</span><span class="n">commit_id</span><span class="p">,</span> <span class="n">recipe_from_toml</span><span class="p">(</span><span class="n">recipe_toml</span><span class="p">))</span>
</div>
<div class="viewcode-block" id="list_branch_files"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.list_branch_files">[docs]</a><span class="k">def</span> <span class="nf">list_branch_files</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return a sorted list of the files on the branch HEAD</span>
<span class="sd"> :param repo: Open repository</span>
<span class="sd"> :type repo: Git.Repository</span>
<span class="sd"> :param branch: Branch name</span>
<span class="sd"> :type branch: str</span>
<span class="sd"> :returns: A sorted list of the filenames</span>
<span class="sd"> :rtype: list(str)</span>
<span class="sd"> :raises: Can raise errors from Ggit</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">commit</span> <span class="o">=</span> <span class="n">head_commit</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">)</span><span class="o">.</span><span class="n">get_id</span><span class="p">()</span><span class="o">.</span><span class="n">to_string</span><span class="p">()</span>
<span class="k">return</span> <span class="n">list_commit_files</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">commit</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="list_commit_files"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.list_commit_files">[docs]</a><span class="k">def</span> <span class="nf">list_commit_files</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">commit</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return a sorted list of the files on a commit</span>
<span class="sd"> :param repo: Open repository</span>
<span class="sd"> :type repo: Git.Repository</span>
<span class="sd"> :param commit: The commit hash to list</span>
<span class="sd"> :type commit: str</span>
<span class="sd"> :returns: A sorted list of the filenames</span>
<span class="sd"> :rtype: list(str)</span>
<span class="sd"> :raises: Can raise errors from Ggit</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">commit_id</span> <span class="o">=</span> <span class="n">Git</span><span class="o">.</span><span class="n">OId</span><span class="o">.</span><span class="n">new_from_string</span><span class="p">(</span><span class="n">commit</span><span class="p">)</span>
<span class="n">commit_obj</span> <span class="o">=</span> <span class="n">repo</span><span class="o">.</span><span class="n">lookup</span><span class="p">(</span><span class="n">commit_id</span><span class="p">,</span> <span class="n">Git</span><span class="o">.</span><span class="n">Commit</span><span class="p">)</span>
<span class="n">tree</span> <span class="o">=</span> <span class="n">commit_obj</span><span class="o">.</span><span class="n">get_tree</span><span class="p">()</span>
<span class="k">return</span> <span class="nb">sorted</span><span class="p">([</span><span class="n">tree</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">i</span><span class="p">)</span><span class="o">.</span><span class="n">get_name</span><span class="p">()</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="n">tree</span><span class="o">.</span><span class="n">size</span><span class="p">())])</span>
</div>
<div class="viewcode-block" id="delete_recipe"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.delete_recipe">[docs]</a><span class="k">def</span> <span class="nf">delete_recipe</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">recipe_name</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Delete a recipe from a branch.</span>
<span class="sd"> :param repo: Open repository</span>
<span class="sd"> :type repo: Git.Repository</span>
<span class="sd"> :param branch: Branch name</span>
<span class="sd"> :type branch: str</span>
<span class="sd"> :param recipe_name: Recipe name to delete</span>
<span class="sd"> :type recipe_name: str</span>
<span class="sd"> :returns: OId of the new commit</span>
<span class="sd"> :rtype: Git.OId</span>
<span class="sd"> :raises: Can raise errors from Ggit</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">return</span> <span class="n">delete_file</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">recipe_filename</span><span class="p">(</span><span class="n">recipe_name</span><span class="p">))</span>
</div>
<div class="viewcode-block" id="delete_file"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.delete_file">[docs]</a><span class="k">def</span> <span class="nf">delete_file</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">filename</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Delete a file from a branch.</span>
<span class="sd"> :param repo: Open repository</span>
<span class="sd"> :type repo: Git.Repository</span>
<span class="sd"> :param branch: Branch name</span>
<span class="sd"> :type branch: str</span>
<span class="sd"> :param filename: filename to delete</span>
<span class="sd"> :type filename: str</span>
<span class="sd"> :returns: OId of the new commit</span>
<span class="sd"> :rtype: Git.OId</span>
<span class="sd"> :raises: Can raise errors from Ggit</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">parent_commit</span> <span class="o">=</span> <span class="n">head_commit</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">)</span>
<span class="n">parent_tree</span> <span class="o">=</span> <span class="n">parent_commit</span><span class="o">.</span><span class="n">get_tree</span><span class="p">()</span>
<span class="n">builder</span> <span class="o">=</span> <span class="n">repo</span><span class="o">.</span><span class="n">create_tree_builder_from_tree</span><span class="p">(</span><span class="n">parent_tree</span><span class="p">)</span>
<span class="n">builder</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">filename</span><span class="p">)</span>
<span class="p">(</span><span class="n">tree</span><span class="p">,</span> <span class="n">sig</span><span class="p">,</span> <span class="n">ref</span><span class="p">)</span> <span class="o">=</span> <span class="n">prepare_commit</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">builder</span><span class="p">)</span>
<span class="n">message</span> <span class="o">=</span> <span class="s">&quot;Recipe </span><span class="si">%s</span><span class="s"> deleted&quot;</span> <span class="o">%</span> <span class="n">filename</span>
<span class="k">return</span> <span class="n">repo</span><span class="o">.</span><span class="n">create_commit</span><span class="p">(</span><span class="n">ref</span><span class="p">,</span> <span class="n">sig</span><span class="p">,</span> <span class="n">sig</span><span class="p">,</span> <span class="s">&quot;UTF-8&quot;</span><span class="p">,</span> <span class="n">message</span><span class="p">,</span> <span class="n">tree</span><span class="p">,</span> <span class="p">[</span><span class="n">parent_commit</span><span class="p">])</span>
</div>
<div class="viewcode-block" id="revert_recipe"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.revert_recipe">[docs]</a><span class="k">def</span> <span class="nf">revert_recipe</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">recipe_name</span><span class="p">,</span> <span class="n">commit</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Revert the contents of a recipe to that of a previous commit</span>
<span class="sd"> :param repo: Open repository</span>
<span class="sd"> :type repo: Git.Repository</span>
<span class="sd"> :param branch: Branch name</span>
<span class="sd"> :type branch: str</span>
<span class="sd"> :param recipe_name: Recipe name to revert</span>
<span class="sd"> :type recipe_name: str</span>
<span class="sd"> :param commit: Commit hash</span>
<span class="sd"> :type commit: str</span>
<span class="sd"> :returns: OId of the new commit</span>
<span class="sd"> :rtype: Git.OId</span>
<span class="sd"> :raises: Can raise errors from Ggit</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">return</span> <span class="n">revert_file</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">recipe_filename</span><span class="p">(</span><span class="n">recipe_name</span><span class="p">),</span> <span class="n">commit</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="revert_file"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.revert_file">[docs]</a><span class="k">def</span> <span class="nf">revert_file</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">filename</span><span class="p">,</span> <span class="n">commit</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Revert the contents of a file to that of a previous commit</span>
<span class="sd"> :param repo: Open repository</span>
<span class="sd"> :type repo: Git.Repository</span>
<span class="sd"> :param branch: Branch name</span>
<span class="sd"> :type branch: str</span>
<span class="sd"> :param filename: filename to revert</span>
<span class="sd"> :type filename: str</span>
<span class="sd"> :param commit: Commit hash</span>
<span class="sd"> :type commit: str</span>
<span class="sd"> :returns: OId of the new commit</span>
<span class="sd"> :rtype: Git.OId</span>
<span class="sd"> :raises: Can raise errors from Ggit</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">commit_id</span> <span class="o">=</span> <span class="n">Git</span><span class="o">.</span><span class="n">OId</span><span class="o">.</span><span class="n">new_from_string</span><span class="p">(</span><span class="n">commit</span><span class="p">)</span>
<span class="n">commit_obj</span> <span class="o">=</span> <span class="n">repo</span><span class="o">.</span><span class="n">lookup</span><span class="p">(</span><span class="n">commit_id</span><span class="p">,</span> <span class="n">Git</span><span class="o">.</span><span class="n">Commit</span><span class="p">)</span>
<span class="n">revert_tree</span> <span class="o">=</span> <span class="n">commit_obj</span><span class="o">.</span><span class="n">get_tree</span><span class="p">()</span>
<span class="n">entry</span> <span class="o">=</span> <span class="n">revert_tree</span><span class="o">.</span><span class="n">get_by_name</span><span class="p">(</span><span class="n">filename</span><span class="p">)</span>
<span class="n">blob_id</span> <span class="o">=</span> <span class="n">entry</span><span class="o">.</span><span class="n">get_id</span><span class="p">()</span>
<span class="n">parent_commit</span> <span class="o">=</span> <span class="n">head_commit</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">)</span>
<span class="c"># Use treebuilder to modify the tree</span>
<span class="n">parent_tree</span> <span class="o">=</span> <span class="n">parent_commit</span><span class="o">.</span><span class="n">get_tree</span><span class="p">()</span>
<span class="n">builder</span> <span class="o">=</span> <span class="n">repo</span><span class="o">.</span><span class="n">create_tree_builder_from_tree</span><span class="p">(</span><span class="n">parent_tree</span><span class="p">)</span>
<span class="n">builder</span><span class="o">.</span><span class="n">insert</span><span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="n">blob_id</span><span class="p">,</span> <span class="n">Git</span><span class="o">.</span><span class="n">FileMode</span><span class="o">.</span><span class="n">BLOB</span><span class="p">)</span>
<span class="p">(</span><span class="n">tree</span><span class="p">,</span> <span class="n">sig</span><span class="p">,</span> <span class="n">ref</span><span class="p">)</span> <span class="o">=</span> <span class="n">prepare_commit</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">builder</span><span class="p">)</span>
<span class="n">commit_hash</span> <span class="o">=</span> <span class="n">commit_id</span><span class="o">.</span><span class="n">to_string</span><span class="p">()</span>
<span class="n">message</span> <span class="o">=</span> <span class="s">&quot;Recipe </span><span class="si">%s</span><span class="s"> reverted to commit </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="n">commit_hash</span><span class="p">)</span>
<span class="k">return</span> <span class="n">repo</span><span class="o">.</span><span class="n">create_commit</span><span class="p">(</span><span class="n">ref</span><span class="p">,</span> <span class="n">sig</span><span class="p">,</span> <span class="n">sig</span><span class="p">,</span> <span class="s">&quot;UTF-8&quot;</span><span class="p">,</span> <span class="n">message</span><span class="p">,</span> <span class="n">tree</span><span class="p">,</span> <span class="p">[</span><span class="n">parent_commit</span><span class="p">])</span>
</div>
<div class="viewcode-block" id="commit_recipe"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.commit_recipe">[docs]</a><span class="k">def</span> <span class="nf">commit_recipe</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">recipe</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Commit a recipe to a branch</span>
<span class="sd"> :param repo: Open repository</span>
<span class="sd"> :type repo: Git.Repository</span>
<span class="sd"> :param branch: Branch name</span>
<span class="sd"> :type branch: str</span>
<span class="sd"> :param recipe: Recipe to commit</span>
<span class="sd"> :type recipe: Recipe</span>
<span class="sd"> :returns: OId of the new commit</span>
<span class="sd"> :rtype: Git.OId</span>
<span class="sd"> :raises: Can raise errors from Ggit</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">old_recipe</span> <span class="o">=</span> <span class="n">read_recipe_commit</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">recipe</span><span class="p">[</span><span class="s">&quot;name&quot;</span><span class="p">])</span>
<span class="n">old_version</span> <span class="o">=</span> <span class="n">old_recipe</span><span class="p">[</span><span class="s">&quot;version&quot;</span><span class="p">]</span>
<span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
<span class="n">old_version</span> <span class="o">=</span> <span class="bp">None</span>
<span class="n">recipe</span><span class="o">.</span><span class="n">bump_version</span><span class="p">(</span><span class="n">old_version</span><span class="p">)</span>
<span class="n">recipe_toml</span> <span class="o">=</span> <span class="n">recipe</span><span class="o">.</span><span class="n">toml</span><span class="p">()</span>
<span class="n">message</span> <span class="o">=</span> <span class="s">&quot;Recipe </span><span class="si">%s</span><span class="s">, version </span><span class="si">%s</span><span class="s"> saved.&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">recipe</span><span class="p">[</span><span class="s">&quot;name&quot;</span><span class="p">],</span> <span class="n">recipe</span><span class="p">[</span><span class="s">&quot;version&quot;</span><span class="p">])</span>
<span class="k">return</span> <span class="n">write_commit</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">recipe</span><span class="o">.</span><span class="n">filename</span><span class="p">,</span> <span class="n">message</span><span class="p">,</span> <span class="n">recipe_toml</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="commit_recipe_file"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.commit_recipe_file">[docs]</a><span class="k">def</span> <span class="nf">commit_recipe_file</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">filename</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Commit a recipe file to a branch</span>
<span class="sd"> :param repo: Open repository</span>
<span class="sd"> :type repo: Git.Repository</span>
<span class="sd"> :param branch: Branch name</span>
<span class="sd"> :type branch: str</span>
<span class="sd"> :param filename: Path to the recipe file to commit</span>
<span class="sd"> :type filename: str</span>
<span class="sd"> :returns: OId of the new commit</span>
<span class="sd"> :rtype: Git.OId</span>
<span class="sd"> :raises: Can raise errors from Ggit or RecipeFileError</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">recipe</span> <span class="o">=</span> <span class="n">recipe_from_file</span><span class="p">(</span><span class="n">filename</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">IOError</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">RecipeFileError</span>
<span class="k">return</span> <span class="n">commit_recipe</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">recipe</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="commit_recipe_directory"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.commit_recipe_directory">[docs]</a><span class="k">def</span> <span class="nf">commit_recipe_directory</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">directory</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Commit all *.toml files from a directory, if they aren&#39;t already in git.</span>
<span class="sd"> :param repo: Open repository</span>
<span class="sd"> :type repo: Git.Repository</span>
<span class="sd"> :param branch: Branch name</span>
<span class="sd"> :type branch: str</span>
<span class="sd"> :param directory: The directory of *.toml recipes to commit</span>
<span class="sd"> :type directory: str</span>
<span class="sd"> :returns: None</span>
<span class="sd"> :raises: Can raise errors from Ggit or RecipeFileError</span>
<span class="sd"> Files with Toml or RecipeFileErrors will be skipped, and the remainder will</span>
<span class="sd"> be tried.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">dir_files</span> <span class="o">=</span> <span class="nb">set</span><span class="p">([</span><span class="n">e</span> <span class="k">for</span> <span class="n">e</span> <span class="ow">in</span> <span class="n">os</span><span class="o">.</span><span class="n">listdir</span><span class="p">(</span><span class="n">directory</span><span class="p">)</span> <span class="k">if</span> <span class="n">e</span><span class="o">.</span><span class="n">endswith</span><span class="p">(</span><span class="s">&quot;.toml&quot;</span><span class="p">)])</span>
<span class="n">branch_files</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">list_branch_files</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">))</span>
<span class="n">new_files</span> <span class="o">=</span> <span class="n">dir_files</span><span class="o">.</span><span class="n">difference</span><span class="p">(</span><span class="n">branch_files</span><span class="p">)</span>
<span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">new_files</span><span class="p">:</span>
<span class="c"># Skip files with errors, but try the others</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">commit_recipe_file</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">directory</span><span class="p">,</span> <span class="n">f</span><span class="p">))</span>
<span class="k">except</span> <span class="p">(</span><span class="n">RecipeFileError</span><span class="p">,</span> <span class="n">toml</span><span class="o">.</span><span class="n">TomlError</span><span class="p">):</span>
<span class="k">pass</span>
</div>
<div class="viewcode-block" id="tag_recipe_commit"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.tag_recipe_commit">[docs]</a><span class="k">def</span> <span class="nf">tag_recipe_commit</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">recipe_name</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Tag a file&#39;s most recent commit</span>
<span class="sd"> :param repo: Open repository</span>
<span class="sd"> :type repo: Git.Repository</span>
<span class="sd"> :param branch: Branch name</span>
<span class="sd"> :type branch: str</span>
<span class="sd"> :param recipe_name: Recipe name to tag</span>
<span class="sd"> :type recipe_name: str</span>
<span class="sd"> :returns: Tag id or None if it failed.</span>
<span class="sd"> :rtype: Git.OId</span>
<span class="sd"> :raises: Can raise errors from Ggit</span>
<span class="sd"> Uses tag_file_commit()</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">return</span> <span class="n">tag_file_commit</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">recipe_filename</span><span class="p">(</span><span class="n">recipe_name</span><span class="p">))</span>
</div>
<div class="viewcode-block" id="tag_file_commit"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.tag_file_commit">[docs]</a><span class="k">def</span> <span class="nf">tag_file_commit</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">filename</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Tag a file&#39;s most recent commit</span>
<span class="sd"> :param repo: Open repository</span>
<span class="sd"> :type repo: Git.Repository</span>
<span class="sd"> :param branch: Branch name</span>
<span class="sd"> :type branch: str</span>
<span class="sd"> :param filename: Filename to tag</span>
<span class="sd"> :type filename: str</span>
<span class="sd"> :returns: Tag id or None if it failed.</span>
<span class="sd"> :rtype: Git.OId</span>
<span class="sd"> :raises: Can raise errors from Ggit</span>
<span class="sd"> This uses git tags, of the form `refs/tags/&lt;branch&gt;/&lt;filename&gt;/r&lt;revision&gt;`</span>
<span class="sd"> Only the most recent recipe commit can be tagged to prevent out of order tagging.</span>
<span class="sd"> Revisions start at 1 and increment for each new commit that is tagged.</span>
<span class="sd"> If the commit has already been tagged it will return false.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">file_commits</span> <span class="o">=</span> <span class="n">list_commits</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">filename</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">file_commits</span><span class="p">:</span>
<span class="k">return</span> <span class="bp">None</span>
<span class="c"># Find the most recently tagged version (may not be one) and add 1 to it.</span>
<span class="k">for</span> <span class="n">details</span> <span class="ow">in</span> <span class="n">file_commits</span><span class="p">:</span>
<span class="k">if</span> <span class="n">details</span><span class="o">.</span><span class="n">revision</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span>
<span class="n">new_revision</span> <span class="o">=</span> <span class="n">details</span><span class="o">.</span><span class="n">revision</span> <span class="o">+</span> <span class="mi">1</span>
<span class="k">break</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">new_revision</span> <span class="o">=</span> <span class="mi">1</span>
<span class="n">name</span> <span class="o">=</span> <span class="s">&quot;</span><span class="si">%s</span><span class="s">/</span><span class="si">%s</span><span class="s">/r</span><span class="si">%d</span><span class="s">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">branch</span><span class="p">,</span> <span class="n">filename</span><span class="p">,</span> <span class="n">new_revision</span><span class="p">)</span>
<span class="n">sig</span> <span class="o">=</span> <span class="n">Git</span><span class="o">.</span><span class="n">Signature</span><span class="o">.</span><span class="n">new_now</span><span class="p">(</span><span class="s">&quot;bdcs-api-server&quot;</span><span class="p">,</span> <span class="s">&quot;user-email&quot;</span><span class="p">)</span>
<span class="n">commit_id</span> <span class="o">=</span> <span class="n">Git</span><span class="o">.</span><span class="n">OId</span><span class="o">.</span><span class="n">new_from_string</span><span class="p">(</span><span class="n">file_commits</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">commit</span><span class="p">)</span>
<span class="n">commit</span> <span class="o">=</span> <span class="n">repo</span><span class="o">.</span><span class="n">lookup</span><span class="p">(</span><span class="n">commit_id</span><span class="p">,</span> <span class="n">Git</span><span class="o">.</span><span class="n">Commit</span><span class="p">)</span>
<span class="k">return</span> <span class="n">repo</span><span class="o">.</span><span class="n">create_tag</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">commit</span><span class="p">,</span> <span class="n">sig</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">Git</span><span class="o">.</span><span class="n">CreateFlags</span><span class="o">.</span><span class="n">NONE</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="find_commit_tag"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.find_commit_tag">[docs]</a><span class="k">def</span> <span class="nf">find_commit_tag</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">filename</span><span class="p">,</span> <span class="n">commit_id</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Find the tag that matches the commit_id</span>
<span class="sd"> :param repo: Open repository</span>
<span class="sd"> :type repo: Git.Repository</span>
<span class="sd"> :param branch: Branch name</span>
<span class="sd"> :type branch: str</span>
<span class="sd"> :param filename: filename to revert</span>
<span class="sd"> :type filename: str</span>
<span class="sd"> :param commit_id: The commit id to check</span>
<span class="sd"> :type commit_id: Git.OId</span>
<span class="sd"> :returns: The tag or None if there isn&#39;t one</span>
<span class="sd"> :rtype: str or None</span>
<span class="sd"> There should be only 1 tag pointing to a commit, but there may not</span>
<span class="sd"> be a tag at all.</span>
<span class="sd"> The tag will look like: &#39;refs/tags/&lt;branch&gt;/&lt;filename&gt;/r&lt;revision&gt;&#39;</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">pattern</span> <span class="o">=</span> <span class="s">&quot;</span><span class="si">%s</span><span class="s">/</span><span class="si">%s</span><span class="s">/r*&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">branch</span><span class="p">,</span> <span class="n">filename</span><span class="p">)</span>
<span class="n">tags</span> <span class="o">=</span> <span class="p">[</span><span class="n">t</span> <span class="k">for</span> <span class="n">t</span> <span class="ow">in</span> <span class="n">repo</span><span class="o">.</span><span class="n">list_tags_match</span><span class="p">(</span><span class="n">pattern</span><span class="p">)</span> <span class="k">if</span> <span class="n">is_commit_tag</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">commit_id</span><span class="p">,</span> <span class="n">t</span><span class="p">)]</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">tags</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">1</span><span class="p">:</span>
<span class="k">return</span> <span class="bp">None</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="n">tags</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
</div>
<div class="viewcode-block" id="is_commit_tag"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.is_commit_tag">[docs]</a><span class="k">def</span> <span class="nf">is_commit_tag</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">commit_id</span><span class="p">,</span> <span class="n">tag</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Check to see if a tag points to a specific commit.</span>
<span class="sd"> :param repo: Open repository</span>
<span class="sd"> :type repo: Git.Repository</span>
<span class="sd"> :param commit_id: The commit id to check</span>
<span class="sd"> :type commit_id: Git.OId</span>
<span class="sd"> :param tag: The tag to check</span>
<span class="sd"> :type tag: str</span>
<span class="sd"> :returns: True if the tag points to the commit, False otherwise</span>
<span class="sd"> :rtype: bool</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">ref</span> <span class="o">=</span> <span class="n">repo</span><span class="o">.</span><span class="n">lookup_reference</span><span class="p">(</span><span class="s">&quot;refs/tags/&quot;</span> <span class="o">+</span> <span class="n">tag</span><span class="p">)</span>
<span class="n">tag_id</span> <span class="o">=</span> <span class="n">ref</span><span class="o">.</span><span class="n">get_target</span><span class="p">()</span>
<span class="n">tag</span> <span class="o">=</span> <span class="n">repo</span><span class="o">.</span><span class="n">lookup</span><span class="p">(</span><span class="n">tag_id</span><span class="p">,</span> <span class="n">Git</span><span class="o">.</span><span class="n">Tag</span><span class="p">)</span>
<span class="n">target_id</span> <span class="o">=</span> <span class="n">tag</span><span class="o">.</span><span class="n">get_target_id</span><span class="p">()</span>
<span class="k">return</span> <span class="n">commit_id</span><span class="o">.</span><span class="n">compare</span><span class="p">(</span><span class="n">target_id</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span>
</div>
<div class="viewcode-block" id="get_revision_from_tag"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.get_revision_from_tag">[docs]</a><span class="k">def</span> <span class="nf">get_revision_from_tag</span><span class="p">(</span><span class="n">tag</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return the revision number from a tag</span>
<span class="sd"> :param tag: The tag to exract the revision from</span>
<span class="sd"> :type tag: str</span>
<span class="sd"> :returns: The integer revision or None</span>
<span class="sd"> :rtype: int or None</span>
<span class="sd"> The revision is the part after the r in &#39;branch/filename/rXXX&#39;</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">tag</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span>
<span class="k">return</span> <span class="bp">None</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">return</span> <span class="nb">int</span><span class="p">(</span><span class="n">tag</span><span class="o">.</span><span class="n">rsplit</span><span class="p">(</span><span class="s">&#39;r&#39;</span><span class="p">,</span><span class="mi">2</span><span class="p">)[</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
<span class="k">except</span> <span class="p">(</span><span class="ne">ValueError</span><span class="p">,</span> <span class="ne">IndexError</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">None</span>
</div>
<div class="viewcode-block" id="CommitDetails"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.CommitDetails">[docs]</a><span class="k">class</span> <span class="nc">CommitDetails</span><span class="p">(</span><span class="n">DataHolder</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">commit</span><span class="p">,</span> <span class="n">timestamp</span><span class="p">,</span> <span class="n">message</span><span class="p">,</span> <span class="n">revision</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
<span class="n">DataHolder</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">commit</span> <span class="o">=</span> <span class="n">commit</span><span class="p">,</span>
<span class="n">timestamp</span> <span class="o">=</span> <span class="n">timestamp</span><span class="p">,</span>
<span class="n">message</span> <span class="o">=</span> <span class="n">message</span><span class="p">,</span>
<span class="n">revision</span> <span class="o">=</span> <span class="n">revision</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="list_commits"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.list_commits">[docs]</a><span class="k">def</span> <span class="nf">list_commits</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">filename</span><span class="p">,</span> <span class="n">limit</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;List the commit history of a file on a branch.</span>
<span class="sd"> :param repo: Open repository</span>
<span class="sd"> :type repo: Git.Repository</span>
<span class="sd"> :param branch: Branch name</span>
<span class="sd"> :type branch: str</span>
<span class="sd"> :param filename: filename to revert</span>
<span class="sd"> :type filename: str</span>
<span class="sd"> :param limit: Number of commits to return (0=all)</span>
<span class="sd"> :type limit: int</span>
<span class="sd"> :returns: A list of commit details</span>
<span class="sd"> :rtype: list(CommitDetails)</span>
<span class="sd"> :raises: Can raise errors from Ggit</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">revwalk</span> <span class="o">=</span> <span class="n">Git</span><span class="o">.</span><span class="n">RevisionWalker</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">repo</span><span class="p">)</span>
<span class="n">revwalk</span><span class="o">.</span><span class="n">set_sort_mode</span><span class="p">(</span><span class="n">Git</span><span class="o">.</span><span class="n">SortMode</span><span class="o">.</span><span class="n">TIME</span><span class="p">)</span>
<span class="n">branch_ref</span> <span class="o">=</span> <span class="s">&quot;refs/heads/</span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">branch</span>
<span class="n">revwalk</span><span class="o">.</span><span class="n">push_ref</span><span class="p">(</span><span class="n">branch_ref</span><span class="p">)</span>
<span class="n">commits</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">while</span> <span class="bp">True</span><span class="p">:</span>
<span class="n">commit_id</span> <span class="o">=</span> <span class="n">revwalk</span><span class="o">.</span><span class="n">next</span><span class="p">()</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">commit_id</span><span class="p">:</span>
<span class="k">break</span>
<span class="n">commit</span> <span class="o">=</span> <span class="n">repo</span><span class="o">.</span><span class="n">lookup</span><span class="p">(</span><span class="n">commit_id</span><span class="p">,</span> <span class="n">Git</span><span class="o">.</span><span class="n">Commit</span><span class="p">)</span>
<span class="n">parents</span> <span class="o">=</span> <span class="n">commit</span><span class="o">.</span><span class="n">get_parents</span><span class="p">()</span>
<span class="c"># No parents? Must be the first commit.</span>
<span class="k">if</span> <span class="n">parents</span><span class="o">.</span><span class="n">get_size</span><span class="p">()</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="k">continue</span>
<span class="n">tree</span> <span class="o">=</span> <span class="n">commit</span><span class="o">.</span><span class="n">get_tree</span><span class="p">()</span>
<span class="c"># Is the filename in this tree? If not, move on.</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">tree</span><span class="o">.</span><span class="n">get_by_name</span><span class="p">(</span><span class="n">filename</span><span class="p">):</span>
<span class="k">continue</span>
<span class="c"># Is filename different in all of the parent commits?</span>
<span class="n">parent_commits</span> <span class="o">=</span> <span class="nb">map</span><span class="p">(</span><span class="n">parents</span><span class="o">.</span><span class="n">get</span><span class="p">,</span> <span class="nb">xrange</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">parents</span><span class="o">.</span><span class="n">get_size</span><span class="p">()))</span>
<span class="n">is_diff</span> <span class="o">=</span> <span class="nb">all</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="k">lambda</span> <span class="n">pc</span><span class="p">:</span> <span class="n">is_parent_diff</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">filename</span><span class="p">,</span> <span class="n">tree</span><span class="p">,</span> <span class="n">pc</span><span class="p">),</span> <span class="n">parent_commits</span><span class="p">))</span>
<span class="c"># No changes from parents, skip it.</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">is_diff</span><span class="p">:</span>
<span class="k">continue</span>
<span class="n">tag</span> <span class="o">=</span> <span class="n">find_commit_tag</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">filename</span><span class="p">,</span> <span class="n">commit</span><span class="o">.</span><span class="n">get_id</span><span class="p">())</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">commits</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">get_commit_details</span><span class="p">(</span><span class="n">commit</span><span class="p">,</span> <span class="n">get_revision_from_tag</span><span class="p">(</span><span class="n">tag</span><span class="p">)))</span>
<span class="k">if</span> <span class="n">limit</span> <span class="ow">and</span> <span class="nb">len</span><span class="p">(</span><span class="n">commits</span><span class="p">)</span> <span class="o">&gt;</span> <span class="n">limit</span><span class="p">:</span>
<span class="k">break</span>
<span class="k">except</span> <span class="n">CommitTimeValError</span><span class="p">:</span>
<span class="c"># Skip any commits that have trouble converting the time</span>
<span class="c"># TODO - log details about this failure</span>
<span class="k">pass</span>
<span class="c"># These will be in reverse time sort order thanks to revwalk</span>
<span class="k">return</span> <span class="n">commits</span>
</div>
<div class="viewcode-block" id="get_commit_details"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.get_commit_details">[docs]</a><span class="k">def</span> <span class="nf">get_commit_details</span><span class="p">(</span><span class="n">commit</span><span class="p">,</span> <span class="n">revision</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return the details about a specific commit.</span>
<span class="sd"> :param commit: The commit to get details from</span>
<span class="sd"> :type commit: Git.Commit</span>
<span class="sd"> :param revision: Optional commit revision</span>
<span class="sd"> :type revision: int</span>
<span class="sd"> :returns: Details about the commit</span>
<span class="sd"> :rtype: CommitDetails</span>
<span class="sd"> :raises: CommitTimeValError or Ggit exceptions</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">message</span> <span class="o">=</span> <span class="n">commit</span><span class="o">.</span><span class="n">get_message</span><span class="p">()</span>
<span class="n">commit_str</span> <span class="o">=</span> <span class="n">commit</span><span class="o">.</span><span class="n">get_id</span><span class="p">()</span><span class="o">.</span><span class="n">to_string</span><span class="p">()</span>
<span class="n">sig</span> <span class="o">=</span> <span class="n">commit</span><span class="o">.</span><span class="n">get_committer</span><span class="p">()</span>
<span class="n">datetime</span> <span class="o">=</span> <span class="n">sig</span><span class="o">.</span><span class="n">get_time</span><span class="p">()</span>
<span class="c"># XXX What do we do with timezone?</span>
<span class="n">_timezone</span> <span class="o">=</span> <span class="n">sig</span><span class="o">.</span><span class="n">get_time_zone</span><span class="p">()</span>
<span class="n">timeval</span> <span class="o">=</span> <span class="n">GLib</span><span class="o">.</span><span class="n">TimeVal</span><span class="p">()</span>
<span class="n">ok</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">to_timeval</span><span class="p">(</span><span class="n">timeval</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">ok</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">CommitTimeValError</span>
<span class="n">time_str</span> <span class="o">=</span> <span class="n">timeval</span><span class="o">.</span><span class="n">to_iso8601</span><span class="p">()</span>
<span class="k">return</span> <span class="n">CommitDetails</span><span class="p">(</span><span class="n">commit_str</span><span class="p">,</span> <span class="n">time_str</span><span class="p">,</span> <span class="n">message</span><span class="p">,</span> <span class="n">revision</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="is_parent_diff"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.is_parent_diff">[docs]</a><span class="k">def</span> <span class="nf">is_parent_diff</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">filename</span><span class="p">,</span> <span class="n">tree</span><span class="p">,</span> <span class="n">parent</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Check to see if the commit is different from its parents</span>
<span class="sd"> :param repo: Open repository</span>
<span class="sd"> :type repo: Git.Repository</span>
<span class="sd"> :param filename: filename to revert</span>
<span class="sd"> :type filename: str</span>
<span class="sd"> :param tree: The commit&#39;s tree</span>
<span class="sd"> :type tree: Git.Tree</span>
<span class="sd"> :param parent: The commit&#39;s parent commit</span>
<span class="sd"> :type parent: Git.Commit</span>
<span class="sd"> :retuns: True if filename in the commit is different from its parents</span>
<span class="sd"> :rtype: bool</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">diff_opts</span> <span class="o">=</span> <span class="n">Git</span><span class="o">.</span><span class="n">DiffOptions</span><span class="o">.</span><span class="n">new</span><span class="p">()</span>
<span class="n">diff_opts</span><span class="o">.</span><span class="n">set_pathspec</span><span class="p">([</span><span class="n">filename</span><span class="p">])</span>
<span class="n">diff</span> <span class="o">=</span> <span class="n">Git</span><span class="o">.</span><span class="n">Diff</span><span class="o">.</span><span class="n">new_tree_to_tree</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">parent</span><span class="o">.</span><span class="n">get_tree</span><span class="p">(),</span> <span class="n">tree</span><span class="p">,</span> <span class="n">diff_opts</span><span class="p">)</span>
<span class="k">return</span> <span class="n">diff</span><span class="o">.</span><span class="n">get_num_deltas</span><span class="p">()</span> <span class="o">&gt;</span> <span class="mi">0</span>
</div>
<div class="viewcode-block" id="find_name"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.find_name">[docs]</a><span class="k">def</span> <span class="nf">find_name</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">lst</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Find the dict matching the name in a list and return it.</span>
<span class="sd"> :param name: Name to search for</span>
<span class="sd"> :type name: str</span>
<span class="sd"> :param lst: List of dict&#39;s with &quot;name&quot; field</span>
<span class="sd"> :returns: First dict with matching name, or None</span>
<span class="sd"> :rtype: dict or None</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">for</span> <span class="n">e</span> <span class="ow">in</span> <span class="n">lst</span><span class="p">:</span>
<span class="k">if</span> <span class="n">e</span><span class="p">[</span><span class="s">&quot;name&quot;</span><span class="p">]</span> <span class="o">==</span> <span class="n">name</span><span class="p">:</span>
<span class="k">return</span> <span class="n">e</span>
<span class="k">return</span> <span class="bp">None</span>
</div>
<div class="viewcode-block" id="diff_items"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.diff_items">[docs]</a><span class="k">def</span> <span class="nf">diff_items</span><span class="p">(</span><span class="n">title</span><span class="p">,</span> <span class="n">old_items</span><span class="p">,</span> <span class="n">new_items</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return the differences between two lists of dicts.</span>
<span class="sd"> :param title: Title of the entry</span>
<span class="sd"> :type title: str</span>
<span class="sd"> :param old_items: List of item dicts with &quot;name&quot; field</span>
<span class="sd"> :type old_items: list(dict)</span>
<span class="sd"> :param new_items: List of item dicts with &quot;name&quot; field</span>
<span class="sd"> :type new_items: list(dict)</span>
<span class="sd"> :returns: List of diff dicts with old/new entries</span>
<span class="sd"> :rtype: list(dict)</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">diffs</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">old_names</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">m</span><span class="p">[</span><span class="s">&quot;name&quot;</span><span class="p">]</span> <span class="k">for</span> <span class="n">m</span> <span class="ow">in</span> <span class="n">old_items</span><span class="p">)</span>
<span class="n">new_names</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">m</span><span class="p">[</span><span class="s">&quot;name&quot;</span><span class="p">]</span> <span class="k">for</span> <span class="n">m</span> <span class="ow">in</span> <span class="n">new_items</span><span class="p">)</span>
<span class="n">added_items</span> <span class="o">=</span> <span class="n">new_names</span><span class="o">.</span><span class="n">difference</span><span class="p">(</span><span class="n">old_names</span><span class="p">)</span>
<span class="n">added_items</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">added_items</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">n</span><span class="p">:</span> <span class="n">n</span><span class="o">.</span><span class="n">lower</span><span class="p">())</span>
<span class="n">removed_items</span> <span class="o">=</span> <span class="n">old_names</span><span class="o">.</span><span class="n">difference</span><span class="p">(</span><span class="n">new_names</span><span class="p">)</span>
<span class="n">removed_items</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">removed_items</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">n</span><span class="p">:</span> <span class="n">n</span><span class="o">.</span><span class="n">lower</span><span class="p">())</span>
<span class="n">same_items</span> <span class="o">=</span> <span class="n">old_names</span><span class="o">.</span><span class="n">intersection</span><span class="p">(</span><span class="n">new_names</span><span class="p">)</span>
<span class="n">same_items</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">same_items</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">n</span><span class="p">:</span> <span class="n">n</span><span class="o">.</span><span class="n">lower</span><span class="p">())</span>
<span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">added_items</span><span class="p">:</span>
<span class="n">diffs</span><span class="o">.</span><span class="n">append</span><span class="p">({</span><span class="s">&quot;old&quot;</span><span class="p">:</span><span class="bp">None</span><span class="p">,</span>
<span class="s">&quot;new&quot;</span><span class="p">:{</span><span class="n">title</span><span class="p">:</span><span class="n">find_name</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">new_items</span><span class="p">)}})</span>
<span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">removed_items</span><span class="p">:</span>
<span class="n">diffs</span><span class="o">.</span><span class="n">append</span><span class="p">({</span><span class="s">&quot;old&quot;</span><span class="p">:{</span><span class="n">title</span><span class="p">:</span><span class="n">find_name</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">old_items</span><span class="p">)},</span>
<span class="s">&quot;new&quot;</span><span class="p">:</span><span class="bp">None</span><span class="p">})</span>
<span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">same_items</span><span class="p">:</span>
<span class="n">old_item</span> <span class="o">=</span> <span class="n">find_name</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">old_items</span><span class="p">)</span>
<span class="n">new_item</span> <span class="o">=</span> <span class="n">find_name</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">new_items</span><span class="p">)</span>
<span class="k">if</span> <span class="n">old_item</span> <span class="o">!=</span> <span class="n">new_item</span><span class="p">:</span>
<span class="n">diffs</span><span class="o">.</span><span class="n">append</span><span class="p">({</span><span class="s">&quot;old&quot;</span><span class="p">:{</span><span class="n">title</span><span class="p">:</span><span class="n">old_item</span><span class="p">},</span>
<span class="s">&quot;new&quot;</span><span class="p">:{</span><span class="n">title</span><span class="p">:</span><span class="n">new_item</span><span class="p">}})</span>
<span class="k">return</span> <span class="n">diffs</span>
</div>
<div class="viewcode-block" id="recipe_diff"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.recipe_diff">[docs]</a><span class="k">def</span> <span class="nf">recipe_diff</span><span class="p">(</span><span class="n">old_recipe</span><span class="p">,</span> <span class="n">new_recipe</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Diff two versions of a recipe</span>
<span class="sd"> :param old_recipe: The old version of the recipe</span>
<span class="sd"> :type old_recipe: Recipe</span>
<span class="sd"> :param new_recipe: The new version of the recipe</span>
<span class="sd"> :type new_recipe: Recipe</span>
<span class="sd"> :returns: A list of diff dict entries with old/new</span>
<span class="sd"> :rtype: list(dict)</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">diffs</span> <span class="o">=</span> <span class="p">[]</span>
<span class="c"># These cannot be added or removed, just different</span>
<span class="k">for</span> <span class="n">element</span> <span class="ow">in</span> <span class="p">[</span><span class="s">&quot;name&quot;</span><span class="p">,</span> <span class="s">&quot;description&quot;</span><span class="p">,</span> <span class="s">&quot;version&quot;</span><span class="p">]:</span>
<span class="k">if</span> <span class="n">old_recipe</span><span class="p">[</span><span class="n">element</span><span class="p">]</span> <span class="o">!=</span> <span class="n">new_recipe</span><span class="p">[</span><span class="n">element</span><span class="p">]:</span>
<span class="n">diffs</span><span class="o">.</span><span class="n">append</span><span class="p">({</span><span class="s">&quot;old&quot;</span><span class="p">:{</span><span class="n">element</span><span class="o">.</span><span class="n">title</span><span class="p">():</span><span class="n">old_recipe</span><span class="p">[</span><span class="n">element</span><span class="p">]},</span>
<span class="s">&quot;new&quot;</span><span class="p">:{</span><span class="n">element</span><span class="o">.</span><span class="n">title</span><span class="p">():</span><span class="n">new_recipe</span><span class="p">[</span><span class="n">element</span><span class="p">]}})</span>
<span class="n">diffs</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">diff_items</span><span class="p">(</span><span class="s">&quot;Module&quot;</span><span class="p">,</span> <span class="n">old_recipe</span><span class="p">[</span><span class="s">&quot;modules&quot;</span><span class="p">],</span> <span class="n">new_recipe</span><span class="p">[</span><span class="s">&quot;modules&quot;</span><span class="p">]))</span>
<span class="n">diffs</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">diff_items</span><span class="p">(</span><span class="s">&quot;Package&quot;</span><span class="p">,</span> <span class="n">old_recipe</span><span class="p">[</span><span class="s">&quot;packages&quot;</span><span class="p">],</span> <span class="n">new_recipe</span><span class="p">[</span><span class="s">&quot;packages&quot;</span><span class="p">]))</span>
<span class="k">return</span> <span class="n">diffs</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">Lorax 19.7.10 documentation</a> &raquo;</li>
<li><a href="../../index.html" >Module code</a> &raquo;</li>
<li><a href="../api.html" >pylorax.api</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2017, Red Hat, Inc..
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>

View File

@ -0,0 +1,151 @@
<!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>pylorax.api.server &mdash; Lorax 19.7.10 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: '19.7.10',
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>
<link rel="top" title="Lorax 19.7.10 documentation" href="../../../index.html" />
<link rel="up" title="pylorax.api" href="../api.html" />
</head>
<body>
<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">Lorax 19.7.10 documentation</a> &raquo;</li>
<li><a href="../../index.html" >Module code</a> &raquo;</li>
<li><a href="../api.html" accesskey="U">pylorax.api</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<h1>Source code for pylorax.api.server</h1><div class="highlight"><pre>
<span class="c">#</span>
<span class="c"># Copyright (C) 2017 Red Hat, Inc.</span>
<span class="c">#</span>
<span class="c"># This program is free software; you can redistribute it and/or modify</span>
<span class="c"># it under the terms of the GNU General Public License as published by</span>
<span class="c"># the Free Software Foundation; either version 2 of the License, or</span>
<span class="c"># (at your option) any later version.</span>
<span class="c">#</span>
<span class="c"># This program is distributed in the hope that it will be useful,</span>
<span class="c"># but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<span class="c"># MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span>
<span class="c"># GNU General Public License for more details.</span>
<span class="c">#</span>
<span class="c"># You should have received a copy of the GNU General Public License</span>
<span class="c"># along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;.</span>
<span class="c">#</span>
<span class="kn">import</span> <span class="nn">logging</span>
<span class="n">log</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s">&quot;lorax-composer&quot;</span><span class="p">)</span>
<span class="kn">from</span> <span class="nn">collections</span> <span class="kn">import</span> <span class="n">namedtuple</span>
<span class="kn">from</span> <span class="nn">flask</span> <span class="kn">import</span> <span class="n">Flask</span><span class="p">,</span> <span class="n">send_from_directory</span>
<span class="kn">from</span> <span class="nn">glob</span> <span class="kn">import</span> <span class="n">glob</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">from</span> <span class="nn">pylorax.api.crossdomain</span> <span class="kn">import</span> <span class="n">crossdomain</span>
<span class="kn">from</span> <span class="nn">pylorax.api.v0</span> <span class="kn">import</span> <span class="n">v0_api</span>
<span class="kn">from</span> <span class="nn">pylorax.sysutils</span> <span class="kn">import</span> <span class="n">joinpaths</span>
<span class="n">GitLock</span> <span class="o">=</span> <span class="n">namedtuple</span><span class="p">(</span><span class="s">&quot;GitLock&quot;</span><span class="p">,</span> <span class="p">[</span><span class="s">&quot;repo&quot;</span><span class="p">,</span> <span class="s">&quot;lock&quot;</span><span class="p">,</span> <span class="s">&quot;dir&quot;</span><span class="p">])</span>
<span class="n">YumLock</span> <span class="o">=</span> <span class="n">namedtuple</span><span class="p">(</span><span class="s">&quot;YumLock&quot;</span><span class="p">,</span> <span class="p">[</span><span class="s">&quot;yb&quot;</span><span class="p">,</span> <span class="s">&quot;lock&quot;</span><span class="p">])</span>
<span class="n">server</span> <span class="o">=</span> <span class="n">Flask</span><span class="p">(</span><span class="n">__name__</span><span class="p">)</span>
<span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span><span class="s">&quot;server&quot;</span><span class="p">,</span> <span class="s">&quot;GitLock&quot;</span><span class="p">]</span>
<span class="nd">@server.route</span><span class="p">(</span><span class="s">&#39;/&#39;</span><span class="p">)</span>
<span class="nd">@crossdomain</span><span class="p">(</span><span class="n">origin</span><span class="o">=</span><span class="s">&quot;*&quot;</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">hello_world</span><span class="p">():</span>
<span class="k">return</span> <span class="s">&#39;Hello, World!&#39;</span>
<span class="nd">@server.route</span><span class="p">(</span><span class="s">&quot;/api/docs/&quot;</span><span class="p">)</span>
<span class="nd">@server.route</span><span class="p">(</span><span class="s">&quot;/api/docs/&lt;path:path&gt;&quot;</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">api_docs</span><span class="p">(</span><span class="n">path</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
<span class="c"># Find the html docs</span>
<span class="k">try</span><span class="p">:</span>
<span class="c"># This assumes it is running from the source tree</span>
<span class="n">docs_path</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">abspath</span><span class="p">(</span><span class="n">joinpaths</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">dirname</span><span class="p">(</span><span class="n">__file__</span><span class="p">),</span> <span class="s">&quot;../../../docs/html&quot;</span><span class="p">))</span>
<span class="k">except</span> <span class="ne">IndexError</span><span class="p">:</span>
<span class="n">docs_path</span> <span class="o">=</span> <span class="n">glob</span><span class="p">(</span><span class="s">&quot;/usr/share/doc/lorax-*/html/&quot;</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">path</span><span class="p">:</span>
<span class="n">path</span><span class="o">=</span><span class="s">&quot;index.html&quot;</span>
<span class="k">return</span> <span class="n">send_from_directory</span><span class="p">(</span><span class="n">docs_path</span><span class="p">,</span> <span class="n">path</span><span class="p">)</span>
<span class="n">v0_api</span><span class="p">(</span><span class="n">server</span><span class="p">)</span>
</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">Lorax 19.7.10 documentation</a> &raquo;</li>
<li><a href="../../index.html" >Module code</a> &raquo;</li>
<li><a href="../api.html" >pylorax.api</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2017, Red Hat, Inc..
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,195 @@
<!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>pylorax.api.workspace &mdash; Lorax 19.7.10 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: '19.7.10',
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>
<link rel="top" title="Lorax 19.7.10 documentation" href="../../../index.html" />
<link rel="up" title="pylorax.api" href="../api.html" />
</head>
<body>
<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">Lorax 19.7.10 documentation</a> &raquo;</li>
<li><a href="../../index.html" >Module code</a> &raquo;</li>
<li><a href="../api.html" accesskey="U">pylorax.api</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<h1>Source code for pylorax.api.workspace</h1><div class="highlight"><pre>
<span class="c">#</span>
<span class="c"># Copyright (C) 2017 Red Hat, Inc.</span>
<span class="c">#</span>
<span class="c"># This program is free software; you can redistribute it and/or modify</span>
<span class="c"># it under the terms of the GNU General Public License as published by</span>
<span class="c"># the Free Software Foundation; either version 2 of the License, or</span>
<span class="c"># (at your option) any later version.</span>
<span class="c">#</span>
<span class="c"># This program is distributed in the hope that it will be useful,</span>
<span class="c"># but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<span class="c"># MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span>
<span class="c"># GNU General Public License for more details.</span>
<span class="c">#</span>
<span class="c"># You should have received a copy of the GNU General Public License</span>
<span class="c"># along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;.</span>
<span class="c">#</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">from</span> <span class="nn">pylorax.api.recipes</span> <span class="kn">import</span> <span class="n">recipe_filename</span><span class="p">,</span> <span class="n">recipe_from_toml</span><span class="p">,</span> <span class="n">RecipeFileError</span>
<span class="kn">from</span> <span class="nn">pylorax.sysutils</span> <span class="kn">import</span> <span class="n">joinpaths</span>
<div class="viewcode-block" id="workspace_dir"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.workspace.workspace_dir">[docs]</a><span class="k">def</span> <span class="nf">workspace_dir</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Create the workspace&#39;s path from a Repository and branch</span>
<span class="sd"> :param repo: Open repository</span>
<span class="sd"> :type repo: Git.Repository</span>
<span class="sd"> :param branch: Branch name</span>
<span class="sd"> :type branch: str</span>
<span class="sd"> :returns: The path to the branch&#39;s workspace directory</span>
<span class="sd"> :rtype: str</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">repo_path</span> <span class="o">=</span> <span class="n">repo</span><span class="o">.</span><span class="n">get_location</span><span class="p">()</span><span class="o">.</span><span class="n">get_path</span><span class="p">()</span>
<span class="k">return</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">repo_path</span><span class="p">,</span> <span class="s">&quot;workspace&quot;</span><span class="p">,</span> <span class="n">branch</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="workspace_read"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.workspace.workspace_read">[docs]</a><span class="k">def</span> <span class="nf">workspace_read</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">recipe_name</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Read a Recipe from the branch&#39;s workspace</span>
<span class="sd"> :param repo: Open repository</span>
<span class="sd"> :type repo: Git.Repository</span>
<span class="sd"> :param branch: Branch name</span>
<span class="sd"> :type branch: str</span>
<span class="sd"> :param recipe_name: The name of the recipe</span>
<span class="sd"> :type recipe_name: str</span>
<span class="sd"> :returns: The workspace copy of the recipe, or None if it doesn&#39;t exist</span>
<span class="sd"> :rtype: Recipe or None</span>
<span class="sd"> :raises: RecipeFileError</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">ws_dir</span> <span class="o">=</span> <span class="n">workspace_dir</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</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">isdir</span><span class="p">(</span><span class="n">ws_dir</span><span class="p">):</span>
<span class="n">os</span><span class="o">.</span><span class="n">makedirs</span><span class="p">(</span><span class="n">ws_dir</span><span class="p">)</span>
<span class="n">filename</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">ws_dir</span><span class="p">,</span> <span class="n">recipe_filename</span><span class="p">(</span><span class="n">recipe_name</span><span class="p">))</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">filename</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">None</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">f</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="s">&#39;rb&#39;</span><span class="p">)</span>
<span class="n">recipe</span> <span class="o">=</span> <span class="n">recipe_from_toml</span><span class="p">(</span><span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">())</span>
<span class="k">except</span> <span class="ne">IOError</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">RecipeFileError</span>
<span class="k">return</span> <span class="n">recipe</span>
</div>
<div class="viewcode-block" id="workspace_write"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.workspace.workspace_write">[docs]</a><span class="k">def</span> <span class="nf">workspace_write</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">recipe</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Write a recipe to the workspace</span>
<span class="sd"> :param repo: Open repository</span>
<span class="sd"> :type repo: Git.Repository</span>
<span class="sd"> :param branch: Branch name</span>
<span class="sd"> :type branch: str</span>
<span class="sd"> :param recipe: The recipe to write to the workspace</span>
<span class="sd"> :type recipe: Recipe</span>
<span class="sd"> :returns: None</span>
<span class="sd"> :raises: IO related errors</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">ws_dir</span> <span class="o">=</span> <span class="n">workspace_dir</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</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">isdir</span><span class="p">(</span><span class="n">ws_dir</span><span class="p">):</span>
<span class="n">os</span><span class="o">.</span><span class="n">makedirs</span><span class="p">(</span><span class="n">ws_dir</span><span class="p">)</span>
<span class="n">filename</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">ws_dir</span><span class="p">,</span> <span class="n">recipe</span><span class="o">.</span><span class="n">filename</span><span class="p">)</span>
<span class="nb">open</span><span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="s">&#39;wb&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">recipe</span><span class="o">.</span><span class="n">toml</span><span class="p">())</span>
</div>
<div class="viewcode-block" id="workspace_delete"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.workspace.workspace_delete">[docs]</a><span class="k">def</span> <span class="nf">workspace_delete</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">recipe_name</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Delete the recipe from the workspace</span>
<span class="sd"> :param repo: Open repository</span>
<span class="sd"> :type repo: Git.Repository</span>
<span class="sd"> :param branch: Branch name</span>
<span class="sd"> :type branch: str</span>
<span class="sd"> :param recipe_name: The name of the recipe</span>
<span class="sd"> :type recipe_name: str</span>
<span class="sd"> :returns: None</span>
<span class="sd"> :raises: IO related errors</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">ws_dir</span> <span class="o">=</span> <span class="n">workspace_dir</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">)</span>
<span class="n">filename</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">ws_dir</span><span class="p">,</span> <span class="n">recipe_filename</span><span class="p">(</span><span class="n">recipe_name</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">exists</span><span class="p">(</span><span class="n">filename</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">filename</span><span class="p">)</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">Lorax 19.7.10 documentation</a> &raquo;</li>
<li><a href="../../index.html" >Module code</a> &raquo;</li>
<li><a href="../api.html" >pylorax.api</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2017, Red Hat, Inc..
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>

View File

@ -0,0 +1,201 @@
<!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>pylorax.api.yumbase &mdash; Lorax 19.7.10 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: '19.7.10',
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>
<link rel="top" title="Lorax 19.7.10 documentation" href="../../../index.html" />
<link rel="up" title="pylorax.api" href="../api.html" />
</head>
<body>
<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">Lorax 19.7.10 documentation</a> &raquo;</li>
<li><a href="../../index.html" >Module code</a> &raquo;</li>
<li><a href="../api.html" accesskey="U">pylorax.api</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<h1>Source code for pylorax.api.yumbase</h1><div class="highlight"><pre>
<span class="c">#</span>
<span class="c"># Copyright (C) 2017 Red Hat, Inc.</span>
<span class="c">#</span>
<span class="c"># This program is free software; you can redistribute it and/or modify</span>
<span class="c"># it under the terms of the GNU General Public License as published by</span>
<span class="c"># the Free Software Foundation; either version 2 of the License, or</span>
<span class="c"># (at your option) any later version.</span>
<span class="c">#</span>
<span class="c"># This program is distributed in the hope that it will be useful,</span>
<span class="c"># but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<span class="c"># MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span>
<span class="c"># GNU General Public License for more details.</span>
<span class="c">#</span>
<span class="c"># You should have received a copy of the GNU General Public License</span>
<span class="c"># along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;.</span>
<span class="c">#</span>
<span class="c"># pylint: disable=bad-preconf-access</span>
<span class="kn">import</span> <span class="nn">logging</span>
<span class="n">log</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s">&quot;lorax-composer&quot;</span><span class="p">)</span>
<span class="kn">import</span> <span class="nn">ConfigParser</span>
<span class="kn">from</span> <span class="nn">fnmatch</span> <span class="kn">import</span> <span class="n">fnmatchcase</span>
<span class="kn">from</span> <span class="nn">glob</span> <span class="kn">import</span> <span class="n">glob</span>
<span class="kn">from</span> <span class="nn">distutils.util</span> <span class="kn">import</span> <span class="n">strtobool</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">yum</span>
<span class="c"># This is a hack to short circuit yum&#39;s internal logging</span>
<span class="n">yum</span><span class="o">.</span><span class="n">logginglevels</span><span class="o">.</span><span class="n">_added_handlers</span> <span class="o">=</span> <span class="bp">True</span>
<span class="kn">from</span> <span class="nn">pylorax.sysutils</span> <span class="kn">import</span> <span class="n">joinpaths</span>
<div class="viewcode-block" id="get_base_object"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.yumbase.get_base_object">[docs]</a><span class="k">def</span> <span class="nf">get_base_object</span><span class="p">(</span><span class="n">conf</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Get the Yum object with settings from the config file</span>
<span class="sd"> :param conf: configuration object</span>
<span class="sd"> :type conf: ComposerParser</span>
<span class="sd"> :returns: A Yum base object</span>
<span class="sd"> :rtype: YumBase</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">cachedir</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">abspath</span><span class="p">(</span><span class="n">conf</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">&quot;composer&quot;</span><span class="p">,</span> <span class="s">&quot;cache_dir&quot;</span><span class="p">))</span>
<span class="n">yumconf</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">abspath</span><span class="p">(</span><span class="n">conf</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">&quot;composer&quot;</span><span class="p">,</span> <span class="s">&quot;yum_conf&quot;</span><span class="p">))</span>
<span class="n">repodir</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">abspath</span><span class="p">(</span><span class="n">conf</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">&quot;composer&quot;</span><span class="p">,</span> <span class="s">&quot;repo_dir&quot;</span><span class="p">))</span>
<span class="n">c</span> <span class="o">=</span> <span class="n">ConfigParser</span><span class="o">.</span><span class="n">ConfigParser</span><span class="p">()</span>
<span class="c"># add the main section</span>
<span class="n">section</span> <span class="o">=</span> <span class="s">&quot;main&quot;</span>
<span class="n">data</span> <span class="o">=</span> <span class="p">{</span><span class="s">&quot;cachedir&quot;</span><span class="p">:</span> <span class="n">cachedir</span><span class="p">,</span>
<span class="s">&quot;keepcache&quot;</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span>
<span class="s">&quot;gpgcheck&quot;</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span>
<span class="s">&quot;plugins&quot;</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span>
<span class="s">&quot;assumeyes&quot;</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span>
<span class="s">&quot;reposdir&quot;</span><span class="p">:</span> <span class="s">&quot;&quot;</span><span class="p">,</span>
<span class="s">&quot;tsflags&quot;</span><span class="p">:</span> <span class="s">&quot;nodocs&quot;</span><span class="p">}</span>
<span class="k">if</span> <span class="n">conf</span><span class="o">.</span><span class="n">get_default</span><span class="p">(</span><span class="s">&quot;yum&quot;</span><span class="p">,</span> <span class="s">&quot;proxy&quot;</span><span class="p">,</span> <span class="bp">None</span><span class="p">):</span>
<span class="n">data</span><span class="p">[</span><span class="s">&quot;proxy&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">conf</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">&quot;yum&quot;</span><span class="p">,</span> <span class="s">&quot;proxy&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">conf</span><span class="o">.</span><span class="n">has_option</span><span class="p">(</span><span class="s">&quot;yum&quot;</span><span class="p">,</span> <span class="s">&quot;sslverify&quot;</span><span class="p">)</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">conf</span><span class="o">.</span><span class="n">getboolean</span><span class="p">(</span><span class="s">&quot;yum&quot;</span><span class="p">,</span> <span class="s">&quot;sslverify&quot;</span><span class="p">):</span>
<span class="n">data</span><span class="p">[</span><span class="s">&quot;sslverify&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="s">&quot;0&quot;</span>
<span class="n">c</span><span class="o">.</span><span class="n">add_section</span><span class="p">(</span><span class="n">section</span><span class="p">)</span>
<span class="nb">map</span><span class="p">(</span><span class="k">lambda</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="n">c</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="n">section</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="n">data</span><span class="o">.</span><span class="n">items</span><span class="p">())</span>
<span class="c"># write the yum configuration file</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">yumconf</span><span class="p">,</span> <span class="s">&quot;w&quot;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
<span class="n">c</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
<span class="c"># create the yum base object</span>
<span class="n">yb</span> <span class="o">=</span> <span class="n">yum</span><span class="o">.</span><span class="n">YumBase</span><span class="p">()</span>
<span class="n">yb</span><span class="o">.</span><span class="n">preconf</span><span class="o">.</span><span class="n">fn</span> <span class="o">=</span> <span class="n">yumconf</span>
<span class="c"># TODO How to handle this?</span>
<span class="n">yb</span><span class="o">.</span><span class="n">preconf</span><span class="o">.</span><span class="n">root</span> <span class="o">=</span> <span class="s">&quot;/var/tmp/composer/yum/root&quot;</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">isdir</span><span class="p">(</span><span class="n">yb</span><span class="o">.</span><span class="n">preconf</span><span class="o">.</span><span class="n">root</span><span class="p">):</span>
<span class="n">os</span><span class="o">.</span><span class="n">makedirs</span><span class="p">(</span><span class="n">yb</span><span class="o">.</span><span class="n">preconf</span><span class="o">.</span><span class="n">root</span><span class="p">)</span>
<span class="n">_releasever</span> <span class="o">=</span> <span class="n">conf</span><span class="o">.</span><span class="n">get_default</span><span class="p">(</span><span class="s">&quot;composer&quot;</span><span class="p">,</span> <span class="s">&quot;releasever&quot;</span><span class="p">,</span> <span class="bp">None</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">_releasever</span><span class="p">:</span>
<span class="n">distroverpkg</span> <span class="o">=</span> <span class="p">[</span><span class="s">&#39;system-release(releasever)&#39;</span><span class="p">,</span> <span class="s">&#39;redhat-release&#39;</span><span class="p">]</span>
<span class="c"># Use yum private function to guess the releasever</span>
<span class="n">_releasever</span> <span class="o">=</span> <span class="n">yum</span><span class="o">.</span><span class="n">config</span><span class="o">.</span><span class="n">_getsysver</span><span class="p">(</span><span class="s">&quot;/&quot;</span><span class="p">,</span> <span class="n">distroverpkg</span><span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;releasever = </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">_releasever</span><span class="p">)</span>
<span class="n">yb</span><span class="o">.</span><span class="n">preconf</span><span class="o">.</span><span class="n">releasever</span> <span class="o">=</span> <span class="n">_releasever</span>
<span class="c"># Turn on as much yum logging as we can</span>
<span class="n">yb</span><span class="o">.</span><span class="n">preconf</span><span class="o">.</span><span class="n">debuglevel</span> <span class="o">=</span> <span class="mi">6</span>
<span class="n">yb</span><span class="o">.</span><span class="n">preconf</span><span class="o">.</span><span class="n">errorlevel</span> <span class="o">=</span> <span class="mi">6</span>
<span class="n">yb</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">setLevel</span><span class="p">(</span><span class="n">logging</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">)</span>
<span class="n">yb</span><span class="o">.</span><span class="n">verbose_logger</span><span class="o">.</span><span class="n">setLevel</span><span class="p">(</span><span class="n">logging</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">)</span>
<span class="c"># Gather up all the available repo files, add the ones matching &quot;repos&quot;:&quot;enabled&quot; patterns</span>
<span class="n">enabled_repos</span> <span class="o">=</span> <span class="n">conf</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">&quot;repos&quot;</span><span class="p">,</span> <span class="s">&quot;enabled&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">&quot;,&quot;</span><span class="p">)</span>
<span class="n">repo_files</span> <span class="o">=</span> <span class="n">glob</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">repodir</span><span class="p">,</span> <span class="s">&quot;*.repo&quot;</span><span class="p">))</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">conf</span><span class="o">.</span><span class="n">has_option</span><span class="p">(</span><span class="s">&quot;repos&quot;</span><span class="p">,</span> <span class="s">&quot;use_system_repos&quot;</span><span class="p">)</span> <span class="ow">or</span> <span class="n">conf</span><span class="o">.</span><span class="n">getboolean</span><span class="p">(</span><span class="s">&quot;repos&quot;</span><span class="p">,</span> <span class="s">&quot;use_system_repos&quot;</span><span class="p">):</span>
<span class="n">repo_files</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">glob</span><span class="p">(</span><span class="s">&quot;/etc/yum.repos.d/*.repo&quot;</span><span class="p">))</span>
<span class="k">for</span> <span class="n">repo_file</span> <span class="ow">in</span> <span class="n">repo_files</span><span class="p">:</span>
<span class="n">name</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">basename</span><span class="p">(</span><span class="n">repo_file</span><span class="p">)[:</span><span class="o">-</span><span class="mi">5</span><span class="p">]</span>
<span class="k">if</span> <span class="nb">any</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="k">lambda</span> <span class="n">pattern</span><span class="p">:</span> <span class="n">fnmatchcase</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">pattern</span><span class="p">),</span> <span class="n">enabled_repos</span><span class="p">)):</span> <span class="c"># pylint: disable=cell-var-from-loop</span>
<span class="n">yb</span><span class="o">.</span><span class="n">getReposFromConfigFile</span><span class="p">(</span><span class="n">repo_file</span><span class="p">)</span>
<span class="k">return</span> <span class="n">yb</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">Lorax 19.7.10 documentation</a> &raquo;</li>
<li><a href="../../index.html" >Module code</a> &raquo;</li>
<li><a href="../api.html" >pylorax.api</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2017, Red Hat, Inc..
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>

View File

@ -0,0 +1,161 @@
<!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>pylorax.base &mdash; Lorax 19.7.10 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: '19.7.10',
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>
<link rel="top" title="Lorax 19.7.10 documentation" href="../../index.html" />
<link rel="up" title="Module code" href="../index.html" />
</head>
<body>
<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">Lorax 19.7.10 documentation</a> &raquo;</li>
<li><a href="../index.html" accesskey="U">Module code</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<h1>Source code for pylorax.base</h1><div class="highlight"><pre>
<span class="c">#</span>
<span class="c"># base.py</span>
<span class="c">#</span>
<span class="c"># Copyright (C) 2009 Red Hat, Inc.</span>
<span class="c">#</span>
<span class="c"># This program is free software; you can redistribute it and/or modify</span>
<span class="c"># it under the terms of the GNU General Public License as published by</span>
<span class="c"># the Free Software Foundation; either version 2 of the License, or</span>
<span class="c"># (at your option) any later version.</span>
<span class="c">#</span>
<span class="c"># This program is distributed in the hope that it will be useful,</span>
<span class="c"># but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<span class="c"># MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span>
<span class="c"># GNU General Public License for more details.</span>
<span class="c">#</span>
<span class="c"># You should have received a copy of the GNU General Public License</span>
<span class="c"># along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;.</span>
<span class="c">#</span>
<span class="c"># Red Hat Author(s): Martin Gracik &lt;mgracik@redhat.com&gt;</span>
<span class="c">#</span>
<span class="kn">from</span> <span class="nn">abc</span> <span class="kn">import</span> <span class="n">ABCMeta</span><span class="p">,</span> <span class="n">abstractmethod</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">import</span> <span class="nn">pylorax.output</span> <span class="kn">as</span> <span class="nn">output</span>
<div class="viewcode-block" id="BaseLoraxClass"><a class="viewcode-back" href="../../pylorax.html#pylorax.base.BaseLoraxClass">[docs]</a><span class="k">class</span> <span class="nc">BaseLoraxClass</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="n">__metaclass__</span> <span class="o">=</span> <span class="n">ABCMeta</span>
<span class="nd">@abstractmethod</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="bp">self</span><span class="o">.</span><span class="n">output</span> <span class="o">=</span> <span class="n">output</span><span class="o">.</span><span class="n">LoraxOutput</span><span class="p">()</span>
<div class="viewcode-block" id="BaseLoraxClass.pcritical"><a class="viewcode-back" href="../../pylorax.html#pylorax.base.BaseLoraxClass.pcritical">[docs]</a> <span class="k">def</span> <span class="nf">pcritical</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="n">fobj</span><span class="o">=</span><span class="n">sys</span><span class="o">.</span><span class="n">stdout</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">output</span><span class="o">.</span><span class="n">critical</span><span class="p">(</span><span class="n">msg</span><span class="p">,</span> <span class="n">fobj</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="BaseLoraxClass.perror"><a class="viewcode-back" href="../../pylorax.html#pylorax.base.BaseLoraxClass.perror">[docs]</a> <span class="k">def</span> <span class="nf">perror</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="n">fobj</span><span class="o">=</span><span class="n">sys</span><span class="o">.</span><span class="n">stdout</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">output</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="n">msg</span><span class="p">,</span> <span class="n">fobj</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="BaseLoraxClass.pwarning"><a class="viewcode-back" href="../../pylorax.html#pylorax.base.BaseLoraxClass.pwarning">[docs]</a> <span class="k">def</span> <span class="nf">pwarning</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="n">fobj</span><span class="o">=</span><span class="n">sys</span><span class="o">.</span><span class="n">stdout</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">output</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="n">msg</span><span class="p">,</span> <span class="n">fobj</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="BaseLoraxClass.pinfo"><a class="viewcode-back" href="../../pylorax.html#pylorax.base.BaseLoraxClass.pinfo">[docs]</a> <span class="k">def</span> <span class="nf">pinfo</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="n">fobj</span><span class="o">=</span><span class="n">sys</span><span class="o">.</span><span class="n">stdout</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">output</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="n">msg</span><span class="p">,</span> <span class="n">fobj</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="BaseLoraxClass.pdebug"><a class="viewcode-back" href="../../pylorax.html#pylorax.base.BaseLoraxClass.pdebug">[docs]</a> <span class="k">def</span> <span class="nf">pdebug</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="n">fobj</span><span class="o">=</span><span class="n">sys</span><span class="o">.</span><span class="n">stdout</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">output</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">msg</span><span class="p">,</span> <span class="n">fobj</span><span class="p">)</span>
</div></div>
<div class="viewcode-block" id="DataHolder"><a class="viewcode-back" href="../../pylorax.html#pylorax.base.DataHolder">[docs]</a><span class="k">class</span> <span class="nc">DataHolder</span><span class="p">(</span><span class="nb">dict</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="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="nb">dict</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="k">for</span> <span class="n">attr</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
<span class="bp">self</span><span class="p">[</span><span class="n">attr</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span>
<span class="k">def</span> <span class="nf">__getattr__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">attr</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">self</span><span class="p">[</span><span class="n">attr</span><span class="p">]</span>
<span class="k">def</span> <span class="nf">__setattr__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">attr</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
<span class="bp">self</span><span class="p">[</span><span class="n">attr</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span>
<div class="viewcode-block" id="DataHolder.copy"><a class="viewcode-back" href="../../pylorax.html#pylorax.base.DataHolder.copy">[docs]</a> <span class="k">def</span> <span class="nf">copy</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="n">DataHolder</span><span class="p">(</span><span class="o">**</span><span class="nb">dict</span><span class="o">.</span><span class="n">copy</span><span class="p">(</span><span class="bp">self</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">Lorax 19.7.10 documentation</a> &raquo;</li>
<li><a href="../index.html" >Module code</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2017, Red Hat, Inc..
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>

View File

@ -0,0 +1,152 @@
<!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>pylorax.buildstamp &mdash; Lorax 19.7.10 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: '19.7.10',
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>
<link rel="top" title="Lorax 19.7.10 documentation" href="../../index.html" />
<link rel="up" title="Module code" href="../index.html" />
</head>
<body>
<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">Lorax 19.7.10 documentation</a> &raquo;</li>
<li><a href="../index.html" accesskey="U">Module code</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<h1>Source code for pylorax.buildstamp</h1><div class="highlight"><pre>
<span class="c">#</span>
<span class="c"># buildstamp.py</span>
<span class="c">#</span>
<span class="c"># Copyright (C) 2010 Red Hat, Inc.</span>
<span class="c">#</span>
<span class="c"># This program is free software; you can redistribute it and/or modify</span>
<span class="c"># it under the terms of the GNU General Public License as published by</span>
<span class="c"># the Free Software Foundation; either version 2 of the License, or</span>
<span class="c"># (at your option) any later version.</span>
<span class="c">#</span>
<span class="c"># This program is distributed in the hope that it will be useful,</span>
<span class="c"># but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<span class="c"># MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span>
<span class="c"># GNU General Public License for more details.</span>
<span class="c">#</span>
<span class="c"># You should have received a copy of the GNU General Public License</span>
<span class="c"># along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;.</span>
<span class="c">#</span>
<span class="c"># Red Hat Author(s): Martin Gracik &lt;mgracik@redhat.com&gt;</span>
<span class="c">#</span>
<span class="kn">import</span> <span class="nn">logging</span>
<span class="n">logger</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s">&quot;pylorax.buildstamp&quot;</span><span class="p">)</span>
<span class="kn">import</span> <span class="nn">datetime</span>
<div class="viewcode-block" id="BuildStamp"><a class="viewcode-back" href="../../pylorax.html#pylorax.buildstamp.BuildStamp">[docs]</a><span class="k">class</span> <span class="nc">BuildStamp</span><span class="p">(</span><span class="nb">object</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">product</span><span class="p">,</span> <span class="n">version</span><span class="p">,</span> <span class="n">bugurl</span><span class="p">,</span> <span class="n">isfinal</span><span class="p">,</span> <span class="n">buildarch</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">product</span> <span class="o">=</span> <span class="n">product</span>
<span class="bp">self</span><span class="o">.</span><span class="n">version</span> <span class="o">=</span> <span class="n">version</span>
<span class="bp">self</span><span class="o">.</span><span class="n">bugurl</span> <span class="o">=</span> <span class="n">bugurl</span>
<span class="bp">self</span><span class="o">.</span><span class="n">isfinal</span> <span class="o">=</span> <span class="n">isfinal</span>
<span class="n">now</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">()</span>
<span class="n">now</span> <span class="o">=</span> <span class="n">now</span><span class="o">.</span><span class="n">strftime</span><span class="p">(</span><span class="s">&quot;%Y%m</span><span class="si">%d</span><span class="s">%H%M&quot;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">uuid</span> <span class="o">=</span> <span class="s">&quot;{0}.{1}&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">now</span><span class="p">,</span> <span class="n">buildarch</span><span class="p">)</span>
<div class="viewcode-block" id="BuildStamp.write"><a class="viewcode-back" href="../../pylorax.html#pylorax.buildstamp.BuildStamp.write">[docs]</a> <span class="k">def</span> <span class="nf">write</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">outfile</span><span class="p">):</span>
<span class="c"># get lorax version</span>
<span class="k">try</span><span class="p">:</span>
<span class="kn">import</span> <span class="nn">pylorax.version</span>
<span class="k">except</span> <span class="ne">ImportError</span><span class="p">:</span>
<span class="n">vernum</span> <span class="o">=</span> <span class="s">&quot;devel&quot;</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">vernum</span> <span class="o">=</span> <span class="n">pylorax</span><span class="o">.</span><span class="n">version</span><span class="o">.</span><span class="n">num</span>
<span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;writing .buildstamp file&quot;</span><span class="p">)</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">outfile</span><span class="p">,</span> <span class="s">&quot;w&quot;</span><span class="p">)</span> <span class="k">as</span> <span class="n">fobj</span><span class="p">:</span>
<span class="n">fobj</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">&quot;[Main]</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">)</span>
<span class="n">fobj</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">&quot;Product={0.product}</span><span class="se">\n</span><span class="s">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="p">))</span>
<span class="n">fobj</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">&quot;Version={0.version}</span><span class="se">\n</span><span class="s">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="p">))</span>
<span class="n">fobj</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">&quot;BugURL={0.bugurl}</span><span class="se">\n</span><span class="s">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="p">))</span>
<span class="n">fobj</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">&quot;IsFinal={0.isfinal}</span><span class="se">\n</span><span class="s">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="p">))</span>
<span class="n">fobj</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">&quot;UUID={0.uuid}</span><span class="se">\n</span><span class="s">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="p">))</span>
<span class="n">fobj</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">&quot;[Compose]</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">)</span>
<span class="n">fobj</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">&quot;Lorax={0}</span><span class="se">\n</span><span class="s">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">vernum</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">Lorax 19.7.10 documentation</a> &raquo;</li>
<li><a href="../index.html" >Module code</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2017, Red Hat, Inc..
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>

View File

@ -0,0 +1,707 @@
<!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>pylorax.creator &mdash; Lorax 19.7.10 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: '19.7.10',
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>
<link rel="top" title="Lorax 19.7.10 documentation" href="../../index.html" />
<link rel="up" title="Module code" href="../index.html" />
</head>
<body>
<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">Lorax 19.7.10 documentation</a> &raquo;</li>
<li><a href="../index.html" accesskey="U">Module code</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<h1>Source code for pylorax.creator</h1><div class="highlight"><pre>
<span class="c">#</span>
<span class="c"># Copyright (C) 2011-2017 Red Hat, Inc.</span>
<span class="c">#</span>
<span class="c"># This program is free software; you can redistribute it and/or modify</span>
<span class="c"># it under the terms of the GNU General Public License as published by</span>
<span class="c"># the Free Software Foundation; either version 2 of the License, or</span>
<span class="c"># (at your option) any later version.</span>
<span class="c">#</span>
<span class="c"># This program is distributed in the hope that it will be useful,</span>
<span class="c"># but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<span class="c"># MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span>
<span class="c"># GNU General Public License for more details.</span>
<span class="c">#</span>
<span class="c"># You should have received a copy of the GNU General Public License</span>
<span class="c"># along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;.</span>
<span class="c">#</span>
<span class="kn">import</span> <span class="nn">logging</span>
<span class="n">log</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s">&quot;pylorax&quot;</span><span class="p">)</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">tempfile</span>
<span class="kn">import</span> <span class="nn">subprocess</span>
<span class="kn">import</span> <span class="nn">shutil</span>
<span class="kn">import</span> <span class="nn">hashlib</span>
<span class="kn">import</span> <span class="nn">glob</span>
<span class="c"># Use Mako templates for appliance builder descriptions</span>
<span class="kn">from</span> <span class="nn">mako.template</span> <span class="kn">import</span> <span class="n">Template</span>
<span class="kn">from</span> <span class="nn">mako.exceptions</span> <span class="kn">import</span> <span class="n">text_error_template</span>
<span class="c"># Use pykickstart to calculate disk image size</span>
<span class="kn">from</span> <span class="nn">pykickstart.parser</span> <span class="kn">import</span> <span class="n">KickstartParser</span>
<span class="kn">from</span> <span class="nn">pykickstart.version</span> <span class="kn">import</span> <span class="n">makeVersion</span><span class="p">,</span> <span class="n">RHEL7</span>
<span class="c"># Use the Lorax treebuilder branch for iso creation</span>
<span class="kn">from</span> <span class="nn">pylorax</span> <span class="kn">import</span> <span class="n">ArchData</span>
<span class="kn">from</span> <span class="nn">pylorax.base</span> <span class="kn">import</span> <span class="n">DataHolder</span>
<span class="kn">from</span> <span class="nn">pylorax.treebuilder</span> <span class="kn">import</span> <span class="n">TreeBuilder</span><span class="p">,</span> <span class="n">RuntimeBuilder</span>
<span class="kn">from</span> <span class="nn">pylorax.treebuilder</span> <span class="kn">import</span> <span class="n">findkernels</span>
<span class="kn">from</span> <span class="nn">pylorax.sysutils</span> <span class="kn">import</span> <span class="n">joinpaths</span><span class="p">,</span> <span class="n">remove</span>
<span class="kn">from</span> <span class="nn">pylorax.imgutils</span> <span class="kn">import</span> <span class="n">Mount</span><span class="p">,</span> <span class="n">PartitionMount</span><span class="p">,</span> <span class="n">copytree</span><span class="p">,</span> <span class="n">mount</span><span class="p">,</span> <span class="n">umount</span>
<span class="kn">from</span> <span class="nn">pylorax.imgutils</span> <span class="kn">import</span> <span class="n">mksquashfs</span><span class="p">,</span> <span class="n">mkrootfsimg</span>
<span class="kn">from</span> <span class="nn">pylorax.executils</span> <span class="kn">import</span> <span class="n">execWithRedirect</span><span class="p">,</span> <span class="n">runcmd</span>
<span class="kn">from</span> <span class="nn">pylorax.installer</span> <span class="kn">import</span> <span class="n">InstallError</span><span class="p">,</span> <span class="n">novirt_install</span><span class="p">,</span> <span class="n">virt_install</span>
<span class="n">RUNTIME</span> <span class="o">=</span> <span class="s">&quot;images/install.img&quot;</span>
<span class="c"># Default parameters for rebuilding initramfs, override with --dracut-args</span>
<span class="n">DRACUT_DEFAULT</span> <span class="o">=</span> <span class="p">[</span><span class="s">&quot;--xz&quot;</span><span class="p">,</span> <span class="s">&quot;--add&quot;</span><span class="p">,</span> <span class="s">&quot;livenet dmsquash-live convertfs pollcdrom&quot;</span><span class="p">,</span>
<span class="s">&quot;--omit&quot;</span><span class="p">,</span> <span class="s">&quot;plymouth&quot;</span><span class="p">,</span> <span class="s">&quot;--no-hostonly&quot;</span><span class="p">,</span> <span class="s">&quot;--no-early-microcode&quot;</span><span class="p">]</span>
<div class="viewcode-block" id="get_ks_disk_size"><a class="viewcode-back" href="../../pylorax.html#pylorax.creator.get_ks_disk_size">[docs]</a><span class="k">def</span> <span class="nf">get_ks_disk_size</span><span class="p">(</span><span class="n">ks</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return the size of the kickstart&#39;s disk partitions</span>
<span class="sd"> :param ks: The kickstart</span>
<span class="sd"> :type ks: Kickstart object</span>
<span class="sd"> :returns: The size of the disk, in GiB</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">disk_size</span> <span class="o">=</span> <span class="mi">1</span> <span class="o">+</span> <span class="p">(</span><span class="nb">sum</span><span class="p">([</span><span class="n">p</span><span class="o">.</span><span class="n">size</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">ks</span><span class="o">.</span><span class="n">handler</span><span class="o">.</span><span class="n">partition</span><span class="o">.</span><span class="n">partitions</span><span class="p">])</span> <span class="o">/</span> <span class="mi">1024</span><span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;disk_size = </span><span class="si">%s</span><span class="s">GiB&quot;</span><span class="p">,</span> <span class="n">disk_size</span><span class="p">)</span>
<span class="k">return</span> <span class="n">disk_size</span>
</div>
<div class="viewcode-block" id="is_image_mounted"><a class="viewcode-back" href="../../pylorax.html#pylorax.creator.is_image_mounted">[docs]</a><span class="k">def</span> <span class="nf">is_image_mounted</span><span class="p">(</span><span class="n">disk_img</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Return True if the disk_img is mounted</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s">&quot;/proc/mounts&quot;</span><span class="p">)</span> <span class="k">as</span> <span class="n">mounts</span><span class="p">:</span>
<span class="k">for</span> <span class="n">_mount</span> <span class="ow">in</span> <span class="n">mounts</span><span class="p">:</span>
<span class="n">fields</span> <span class="o">=</span> <span class="n">_mount</span><span class="o">.</span><span class="n">split</span><span class="p">()</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">fields</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">2</span> <span class="ow">and</span> <span class="n">fields</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="n">disk_img</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>
<div class="viewcode-block" id="find_ostree_root"><a class="viewcode-back" href="../../pylorax.html#pylorax.creator.find_ostree_root">[docs]</a><span class="k">def</span> <span class="nf">find_ostree_root</span><span class="p">(</span><span class="n">phys_root</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Find root of ostree deployment</span>
<span class="sd"> :param str phys_root: Path to physical root</span>
<span class="sd"> :returns: Relative path of ostree deployment root</span>
<span class="sd"> :rtype: str</span>
<span class="sd"> :raise Exception: More than one deployment roots were found</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">ostree_root</span> <span class="o">=</span> <span class="s">&quot;&quot;</span>
<span class="n">ostree_sysroots</span> <span class="o">=</span> <span class="n">glob</span><span class="o">.</span><span class="n">glob</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">phys_root</span><span class="p">,</span> <span class="s">&quot;ostree/boot.0/*/*/0&quot;</span><span class="p">))</span>
<span class="k">if</span> <span class="n">ostree_sysroots</span><span class="p">:</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">ostree_sysroots</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="s">&quot;Too many deployment roots found: </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">ostree_sysroots</span><span class="p">)</span>
<span class="n">ostree_root</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">relpath</span><span class="p">(</span><span class="n">ostree_sysroots</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">phys_root</span><span class="p">)</span>
<span class="k">return</span> <span class="n">ostree_root</span>
</div>
<div class="viewcode-block" id="KernelInfo"><a class="viewcode-back" href="../../pylorax.html#pylorax.creator.KernelInfo">[docs]</a><span class="k">class</span> <span class="nc">KernelInfo</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Info about the kernels in boot_dir</span>
<span class="sd"> &quot;&quot;&quot;</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">boot_dir</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">boot_dir</span> <span class="o">=</span> <span class="n">boot_dir</span>
<span class="bp">self</span><span class="o">.</span><span class="n">list</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_kernels</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">arch</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_kernel_arch</span><span class="p">()</span>
<span class="n">log</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">&quot;kernel_list for </span><span class="si">%s</span><span class="s"> = </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">boot_dir</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">list</span><span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">&quot;kernel_arch is </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">arch</span><span class="p">)</span>
<div class="viewcode-block" id="KernelInfo.get_kernels"><a class="viewcode-back" href="../../pylorax.html#pylorax.creator.KernelInfo.get_kernels">[docs]</a> <span class="k">def</span> <span class="nf">get_kernels</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Get a list of the kernels in the boot_dir</span>
<span class="sd"> Examine the vmlinuz-* versions and return a list of them</span>
<span class="sd"> Ignore any with -rescue- in them, these are dracut rescue images.</span>
<span class="sd"> The user shoud add</span>
<span class="sd"> -dracut-config-rescue</span>
<span class="sd"> to the kickstart to remove them, but catch it here as well.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">files</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">listdir</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">boot_dir</span><span class="p">)</span>
<span class="k">return</span> <span class="p">[</span><span class="n">f</span><span class="p">[</span><span class="mi">8</span><span class="p">:]</span> <span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">files</span> <span class="k">if</span> <span class="n">f</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s">&quot;vmlinuz-&quot;</span><span class="p">)</span> \
<span class="ow">and</span> <span class="n">f</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="s">&quot;-rescue-&quot;</span><span class="p">)</span> <span class="o">==</span> <span class="o">-</span><span class="mi">1</span><span class="p">]</span>
</div>
<div class="viewcode-block" id="KernelInfo.get_kernel_arch"><a class="viewcode-back" href="../../pylorax.html#pylorax.creator.KernelInfo.get_kernel_arch">[docs]</a> <span class="k">def</span> <span class="nf">get_kernel_arch</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Get the arch of the first kernel in boot_dir</span>
<span class="sd"> Defaults to i386</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">list</span><span class="p">:</span>
<span class="n">kernel_arch</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">list</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">&quot;.&quot;</span><span class="p">)[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">kernel_arch</span> <span class="o">=</span> <span class="s">&quot;i386&quot;</span>
<span class="k">return</span> <span class="n">kernel_arch</span>
</div></div>
<div class="viewcode-block" id="make_appliance"><a class="viewcode-back" href="../../pylorax.html#pylorax.creator.make_appliance">[docs]</a><span class="k">def</span> <span class="nf">make_appliance</span><span class="p">(</span><span class="n">disk_img</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">template</span><span class="p">,</span> <span class="n">outfile</span><span class="p">,</span> <span class="n">networks</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">ram</span><span class="o">=</span><span class="mi">1024</span><span class="p">,</span>
<span class="n">vcpus</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">arch</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">title</span><span class="o">=</span><span class="s">&quot;Linux&quot;</span><span class="p">,</span> <span class="n">project</span><span class="o">=</span><span class="s">&quot;Linux&quot;</span><span class="p">,</span>
<span class="n">releasever</span><span class="o">=</span><span class="s">&quot;7&quot;</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Generate an appliance description file</span>
<span class="sd"> disk_img Full path of the disk image</span>
<span class="sd"> name Name of the appliance, passed to the template</span>
<span class="sd"> template Full path of Mako template</span>
<span class="sd"> outfile Full path of file to write, using template</span>
<span class="sd"> networks List of networks from the kickstart</span>
<span class="sd"> ram Ram, in MB, passed to template. Default is 1024</span>
<span class="sd"> vcpus CPUs, passed to template. Default is 1</span>
<span class="sd"> arch CPU architecture. Default is &#39;x86_64&#39;</span>
<span class="sd"> title Title, passed to template. Default is &#39;Linux&#39;</span>
<span class="sd"> project Project, passed to template. Default is &#39;Linux&#39;</span>
<span class="sd"> releasever Release version, passed to template. Default is 17</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="ow">not</span> <span class="p">(</span><span class="n">disk_img</span> <span class="ow">and</span> <span class="n">template</span> <span class="ow">and</span> <span class="n">outfile</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">None</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;Creating appliance definition using </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">template</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">arch</span><span class="p">:</span>
<span class="n">arch</span> <span class="o">=</span> <span class="s">&quot;x86_64&quot;</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;Calculating SHA256 checksum of </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">disk_img</span><span class="p">)</span>
<span class="n">sha256</span> <span class="o">=</span> <span class="n">hashlib</span><span class="o">.</span><span class="n">sha256</span><span class="p">()</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">disk_img</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
<span class="k">while</span> <span class="bp">True</span><span class="p">:</span>
<span class="n">data</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mi">1024</span><span class="o">*</span><span class="mi">1024</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">data</span><span class="p">:</span>
<span class="k">break</span>
<span class="n">sha256</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;SHA256 of </span><span class="si">%s</span><span class="s"> is </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">disk_img</span><span class="p">,</span> <span class="n">sha256</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">())</span>
<span class="n">disk_info</span> <span class="o">=</span> <span class="n">DataHolder</span><span class="p">(</span><span class="n">name</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">basename</span><span class="p">(</span><span class="n">disk_img</span><span class="p">),</span> <span class="n">format</span><span class="o">=</span><span class="s">&quot;raw&quot;</span><span class="p">,</span>
<span class="n">checksum_type</span><span class="o">=</span><span class="s">&quot;sha256&quot;</span><span class="p">,</span> <span class="n">checksum</span><span class="o">=</span><span class="n">sha256</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">())</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">result</span> <span class="o">=</span> <span class="n">Template</span><span class="p">(</span><span class="n">filename</span><span class="o">=</span><span class="n">template</span><span class="p">)</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="n">disks</span><span class="o">=</span><span class="p">[</span><span class="n">disk_info</span><span class="p">],</span> <span class="n">name</span><span class="o">=</span><span class="n">name</span><span class="p">,</span>
<span class="n">arch</span><span class="o">=</span><span class="n">arch</span><span class="p">,</span> <span class="n">memory</span><span class="o">=</span><span class="n">ram</span><span class="p">,</span> <span class="n">vcpus</span><span class="o">=</span><span class="n">vcpus</span><span class="p">,</span> <span class="n">networks</span><span class="o">=</span><span class="n">networks</span><span class="p">,</span>
<span class="n">title</span><span class="o">=</span><span class="n">title</span><span class="p">,</span> <span class="n">project</span><span class="o">=</span><span class="n">project</span><span class="p">,</span> <span class="n">releasever</span><span class="o">=</span><span class="n">releasever</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
<span class="n">log</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="n">text_error_template</span><span class="p">()</span><span class="o">.</span><span class="n">render</span><span class="p">())</span>
<span class="k">raise</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">outfile</span><span class="p">,</span> <span class="s">&quot;w&quot;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">result</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="make_runtime"><a class="viewcode-back" href="../../pylorax.html#pylorax.creator.make_runtime">[docs]</a><span class="k">def</span> <span class="nf">make_runtime</span><span class="p">(</span><span class="n">opts</span><span class="p">,</span> <span class="n">mount_dir</span><span class="p">,</span> <span class="n">work_dir</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Make the squashfs image from a directory</span>
<span class="sd"> Result is in work_dir+RUNTIME</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">kernels</span> <span class="o">=</span> <span class="n">KernelInfo</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">mount_dir</span><span class="p">,</span> <span class="s">&quot;boot&quot;</span> <span class="p">))</span>
<span class="c"># Fake yum object</span>
<span class="n">fake_yum</span> <span class="o">=</span> <span class="n">DataHolder</span><span class="p">(</span><span class="n">conf</span><span class="o">=</span><span class="n">DataHolder</span><span class="p">(</span><span class="n">installroot</span><span class="o">=</span><span class="n">mount_dir</span><span class="p">))</span>
<span class="c"># Fake arch with only basearch set</span>
<span class="n">arch</span> <span class="o">=</span> <span class="n">ArchData</span><span class="p">(</span><span class="n">kernels</span><span class="o">.</span><span class="n">arch</span><span class="p">)</span>
<span class="c"># TODO: Need to get release info from someplace...</span>
<span class="n">product</span> <span class="o">=</span> <span class="n">DataHolder</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="n">opts</span><span class="o">.</span><span class="n">project</span><span class="p">,</span> <span class="n">version</span><span class="o">=</span><span class="n">opts</span><span class="o">.</span><span class="n">releasever</span><span class="p">,</span> <span class="n">release</span><span class="o">=</span><span class="s">&quot;&quot;</span><span class="p">,</span>
<span class="n">variant</span><span class="o">=</span><span class="s">&quot;&quot;</span><span class="p">,</span> <span class="n">bugurl</span><span class="o">=</span><span class="s">&quot;&quot;</span><span class="p">,</span> <span class="n">isfinal</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>
<span class="c"># This is a mounted image partition, cannot hardlink to it, so just use it</span>
<span class="c"># symlink mount_dir/images to work_dir/images so we don&#39;t run out of space</span>
<span class="n">os</span><span class="o">.</span><span class="n">makedirs</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">work_dir</span><span class="p">,</span> <span class="s">&quot;images&quot;</span><span class="p">))</span>
<span class="n">rb</span> <span class="o">=</span> <span class="n">RuntimeBuilder</span><span class="p">(</span><span class="n">product</span><span class="p">,</span> <span class="n">arch</span><span class="p">,</span> <span class="n">fake_yum</span><span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;Creating runtime&quot;</span><span class="p">)</span>
<span class="n">rb</span><span class="o">.</span><span class="n">create_runtime</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">work_dir</span><span class="p">,</span> <span class="n">RUNTIME</span><span class="p">),</span> <span class="n">size</span><span class="o">=</span><span class="bp">None</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="rebuild_initrds_for_live"><a class="viewcode-back" href="../../pylorax.html#pylorax.creator.rebuild_initrds_for_live">[docs]</a><span class="k">def</span> <span class="nf">rebuild_initrds_for_live</span><span class="p">(</span><span class="n">opts</span><span class="p">,</span> <span class="n">sys_root_dir</span><span class="p">,</span> <span class="n">results_dir</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Rebuild intrds for pxe live image (root=live:http://)</span>
<span class="sd"> :param opts: options passed to livemedia-creator</span>
<span class="sd"> :type opts: argparse options</span>
<span class="sd"> :param str sys_root_dir: Path to root of the system</span>
<span class="sd"> :param str results_dir: Path of directory for storing results</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">opts</span><span class="o">.</span><span class="n">dracut_args</span><span class="p">:</span>
<span class="n">dracut_args</span> <span class="o">=</span> <span class="n">DRACUT_DEFAULT</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">dracut_args</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">arg</span> <span class="ow">in</span> <span class="n">opts</span><span class="o">.</span><span class="n">dracut_args</span><span class="p">:</span>
<span class="n">dracut_args</span> <span class="o">+=</span> <span class="n">arg</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">&quot; &quot;</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;dracut args = </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">dracut_args</span><span class="p">)</span>
<span class="n">dracut</span> <span class="o">=</span> <span class="p">[</span><span class="s">&quot;dracut&quot;</span><span class="p">,</span> <span class="s">&quot;--nomdadmconf&quot;</span><span class="p">,</span> <span class="s">&quot;--nolvmconf&quot;</span><span class="p">]</span> <span class="o">+</span> <span class="n">dracut_args</span>
<span class="n">kdir</span> <span class="o">=</span> <span class="s">&quot;boot&quot;</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">ostree</span><span class="p">:</span>
<span class="n">kernels_dir</span> <span class="o">=</span> <span class="n">glob</span><span class="o">.</span><span class="n">glob</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">sys_root_dir</span><span class="p">,</span> <span class="s">&quot;boot/ostree/*&quot;</span><span class="p">))[</span><span class="mi">0</span><span class="p">]</span>
<span class="n">kdir</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">relpath</span><span class="p">(</span><span class="n">kernels_dir</span><span class="p">,</span> <span class="n">sys_root_dir</span><span class="p">)</span>
<span class="n">kernels</span> <span class="o">=</span> <span class="p">[</span><span class="n">kernel</span> <span class="k">for</span> <span class="n">kernel</span> <span class="ow">in</span> <span class="n">findkernels</span><span class="p">(</span><span class="n">sys_root_dir</span><span class="p">,</span> <span class="n">kdir</span><span class="p">)</span>
<span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">kernel</span><span class="p">,</span> <span class="s">&quot;initrd&quot;</span><span class="p">)]</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">kernels</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="s">&quot;No initrds found, cannot rebuild_initrds&quot;</span><span class="p">)</span>
<span class="c"># Hush some dracut warnings. TODO: bind-mount proc in place?</span>
<span class="nb">open</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">sys_root_dir</span><span class="p">,</span><span class="s">&quot;/proc/modules&quot;</span><span class="p">),</span><span class="s">&quot;w&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">ostree</span><span class="p">:</span>
<span class="c"># Dracut assumes to have some dirs in disk image</span>
<span class="c"># /var/tmp for temp files</span>
<span class="n">vartmp_dir</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">sys_root_dir</span><span class="p">,</span> <span class="s">&quot;var/tmp&quot;</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">isdir</span><span class="p">(</span><span class="n">vartmp_dir</span><span class="p">):</span>
<span class="n">os</span><span class="o">.</span><span class="n">mkdir</span><span class="p">(</span><span class="n">vartmp_dir</span><span class="p">)</span>
<span class="c"># /root (maybe not fatal)</span>
<span class="n">root_dir</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">sys_root_dir</span><span class="p">,</span> <span class="s">&quot;var/roothome&quot;</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">isdir</span><span class="p">(</span><span class="n">root_dir</span><span class="p">):</span>
<span class="n">os</span><span class="o">.</span><span class="n">mkdir</span><span class="p">(</span><span class="n">root_dir</span><span class="p">)</span>
<span class="c"># /tmp (maybe not fatal)</span>
<span class="n">tmp_dir</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">sys_root_dir</span><span class="p">,</span> <span class="s">&quot;sysroot/tmp&quot;</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">isdir</span><span class="p">(</span><span class="n">tmp_dir</span><span class="p">):</span>
<span class="n">os</span><span class="o">.</span><span class="n">mkdir</span><span class="p">(</span><span class="n">tmp_dir</span><span class="p">)</span>
<span class="k">for</span> <span class="n">kernel</span> <span class="ow">in</span> <span class="n">kernels</span><span class="p">:</span>
<span class="n">outfile</span> <span class="o">=</span> <span class="n">kernel</span><span class="o">.</span><span class="n">initrd</span><span class="o">.</span><span class="n">path</span> <span class="o">+</span> <span class="s">&quot;.live&quot;</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;rebuilding </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">outfile</span><span class="p">)</span>
<span class="n">kver</span> <span class="o">=</span> <span class="n">kernel</span><span class="o">.</span><span class="n">version</span>
<span class="n">cmd</span> <span class="o">=</span> <span class="n">dracut</span> <span class="o">+</span> <span class="p">[</span><span class="n">outfile</span><span class="p">,</span> <span class="n">kver</span><span class="p">]</span>
<span class="n">runcmd</span><span class="p">(</span><span class="n">cmd</span><span class="p">,</span> <span class="n">root</span><span class="o">=</span><span class="n">sys_root_dir</span><span class="p">)</span>
<span class="n">new_initrd_path</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">results_dir</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">kernel</span><span class="o">.</span><span class="n">initrd</span><span class="o">.</span><span class="n">path</span><span class="p">))</span>
<span class="n">shutil</span><span class="o">.</span><span class="n">move</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">sys_root_dir</span><span class="p">,</span> <span class="n">outfile</span><span class="p">),</span> <span class="n">new_initrd_path</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">chmod</span><span class="p">(</span><span class="n">new_initrd_path</span><span class="p">,</span> <span class="mo">0644</span><span class="p">)</span>
<span class="n">shutil</span><span class="o">.</span><span class="n">copy2</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">sys_root_dir</span><span class="p">,</span> <span class="n">kernel</span><span class="o">.</span><span class="n">path</span><span class="p">),</span> <span class="n">results_dir</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">joinpaths</span><span class="p">(</span><span class="n">sys_root_dir</span><span class="p">,</span><span class="s">&quot;/proc/modules&quot;</span><span class="p">))</span>
</div>
<div class="viewcode-block" id="create_pxe_config"><a class="viewcode-back" href="../../pylorax.html#pylorax.creator.create_pxe_config">[docs]</a><span class="k">def</span> <span class="nf">create_pxe_config</span><span class="p">(</span><span class="n">template</span><span class="p">,</span> <span class="n">images_dir</span><span class="p">,</span> <span class="n">live_image_name</span><span class="p">,</span> <span class="n">add_args</span> <span class="o">=</span> <span class="bp">None</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Create template for pxe to live configuration</span>
<span class="sd"> :param str images_dir: Path of directory with images to be used</span>
<span class="sd"> :param str live_image_name: Name of live rootfs image file</span>
<span class="sd"> :param list add_args: Arguments to be added to initrd= pxe config</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">add_args</span> <span class="o">=</span> <span class="n">add_args</span> <span class="ow">or</span> <span class="p">[]</span>
<span class="n">kernels</span> <span class="o">=</span> <span class="p">[</span><span class="n">kernel</span> <span class="k">for</span> <span class="n">kernel</span> <span class="ow">in</span> <span class="n">findkernels</span><span class="p">(</span><span class="n">images_dir</span><span class="p">,</span> <span class="n">kdir</span><span class="o">=</span><span class="s">&quot;&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">kernel</span><span class="p">,</span> <span class="s">&quot;initrd&quot;</span><span class="p">)]</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">kernels</span><span class="p">:</span>
<span class="k">return</span>
<span class="n">kernel</span> <span class="o">=</span> <span class="n">kernels</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="n">add_args_str</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">add_args</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">result</span> <span class="o">=</span> <span class="n">Template</span><span class="p">(</span><span class="n">filename</span><span class="o">=</span><span class="n">template</span><span class="p">)</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="n">kernel</span><span class="o">=</span><span class="n">kernel</span><span class="o">.</span><span class="n">path</span><span class="p">,</span>
<span class="n">initrd</span><span class="o">=</span><span class="n">kernel</span><span class="o">.</span><span class="n">initrd</span><span class="o">.</span><span class="n">path</span><span class="p">,</span> <span class="n">liveimg</span><span class="o">=</span><span class="n">live_image_name</span><span class="p">,</span>
<span class="n">addargs</span><span class="o">=</span><span class="n">add_args_str</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
<span class="n">log</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="n">text_error_template</span><span class="p">()</span><span class="o">.</span><span class="n">render</span><span class="p">())</span>
<span class="k">raise</span>
<span class="k">with</span> <span class="nb">open</span> <span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">images_dir</span><span class="p">,</span> <span class="s">&quot;PXE_CONFIG&quot;</span><span class="p">),</span> <span class="s">&quot;w&quot;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">result</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="make_livecd"><a class="viewcode-back" href="../../pylorax.html#pylorax.creator.make_livecd">[docs]</a><span class="k">def</span> <span class="nf">make_livecd</span><span class="p">(</span><span class="n">opts</span><span class="p">,</span> <span class="n">mount_dir</span><span class="p">,</span> <span class="n">work_dir</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Take the content from the disk image and make a livecd out of it</span>
<span class="sd"> This uses wwood&#39;s squashfs live initramfs method:</span>
<span class="sd"> * put the real / into LiveOS/rootfs.img</span>
<span class="sd"> * make a squashfs of the LiveOS/rootfs.img tree</span>
<span class="sd"> * make a simple initramfs with the squashfs.img and /etc/cmdline in it</span>
<span class="sd"> * make a cpio of that tree</span>
<span class="sd"> * append the squashfs.cpio to a dracut initramfs for each kernel installed</span>
<span class="sd"> Then on boot dracut reads /etc/cmdline which points to the squashfs.img</span>
<span class="sd"> mounts that and then mounts LiveOS/rootfs.img as /</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">kernels</span> <span class="o">=</span> <span class="n">KernelInfo</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">mount_dir</span><span class="p">,</span> <span class="s">&quot;boot&quot;</span> <span class="p">))</span>
<span class="n">arch</span> <span class="o">=</span> <span class="n">ArchData</span><span class="p">(</span><span class="n">kernels</span><span class="o">.</span><span class="n">arch</span><span class="p">)</span>
<span class="c"># TODO: Need to get release info from someplace...</span>
<span class="n">product</span> <span class="o">=</span> <span class="n">DataHolder</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="n">opts</span><span class="o">.</span><span class="n">project</span><span class="p">,</span> <span class="n">version</span><span class="o">=</span><span class="n">opts</span><span class="o">.</span><span class="n">releasever</span><span class="p">,</span> <span class="n">release</span><span class="o">=</span><span class="s">&quot;&quot;</span><span class="p">,</span>
<span class="n">variant</span><span class="o">=</span><span class="s">&quot;&quot;</span><span class="p">,</span> <span class="n">bugurl</span><span class="o">=</span><span class="s">&quot;&quot;</span><span class="p">,</span> <span class="n">isfinal</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>
<span class="c"># Link /images to work_dir/images to make the templates happy</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">islink</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">mount_dir</span><span class="p">,</span> <span class="s">&quot;images&quot;</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">joinpaths</span><span class="p">(</span><span class="n">mount_dir</span><span class="p">,</span> <span class="s">&quot;images&quot;</span><span class="p">))</span>
<span class="n">execWithRedirect</span><span class="p">(</span><span class="s">&quot;/bin/ln&quot;</span><span class="p">,</span> <span class="p">[</span><span class="s">&quot;-s&quot;</span><span class="p">,</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">work_dir</span><span class="p">,</span> <span class="s">&quot;images&quot;</span><span class="p">),</span>
<span class="n">joinpaths</span><span class="p">(</span><span class="n">mount_dir</span><span class="p">,</span> <span class="s">&quot;images&quot;</span><span class="p">)])</span>
<span class="c"># The templates expect the config files to be in /tmp/config_files</span>
<span class="c"># I think these should be release specific, not from lorax, but for now</span>
<span class="n">configdir</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">opts</span><span class="o">.</span><span class="n">lorax_templates</span><span class="p">,</span><span class="s">&quot;live/config_files/&quot;</span><span class="p">)</span>
<span class="n">configdir_path</span> <span class="o">=</span> <span class="s">&quot;tmp/config_files&quot;</span>
<span class="n">fullpath</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">mount_dir</span><span class="p">,</span> <span class="n">configdir_path</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">exists</span><span class="p">(</span><span class="n">fullpath</span><span class="p">):</span>
<span class="n">remove</span><span class="p">(</span><span class="n">fullpath</span><span class="p">)</span>
<span class="n">shutil</span><span class="o">.</span><span class="n">copytree</span><span class="p">(</span><span class="n">configdir</span><span class="p">,</span> <span class="n">fullpath</span><span class="p">)</span>
<span class="n">isolabel</span> <span class="o">=</span> <span class="n">opts</span><span class="o">.</span><span class="n">volid</span> <span class="ow">or</span> <span class="s">&quot;{0.name} {0.version} {1.basearch}&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">product</span><span class="p">,</span> <span class="n">arch</span><span class="p">)</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">isolabel</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">32</span><span class="p">:</span>
<span class="n">isolabel</span> <span class="o">=</span> <span class="n">isolabel</span><span class="p">[:</span><span class="mi">32</span><span class="p">]</span>
<span class="n">log</span><span class="o">.</span><span class="n">warn</span><span class="p">(</span><span class="s">&quot;Truncating isolabel to 32 chars: </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">isolabel</span><span class="p">)</span>
<span class="n">tb</span> <span class="o">=</span> <span class="n">TreeBuilder</span><span class="p">(</span><span class="n">product</span><span class="o">=</span><span class="n">product</span><span class="p">,</span> <span class="n">arch</span><span class="o">=</span><span class="n">arch</span><span class="p">,</span> <span class="n">domacboot</span><span class="o">=</span><span class="n">opts</span><span class="o">.</span><span class="n">domacboot</span><span class="p">,</span>
<span class="n">inroot</span><span class="o">=</span><span class="n">mount_dir</span><span class="p">,</span> <span class="n">outroot</span><span class="o">=</span><span class="n">work_dir</span><span class="p">,</span>
<span class="n">runtime</span><span class="o">=</span><span class="n">RUNTIME</span><span class="p">,</span> <span class="n">isolabel</span><span class="o">=</span><span class="n">isolabel</span><span class="p">,</span>
<span class="n">templatedir</span><span class="o">=</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">opts</span><span class="o">.</span><span class="n">lorax_templates</span><span class="p">,</span><span class="s">&quot;live/&quot;</span><span class="p">))</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span> <span class="s">&quot;Rebuilding initrds&quot;</span> <span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">opts</span><span class="o">.</span><span class="n">dracut_args</span><span class="p">:</span>
<span class="n">dracut_args</span> <span class="o">=</span> <span class="n">DRACUT_DEFAULT</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">dracut_args</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">arg</span> <span class="ow">in</span> <span class="n">opts</span><span class="o">.</span><span class="n">dracut_args</span><span class="p">:</span>
<span class="n">dracut_args</span> <span class="o">+=</span> <span class="n">arg</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">&quot; &quot;</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;dracut args = </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">dracut_args</span><span class="p">)</span>
<span class="n">tb</span><span class="o">.</span><span class="n">rebuild_initrds</span><span class="p">(</span><span class="n">add_args</span><span class="o">=</span><span class="n">dracut_args</span><span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;Building boot.iso&quot;</span><span class="p">)</span>
<span class="n">tb</span><span class="o">.</span><span class="n">build</span><span class="p">()</span>
<span class="k">return</span> <span class="n">work_dir</span>
</div>
<div class="viewcode-block" id="mount_boot_part_over_root"><a class="viewcode-back" href="../../pylorax.html#pylorax.creator.mount_boot_part_over_root">[docs]</a><span class="k">def</span> <span class="nf">mount_boot_part_over_root</span><span class="p">(</span><span class="n">img_mount</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Mount boot partition to /boot of root fs mounted in img_mount</span>
<span class="sd"> Used for OSTree so it finds deployment configurations on live rootfs</span>
<span class="sd"> param img_mount: object with mounted disk image root partition</span>
<span class="sd"> type img_mount: imgutils.PartitionMount</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">root_dir</span> <span class="o">=</span> <span class="n">img_mount</span><span class="o">.</span><span class="n">mount_dir</span>
<span class="n">is_boot_part</span> <span class="o">=</span> <span class="k">lambda</span> <span class="nb">dir</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">exists</span><span class="p">(</span><span class="nb">dir</span><span class="o">+</span><span class="s">&quot;/loader.0&quot;</span><span class="p">)</span>
<span class="n">tmp_mount_dir</span> <span class="o">=</span> <span class="n">tempfile</span><span class="o">.</span><span class="n">mkdtemp</span><span class="p">()</span>
<span class="n">sys_root</span> <span class="o">=</span> <span class="n">find_ostree_root</span><span class="p">(</span><span class="n">root_dir</span><span class="p">)</span>
<span class="n">sysroot_boot_dir</span> <span class="o">=</span> <span class="bp">None</span>
<span class="k">for</span> <span class="n">dev</span><span class="p">,</span> <span class="n">_size</span> <span class="ow">in</span> <span class="n">img_mount</span><span class="o">.</span><span class="n">loop_devices</span><span class="p">:</span>
<span class="k">if</span> <span class="n">dev</span> <span class="ow">is</span> <span class="n">img_mount</span><span class="o">.</span><span class="n">mount_dev</span><span class="p">:</span>
<span class="k">continue</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">mount</span><span class="p">(</span><span class="s">&quot;/dev/mapper/&quot;</span><span class="o">+</span><span class="n">dev</span><span class="p">,</span> <span class="n">mnt</span><span class="o">=</span><span class="n">tmp_mount_dir</span><span class="p">)</span>
<span class="k">if</span> <span class="n">is_boot_part</span><span class="p">(</span><span class="n">tmp_mount_dir</span><span class="p">):</span>
<span class="n">umount</span><span class="p">(</span><span class="n">tmp_mount_dir</span><span class="p">)</span>
<span class="n">sysroot_boot_dir</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">root_dir</span><span class="p">,</span> <span class="n">sys_root</span><span class="p">),</span> <span class="s">&quot;boot&quot;</span><span class="p">)</span>
<span class="n">mount</span><span class="p">(</span><span class="s">&quot;/dev/mapper/&quot;</span><span class="o">+</span><span class="n">dev</span><span class="p">,</span> <span class="n">mnt</span><span class="o">=</span><span class="n">sysroot_boot_dir</span><span class="p">)</span>
<span class="k">break</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">umount</span><span class="p">(</span><span class="n">tmp_mount_dir</span><span class="p">)</span>
<span class="k">except</span> <span class="n">subprocess</span><span class="o">.</span><span class="n">CalledProcessError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="n">log</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">&quot;Looking for boot partition error: </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">e</span><span class="p">)</span>
<span class="n">remove</span><span class="p">(</span><span class="n">tmp_mount_dir</span><span class="p">)</span>
<span class="k">return</span> <span class="n">sysroot_boot_dir</span>
</div>
<div class="viewcode-block" id="make_squashfs"><a class="viewcode-back" href="../../pylorax.html#pylorax.creator.make_squashfs">[docs]</a><span class="k">def</span> <span class="nf">make_squashfs</span><span class="p">(</span><span class="n">disk_img</span><span class="p">,</span> <span class="n">work_dir</span><span class="p">,</span> <span class="n">compression</span><span class="o">=</span><span class="s">&quot;xz&quot;</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Take disk_img and put it into LiveOS/rootfs.img and squashfs this</span>
<span class="sd"> tree into work_dir+RUNTIME</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">liveos_dir</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">work_dir</span><span class="p">,</span> <span class="s">&quot;runtime/LiveOS&quot;</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">makedirs</span><span class="p">(</span><span class="n">liveos_dir</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">makedirs</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">dirname</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">work_dir</span><span class="p">,</span> <span class="n">RUNTIME</span><span class="p">)))</span>
<span class="n">rc</span> <span class="o">=</span> <span class="n">execWithRedirect</span><span class="p">(</span><span class="s">&quot;/bin/ln&quot;</span><span class="p">,</span> <span class="p">[</span><span class="n">disk_img</span><span class="p">,</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">liveos_dir</span><span class="p">,</span> <span class="s">&quot;rootfs.img&quot;</span><span class="p">)])</span>
<span class="k">if</span> <span class="n">rc</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span>
<span class="n">shutil</span><span class="o">.</span><span class="n">copy2</span><span class="p">(</span><span class="n">disk_img</span><span class="p">,</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">liveos_dir</span><span class="p">,</span> <span class="s">&quot;rootfs.img&quot;</span><span class="p">))</span>
<span class="n">mksquashfs</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">work_dir</span><span class="p">,</span> <span class="s">&quot;runtime&quot;</span><span class="p">),</span>
<span class="n">joinpaths</span><span class="p">(</span><span class="n">work_dir</span><span class="p">,</span> <span class="n">RUNTIME</span><span class="p">),</span> <span class="n">compression</span><span class="p">)</span>
<span class="n">remove</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">work_dir</span><span class="p">,</span> <span class="s">&quot;runtime&quot;</span><span class="p">))</span>
</div>
<div class="viewcode-block" id="make_image"><a class="viewcode-back" href="../../pylorax.html#pylorax.creator.make_image">[docs]</a><span class="k">def</span> <span class="nf">make_image</span><span class="p">(</span><span class="n">opts</span><span class="p">,</span> <span class="n">ks</span><span class="p">,</span> <span class="n">callback_func</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Install to an image</span>
<span class="sd"> Use virt or anaconda to install to an image.</span>
<span class="sd"> Returns the full path of of the image created.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">disk_size</span> <span class="o">=</span> <span class="n">get_ks_disk_size</span><span class="p">(</span><span class="n">ks</span><span class="p">)</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">image_name</span><span class="p">:</span>
<span class="n">disk_img</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">opts</span><span class="o">.</span><span class="n">result_dir</span><span class="p">,</span> <span class="n">opts</span><span class="o">.</span><span class="n">image_name</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">disk_img</span> <span class="o">=</span> <span class="n">tempfile</span><span class="o">.</span><span class="n">mktemp</span><span class="p">(</span><span class="n">prefix</span><span class="o">=</span><span class="s">&quot;disk&quot;</span><span class="p">,</span> <span class="n">suffix</span><span class="o">=</span><span class="s">&quot;.img&quot;</span><span class="p">,</span> <span class="nb">dir</span><span class="o">=</span><span class="n">opts</span><span class="o">.</span><span class="n">result_dir</span><span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;disk_img = </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">disk_img</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">no_virt</span><span class="p">:</span>
<span class="n">novirt_install</span><span class="p">(</span><span class="n">opts</span><span class="p">,</span> <span class="n">disk_img</span><span class="p">,</span> <span class="n">disk_size</span><span class="p">,</span> <span class="n">ks</span><span class="o">.</span><span class="n">handler</span><span class="o">.</span><span class="n">method</span><span class="o">.</span><span class="n">url</span><span class="p">,</span> <span class="n">callback_func</span><span class="o">=</span><span class="n">callback_func</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">install_log</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">abspath</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">dirname</span><span class="p">(</span><span class="n">opts</span><span class="o">.</span><span class="n">logfile</span><span class="p">))</span><span class="o">+</span><span class="s">&quot;/virt-install.log&quot;</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;install_log = </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">install_log</span><span class="p">)</span>
<span class="n">virt_install</span><span class="p">(</span><span class="n">opts</span><span class="p">,</span> <span class="n">install_log</span><span class="p">,</span> <span class="n">disk_img</span><span class="p">,</span> <span class="n">disk_size</span><span class="p">)</span>
<span class="k">except</span> <span class="n">InstallError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="n">log</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s">&quot;Install failed: </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">e</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">opts</span><span class="o">.</span><span class="n">keep_image</span><span class="p">:</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;Removing bad disk image&quot;</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">disk_img</span><span class="p">)</span>
<span class="k">raise</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;Disk Image install successful&quot;</span><span class="p">)</span>
<span class="k">return</span> <span class="n">disk_img</span>
</div>
<div class="viewcode-block" id="make_live_images"><a class="viewcode-back" href="../../pylorax.html#pylorax.creator.make_live_images">[docs]</a><span class="k">def</span> <span class="nf">make_live_images</span><span class="p">(</span><span class="n">opts</span><span class="p">,</span> <span class="n">work_dir</span><span class="p">,</span> <span class="n">root_dir</span><span class="p">,</span> <span class="n">rootfs_image</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">size</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Create live images from direcory or rootfs image</span>
<span class="sd"> :param opts: options passed to livemedia-creator</span>
<span class="sd"> :type opts: argparse options</span>
<span class="sd"> :param str work_dir: Directory for storing results</span>
<span class="sd"> :param str root_dir: Root directory of live filesystem tree</span>
<span class="sd"> :param str rootfs_image: Path to live rootfs image to be used</span>
<span class="sd"> :returns: Path of directory with created images</span>
<span class="sd"> :rtype: str</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">sys_root</span> <span class="o">=</span> <span class="s">&quot;&quot;</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">ostree</span><span class="p">:</span>
<span class="n">sys_root</span> <span class="o">=</span> <span class="n">find_ostree_root</span><span class="p">(</span><span class="n">root_dir</span><span class="p">)</span>
<span class="n">squashfs_root_dir</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">work_dir</span><span class="p">,</span> <span class="s">&quot;squashfs_root&quot;</span><span class="p">)</span>
<span class="n">liveos_dir</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">squashfs_root_dir</span><span class="p">,</span> <span class="s">&quot;LiveOS&quot;</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">makedirs</span><span class="p">(</span><span class="n">liveos_dir</span><span class="p">)</span>
<span class="k">if</span> <span class="n">rootfs_image</span><span class="p">:</span>
<span class="n">rc</span> <span class="o">=</span> <span class="n">execWithRedirect</span><span class="p">(</span><span class="s">&quot;/bin/ln&quot;</span><span class="p">,</span> <span class="p">[</span><span class="n">rootfs_image</span><span class="p">,</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">liveos_dir</span><span class="p">,</span> <span class="s">&quot;rootfs.img&quot;</span><span class="p">)])</span>
<span class="k">if</span> <span class="n">rc</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span>
<span class="n">shutil</span><span class="o">.</span><span class="n">copy2</span><span class="p">(</span><span class="n">rootfs_image</span><span class="p">,</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">liveos_dir</span><span class="p">,</span> <span class="s">&quot;rootfs.img&quot;</span><span class="p">))</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;Creating live rootfs image&quot;</span><span class="p">)</span>
<span class="n">mkrootfsimg</span><span class="p">(</span><span class="n">root_dir</span><span class="p">,</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">liveos_dir</span><span class="p">,</span> <span class="s">&quot;rootfs.img&quot;</span><span class="p">),</span> <span class="s">&quot;LiveOS&quot;</span><span class="p">,</span> <span class="n">size</span><span class="o">=</span><span class="n">size</span><span class="p">,</span> <span class="n">sysroot</span><span class="o">=</span><span class="n">sys_root</span><span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;Packing live rootfs image&quot;</span><span class="p">)</span>
<span class="n">add_pxe_args</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">live_image_name</span> <span class="o">=</span> <span class="s">&quot;live-rootfs.squashfs.img&quot;</span>
<span class="n">mksquashfs</span><span class="p">(</span><span class="n">squashfs_root_dir</span><span class="p">,</span>
<span class="n">joinpaths</span><span class="p">(</span><span class="n">work_dir</span><span class="p">,</span> <span class="n">live_image_name</span><span class="p">),</span>
<span class="n">opts</span><span class="o">.</span><span class="n">compression</span><span class="p">,</span>
<span class="n">opts</span><span class="o">.</span><span class="n">compress_args</span><span class="p">)</span>
<span class="n">remove</span><span class="p">(</span><span class="n">squashfs_root_dir</span><span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;Rebuilding initramfs for live&quot;</span><span class="p">)</span>
<span class="n">rebuild_initrds_for_live</span><span class="p">(</span><span class="n">opts</span><span class="p">,</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">root_dir</span><span class="p">,</span> <span class="n">sys_root</span><span class="p">),</span> <span class="n">work_dir</span><span class="p">)</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">ostree</span><span class="p">:</span>
<span class="n">add_pxe_args</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s">&quot;ostree=/</span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">sys_root</span><span class="p">)</span>
<span class="n">template</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">opts</span><span class="o">.</span><span class="n">lorax_templates</span><span class="p">,</span> <span class="s">&quot;pxe-live/pxe-config.tmpl&quot;</span><span class="p">)</span>
<span class="n">create_pxe_config</span><span class="p">(</span><span class="n">template</span><span class="p">,</span> <span class="n">work_dir</span><span class="p">,</span> <span class="n">live_image_name</span><span class="p">,</span> <span class="n">add_pxe_args</span><span class="p">)</span>
<span class="k">return</span> <span class="n">work_dir</span>
</div>
<div class="viewcode-block" id="run_creator"><a class="viewcode-back" href="../../pylorax.html#pylorax.creator.run_creator">[docs]</a><span class="k">def</span> <span class="nf">run_creator</span><span class="p">(</span><span class="n">opts</span><span class="p">,</span> <span class="n">callback_func</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Run the image creator process</span>
<span class="sd"> :param opts: Commandline options to control the process</span>
<span class="sd"> :type opts: Either a DataHolder or ArgumentParser</span>
<span class="sd"> :returns: The result directory and the disk image path.</span>
<span class="sd"> :rtype: Tuple of str</span>
<span class="sd"> This function takes the opts arguments and creates the selected output image.</span>
<span class="sd"> See the cmdline --help for livemedia-creator for the possible options</span>
<span class="sd"> (Yes, this is not ideal, but we can fix that later)</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">result_dir</span> <span class="o">=</span> <span class="bp">None</span>
<span class="c"># Parse the kickstart</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">ks</span><span class="p">:</span>
<span class="n">ks_version</span> <span class="o">=</span> <span class="n">makeVersion</span><span class="p">(</span><span class="n">RHEL7</span><span class="p">)</span>
<span class="n">ks</span> <span class="o">=</span> <span class="n">KickstartParser</span><span class="p">(</span> <span class="n">ks_version</span><span class="p">,</span> <span class="n">errorsAreFatal</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">missingIncludeIsFatal</span><span class="o">=</span><span class="bp">False</span> <span class="p">)</span>
<span class="n">ks</span><span class="o">.</span><span class="n">readKickstart</span><span class="p">(</span> <span class="n">opts</span><span class="o">.</span><span class="n">ks</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="p">)</span>
<span class="c"># Make the disk or filesystem image</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">opts</span><span class="o">.</span><span class="n">disk_image</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">opts</span><span class="o">.</span><span class="n">fs_image</span><span class="p">:</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">opts</span><span class="o">.</span><span class="n">ks</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s">&quot;Image creation requires a kickstart file&quot;</span><span class="p">)</span>
<span class="n">errors</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">if</span> <span class="n">ks</span><span class="o">.</span><span class="n">handler</span><span class="o">.</span><span class="n">method</span><span class="o">.</span><span class="n">method</span> <span class="o">!=</span> <span class="s">&quot;url&quot;</span> <span class="ow">and</span> <span class="n">opts</span><span class="o">.</span><span class="n">no_virt</span><span class="p">:</span>
<span class="n">errors</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s">&quot;Only url install method is currently supported. Please &quot;</span>
<span class="s">&quot;fix your kickstart file.&quot;</span> <span class="p">)</span>
<span class="k">if</span> <span class="n">ks</span><span class="o">.</span><span class="n">handler</span><span class="o">.</span><span class="n">displaymode</span><span class="o">.</span><span class="n">displayMode</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span>
<span class="n">errors</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s">&quot;The kickstart must not set a display mode (text, cmdline, &quot;</span>
<span class="s">&quot;graphical), this will interfere with livemedia-creator.&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">make_fsimage</span><span class="p">:</span>
<span class="c"># Make sure the kickstart isn&#39;t using autopart and only has a / mountpoint</span>
<span class="n">part_ok</span> <span class="o">=</span> <span class="ow">not</span> <span class="nb">any</span><span class="p">(</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">ks</span><span class="o">.</span><span class="n">handler</span><span class="o">.</span><span class="n">partition</span><span class="o">.</span><span class="n">partitions</span>
<span class="k">if</span> <span class="n">p</span><span class="o">.</span><span class="n">mountpoint</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">[</span><span class="s">&quot;/&quot;</span><span class="p">,</span> <span class="s">&quot;swap&quot;</span><span class="p">])</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">part_ok</span> <span class="ow">or</span> <span class="n">ks</span><span class="o">.</span><span class="n">handler</span><span class="o">.</span><span class="n">autopart</span><span class="o">.</span><span class="n">seen</span><span class="p">:</span>
<span class="n">errors</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s">&quot;Filesystem images must use a single / part, not autopart or &quot;</span>
<span class="s">&quot;multiple partitions. swap is allowed but not used.&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">errors</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</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">errors</span><span class="p">))</span>
<span class="c"># Make the image. Output of this is either a partitioned disk image or a fsimage</span>
<span class="c"># Can also fail with InstallError</span>
<span class="n">disk_img</span> <span class="o">=</span> <span class="n">make_image</span><span class="p">(</span><span class="n">opts</span><span class="p">,</span> <span class="n">ks</span><span class="p">,</span> <span class="n">callback_func</span><span class="o">=</span><span class="n">callback_func</span><span class="p">)</span>
<span class="c"># Only create the disk image, return that now</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">image_only</span><span class="p">:</span>
<span class="k">return</span> <span class="p">(</span><span class="n">result_dir</span><span class="p">,</span> <span class="n">disk_img</span><span class="p">)</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">make_iso</span><span class="p">:</span>
<span class="n">work_dir</span> <span class="o">=</span> <span class="n">tempfile</span><span class="o">.</span><span class="n">mkdtemp</span><span class="p">()</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;working dir is </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">work_dir</span><span class="p">)</span>
<span class="k">if</span> <span class="p">(</span><span class="n">opts</span><span class="o">.</span><span class="n">fs_image</span> <span class="ow">or</span> <span class="n">opts</span><span class="o">.</span><span class="n">no_virt</span><span class="p">)</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">opts</span><span class="o">.</span><span class="n">disk_image</span><span class="p">:</span>
<span class="c"># Create iso from a filesystem image</span>
<span class="n">disk_img</span> <span class="o">=</span> <span class="n">opts</span><span class="o">.</span><span class="n">fs_image</span> <span class="ow">or</span> <span class="n">disk_img</span>
<span class="n">make_squashfs</span><span class="p">(</span><span class="n">disk_img</span><span class="p">,</span> <span class="n">work_dir</span><span class="p">)</span>
<span class="k">with</span> <span class="n">Mount</span><span class="p">(</span><span class="n">disk_img</span><span class="p">,</span> <span class="n">opts</span><span class="o">=</span><span class="s">&quot;loop&quot;</span><span class="p">)</span> <span class="k">as</span> <span class="n">mount_dir</span><span class="p">:</span>
<span class="n">result_dir</span> <span class="o">=</span> <span class="n">make_livecd</span><span class="p">(</span><span class="n">opts</span><span class="p">,</span> <span class="n">mount_dir</span><span class="p">,</span> <span class="n">work_dir</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="c"># Create iso from a partitioned disk image</span>
<span class="n">disk_img</span> <span class="o">=</span> <span class="n">opts</span><span class="o">.</span><span class="n">disk_image</span> <span class="ow">or</span> <span class="n">disk_img</span>
<span class="k">with</span> <span class="n">PartitionMount</span><span class="p">(</span><span class="n">disk_img</span><span class="p">)</span> <span class="k">as</span> <span class="n">img_mount</span><span class="p">:</span>
<span class="k">if</span> <span class="n">img_mount</span> <span class="ow">and</span> <span class="n">img_mount</span><span class="o">.</span><span class="n">mount_dir</span><span class="p">:</span>
<span class="n">make_runtime</span><span class="p">(</span><span class="n">opts</span><span class="p">,</span> <span class="n">img_mount</span><span class="o">.</span><span class="n">mount_dir</span><span class="p">,</span> <span class="n">work_dir</span><span class="p">)</span>
<span class="n">result_dir</span> <span class="o">=</span> <span class="n">make_livecd</span><span class="p">(</span><span class="n">opts</span><span class="p">,</span> <span class="n">img_mount</span><span class="o">.</span><span class="n">mount_dir</span><span class="p">,</span> <span class="n">work_dir</span><span class="p">)</span>
<span class="c"># cleanup the mess</span>
<span class="c"># cleanup work_dir?</span>
<span class="k">if</span> <span class="n">disk_img</span> <span class="ow">and</span> <span class="ow">not</span> <span class="p">(</span><span class="n">opts</span><span class="o">.</span><span class="n">keep_image</span> <span class="ow">or</span> <span class="n">opts</span><span class="o">.</span><span class="n">disk_image</span> <span class="ow">or</span> <span class="n">opts</span><span class="o">.</span><span class="n">fs_image</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">disk_img</span><span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;Disk image erased&quot;</span><span class="p">)</span>
<span class="n">disk_img</span> <span class="o">=</span> <span class="bp">None</span>
<span class="k">elif</span> <span class="n">opts</span><span class="o">.</span><span class="n">make_appliance</span><span class="p">:</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">opts</span><span class="o">.</span><span class="n">ks</span><span class="p">:</span>
<span class="n">networks</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">networks</span> <span class="o">=</span> <span class="n">ks</span><span class="o">.</span><span class="n">handler</span><span class="o">.</span><span class="n">network</span><span class="o">.</span><span class="n">network</span>
<span class="n">make_appliance</span><span class="p">(</span><span class="n">opts</span><span class="o">.</span><span class="n">disk_image</span> <span class="ow">or</span> <span class="n">disk_img</span><span class="p">,</span> <span class="n">opts</span><span class="o">.</span><span class="n">app_name</span><span class="p">,</span>
<span class="n">opts</span><span class="o">.</span><span class="n">app_template</span><span class="p">,</span> <span class="n">opts</span><span class="o">.</span><span class="n">app_file</span><span class="p">,</span> <span class="n">networks</span><span class="p">,</span> <span class="n">opts</span><span class="o">.</span><span class="n">ram</span><span class="p">,</span>
<span class="n">opts</span><span class="o">.</span><span class="n">vcpus</span><span class="p">,</span> <span class="n">opts</span><span class="o">.</span><span class="n">arch</span><span class="p">,</span> <span class="n">opts</span><span class="o">.</span><span class="n">title</span><span class="p">,</span> <span class="n">opts</span><span class="o">.</span><span class="n">project</span><span class="p">,</span> <span class="n">opts</span><span class="o">.</span><span class="n">releasever</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">opts</span><span class="o">.</span><span class="n">make_pxe_live</span><span class="p">:</span>
<span class="n">work_dir</span> <span class="o">=</span> <span class="n">tempfile</span><span class="o">.</span><span class="n">mkdtemp</span><span class="p">()</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;working dir is </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">work_dir</span><span class="p">)</span>
<span class="k">if</span> <span class="p">(</span><span class="n">opts</span><span class="o">.</span><span class="n">fs_image</span> <span class="ow">or</span> <span class="n">opts</span><span class="o">.</span><span class="n">no_virt</span><span class="p">)</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">opts</span><span class="o">.</span><span class="n">disk_image</span><span class="p">:</span>
<span class="c"># Create pxe live images from a filesystem image</span>
<span class="n">disk_img</span> <span class="o">=</span> <span class="n">opts</span><span class="o">.</span><span class="n">fs_image</span> <span class="ow">or</span> <span class="n">disk_img</span>
<span class="k">with</span> <span class="n">Mount</span><span class="p">(</span><span class="n">disk_img</span><span class="p">,</span> <span class="n">opts</span><span class="o">=</span><span class="s">&quot;loop&quot;</span><span class="p">)</span> <span class="k">as</span> <span class="n">mnt_dir</span><span class="p">:</span>
<span class="n">result_dir</span> <span class="o">=</span> <span class="n">make_live_images</span><span class="p">(</span><span class="n">opts</span><span class="p">,</span> <span class="n">work_dir</span><span class="p">,</span> <span class="n">mnt_dir</span><span class="p">,</span> <span class="n">rootfs_image</span><span class="o">=</span><span class="n">disk_img</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="c"># Create pxe live images from a partitioned disk image</span>
<span class="n">disk_img</span> <span class="o">=</span> <span class="n">opts</span><span class="o">.</span><span class="n">disk_image</span> <span class="ow">or</span> <span class="n">disk_img</span>
<span class="n">is_root_part</span> <span class="o">=</span> <span class="bp">None</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">ostree</span><span class="p">:</span>
<span class="n">is_root_part</span> <span class="o">=</span> <span class="k">lambda</span> <span class="nb">dir</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">exists</span><span class="p">(</span><span class="nb">dir</span><span class="o">+</span><span class="s">&quot;/ostree/deploy&quot;</span><span class="p">)</span>
<span class="k">with</span> <span class="n">PartitionMount</span><span class="p">(</span><span class="n">disk_img</span><span class="p">,</span> <span class="n">mount_ok</span><span class="o">=</span><span class="n">is_root_part</span><span class="p">)</span> <span class="k">as</span> <span class="n">img_mount</span><span class="p">:</span>
<span class="k">if</span> <span class="n">img_mount</span> <span class="ow">and</span> <span class="n">img_mount</span><span class="o">.</span><span class="n">mount_dir</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">mounted_sysroot_boot_dir</span> <span class="o">=</span> <span class="bp">None</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">ostree</span><span class="p">:</span>
<span class="n">mounted_sysroot_boot_dir</span> <span class="o">=</span> <span class="n">mount_boot_part_over_root</span><span class="p">(</span><span class="n">img_mount</span><span class="p">)</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">live_rootfs_keep_size</span><span class="p">:</span>
<span class="n">size</span> <span class="o">=</span> <span class="n">img_mount</span><span class="o">.</span><span class="n">mount_size</span> <span class="o">/</span> <span class="mi">1024</span><span class="o">**</span><span class="mi">3</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">size</span> <span class="o">=</span> <span class="n">opts</span><span class="o">.</span><span class="n">live_rootfs_size</span> <span class="ow">or</span> <span class="bp">None</span>
<span class="n">result_dir</span> <span class="o">=</span> <span class="n">make_live_images</span><span class="p">(</span><span class="n">opts</span><span class="p">,</span> <span class="n">work_dir</span><span class="p">,</span> <span class="n">img_mount</span><span class="o">.</span><span class="n">mount_dir</span><span class="p">,</span> <span class="n">size</span><span class="o">=</span><span class="n">size</span><span class="p">)</span>
<span class="k">finally</span><span class="p">:</span>
<span class="k">if</span> <span class="n">mounted_sysroot_boot_dir</span><span class="p">:</span>
<span class="n">umount</span><span class="p">(</span><span class="n">mounted_sysroot_boot_dir</span><span class="p">)</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">result_dir</span> <span class="o">!=</span> <span class="n">opts</span><span class="o">.</span><span class="n">tmp</span> <span class="ow">and</span> <span class="n">result_dir</span><span class="p">:</span>
<span class="n">copytree</span><span class="p">(</span><span class="n">result_dir</span><span class="p">,</span> <span class="n">opts</span><span class="o">.</span><span class="n">result_dir</span><span class="p">,</span> <span class="n">preserve</span><span class="o">=</span><span class="bp">False</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">result_dir</span> <span class="p">)</span>
<span class="n">result_dir</span> <span class="o">=</span> <span class="bp">None</span>
<span class="k">return</span> <span class="p">(</span><span class="n">result_dir</span><span class="p">,</span> <span class="n">disk_img</span><span class="p">)</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">Lorax 19.7.10 documentation</a> &raquo;</li>
<li><a href="../index.html" >Module code</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2017, Red Hat, Inc..
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>

View File

@ -0,0 +1,124 @@
<!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>pylorax.decorators &mdash; Lorax 19.7.10 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: '19.7.10',
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>
<link rel="top" title="Lorax 19.7.10 documentation" href="../../index.html" />
<link rel="up" title="Module code" href="../index.html" />
</head>
<body>
<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">Lorax 19.7.10 documentation</a> &raquo;</li>
<li><a href="../index.html" accesskey="U">Module code</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<h1>Source code for pylorax.decorators</h1><div class="highlight"><pre>
<span class="c">#</span>
<span class="c"># decorators.py</span>
<span class="c">#</span>
<span class="c"># Copyright (C) 2009 Red Hat, Inc.</span>
<span class="c">#</span>
<span class="c"># This program is free software; you can redistribute it and/or modify</span>
<span class="c"># it under the terms of the GNU General Public License as published by</span>
<span class="c"># the Free Software Foundation; either version 2 of the License, or</span>
<span class="c"># (at your option) any later version.</span>
<span class="c">#</span>
<span class="c"># This program is distributed in the hope that it will be useful,</span>
<span class="c"># but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<span class="c"># MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span>
<span class="c"># GNU General Public License for more details.</span>
<span class="c">#</span>
<span class="c"># You should have received a copy of the GNU General Public License</span>
<span class="c"># along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;.</span>
<span class="c">#</span>
<span class="c"># Red Hat Author(s): Martin Gracik &lt;mgracik@redhat.com&gt;</span>
<span class="c">#</span>
<div class="viewcode-block" id="singleton"><a class="viewcode-back" href="../../pylorax.html#pylorax.decorators.singleton">[docs]</a><span class="k">def</span> <span class="nf">singleton</span><span class="p">(</span><span class="n">cls</span><span class="p">):</span>
<span class="n">instances</span> <span class="o">=</span> <span class="p">{}</span>
<span class="k">def</span> <span class="nf">get_instance</span><span class="p">():</span>
<span class="k">if</span> <span class="n">cls</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">instances</span><span class="p">:</span>
<span class="n">instances</span><span class="p">[</span><span class="n">cls</span><span class="p">]</span> <span class="o">=</span> <span class="n">cls</span><span class="p">()</span>
<span class="k">return</span> <span class="n">instances</span><span class="p">[</span><span class="n">cls</span><span class="p">]</span>
<span class="k">return</span> <span class="n">get_instance</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">Lorax 19.7.10 documentation</a> &raquo;</li>
<li><a href="../index.html" >Module code</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2017, Red Hat, Inc..
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>

View File

@ -0,0 +1,133 @@
<!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>pylorax.discinfo &mdash; Lorax 19.7.10 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: '19.7.10',
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>
<link rel="top" title="Lorax 19.7.10 documentation" href="../../index.html" />
<link rel="up" title="Module code" href="../index.html" />
</head>
<body>
<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">Lorax 19.7.10 documentation</a> &raquo;</li>
<li><a href="../index.html" accesskey="U">Module code</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<h1>Source code for pylorax.discinfo</h1><div class="highlight"><pre>
<span class="c">#</span>
<span class="c"># discinfo.py</span>
<span class="c">#</span>
<span class="c"># Copyright (C) 2010 Red Hat, Inc.</span>
<span class="c">#</span>
<span class="c"># This program is free software; you can redistribute it and/or modify</span>
<span class="c"># it under the terms of the GNU General Public License as published by</span>
<span class="c"># the Free Software Foundation; either version 2 of the License, or</span>
<span class="c"># (at your option) any later version.</span>
<span class="c">#</span>
<span class="c"># This program is distributed in the hope that it will be useful,</span>
<span class="c"># but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<span class="c"># MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span>
<span class="c"># GNU General Public License for more details.</span>
<span class="c">#</span>
<span class="c"># You should have received a copy of the GNU General Public License</span>
<span class="c"># along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;.</span>
<span class="c">#</span>
<span class="c"># Red Hat Author(s): Martin Gracik &lt;mgracik@redhat.com&gt;</span>
<span class="c">#</span>
<span class="kn">import</span> <span class="nn">logging</span>
<span class="n">logger</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s">&quot;pylorax.discinfo&quot;</span><span class="p">)</span>
<span class="kn">import</span> <span class="nn">time</span>
<div class="viewcode-block" id="DiscInfo"><a class="viewcode-back" href="../../pylorax.html#pylorax.discinfo.DiscInfo">[docs]</a><span class="k">class</span> <span class="nc">DiscInfo</span><span class="p">(</span><span class="nb">object</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">release</span><span class="p">,</span> <span class="n">basearch</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">release</span> <span class="o">=</span> <span class="n">release</span>
<span class="bp">self</span><span class="o">.</span><span class="n">basearch</span> <span class="o">=</span> <span class="n">basearch</span>
<div class="viewcode-block" id="DiscInfo.write"><a class="viewcode-back" href="../../pylorax.html#pylorax.discinfo.DiscInfo.write">[docs]</a> <span class="k">def</span> <span class="nf">write</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">outfile</span><span class="p">):</span>
<span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;writing .discinfo file&quot;</span><span class="p">)</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">outfile</span><span class="p">,</span> <span class="s">&quot;w&quot;</span><span class="p">)</span> <span class="k">as</span> <span class="n">fobj</span><span class="p">:</span>
<span class="n">fobj</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">&quot;{0:f}</span><span class="se">\n</span><span class="s">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()))</span>
<span class="n">fobj</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">&quot;{0.release}</span><span class="se">\n</span><span class="s">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="p">))</span>
<span class="n">fobj</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">&quot;{0.basearch}</span><span class="se">\n</span><span class="s">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</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">Lorax 19.7.10 documentation</a> &raquo;</li>
<li><a href="../index.html" >Module code</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2017, Red Hat, Inc..
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>

View File

@ -0,0 +1,519 @@
<!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>pylorax.executils &mdash; Lorax 19.7.10 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: '19.7.10',
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>
<link rel="top" title="Lorax 19.7.10 documentation" href="../../index.html" />
<link rel="up" title="Module code" href="../index.html" />
</head>
<body>
<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">Lorax 19.7.10 documentation</a> &raquo;</li>
<li><a href="../index.html" accesskey="U">Module code</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<h1>Source code for pylorax.executils</h1><div class="highlight"><pre>
<span class="c">#</span>
<span class="c"># executil.py - subprocess execution utility functions</span>
<span class="c">#</span>
<span class="c"># Copyright (C) 1999-2011</span>
<span class="c"># Red Hat, Inc. All rights reserved.</span>
<span class="c">#</span>
<span class="c"># This program is free software; you can redistribute it and/or modify</span>
<span class="c"># it under the terms of the GNU General Public License as published by</span>
<span class="c"># the Free Software Foundation; either version 2 of the License, or</span>
<span class="c"># (at your option) any later version.</span>
<span class="c">#</span>
<span class="c"># This program is distributed in the hope that it will be useful,</span>
<span class="c"># but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<span class="c"># MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span>
<span class="c"># GNU General Public License for more details.</span>
<span class="c">#</span>
<span class="c"># You should have received a copy of the GNU General Public License</span>
<span class="c"># along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;.</span>
<span class="c">#</span>
<span class="c"># Author(s): Erik Troan &lt;ewt@redhat.com&gt;</span>
<span class="c">#</span>
<span class="kn">import</span> <span class="nn">os</span><span class="o">,</span> <span class="nn">sys</span>
<span class="kn">import</span> <span class="nn">subprocess</span>
<span class="kn">import</span> <span class="nn">time</span>
<span class="kn">import</span> <span class="nn">threading</span>
<span class="kn">import</span> <span class="nn">logging</span>
<span class="n">log</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s">&quot;pylorax&quot;</span><span class="p">)</span>
<span class="n">program_log</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s">&quot;program&quot;</span><span class="p">)</span>
<div class="viewcode-block" id="ExecProduct"><a class="viewcode-back" href="../../pylorax.html#pylorax.executils.ExecProduct">[docs]</a><span class="k">class</span> <span class="nc">ExecProduct</span><span class="p">(</span><span class="nb">object</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">rc</span><span class="p">,</span> <span class="n">stdout</span><span class="p">,</span> <span class="n">stderr</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">rc</span> <span class="o">=</span> <span class="n">rc</span>
<span class="bp">self</span><span class="o">.</span><span class="n">stdout</span> <span class="o">=</span> <span class="n">stdout</span>
<span class="bp">self</span><span class="o">.</span><span class="n">stderr</span> <span class="o">=</span> <span class="n">stderr</span>
</div>
<div class="viewcode-block" id="tee"><a class="viewcode-back" href="../../pylorax.html#pylorax.executils.tee">[docs]</a><span class="k">class</span> <span class="nc">tee</span><span class="p">(</span><span class="n">threading</span><span class="o">.</span><span class="n">Thread</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot; Python reimplementation of the shell tee process, so we can</span>
<span class="sd"> feed the pipe output into two places at the same time</span>
<span class="sd"> &quot;&quot;&quot;</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">inputdesc</span><span class="p">,</span> <span class="n">outputdesc</span><span class="p">,</span> <span class="n">logmethod</span><span class="p">,</span> <span class="n">command</span><span class="p">):</span>
<span class="n">threading</span><span class="o">.</span><span class="n">Thread</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="bp">self</span><span class="o">.</span><span class="n">inputdesc</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">fdopen</span><span class="p">(</span><span class="n">inputdesc</span><span class="p">,</span> <span class="s">&quot;r&quot;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">outputdesc</span> <span class="o">=</span> <span class="n">outputdesc</span>
<span class="bp">self</span><span class="o">.</span><span class="n">logmethod</span> <span class="o">=</span> <span class="n">logmethod</span>
<span class="bp">self</span><span class="o">.</span><span class="n">running</span> <span class="o">=</span> <span class="bp">True</span>
<span class="bp">self</span><span class="o">.</span><span class="n">command</span> <span class="o">=</span> <span class="n">command</span>
<div class="viewcode-block" id="tee.run"><a class="viewcode-back" href="../../pylorax.html#pylorax.executils.tee.run">[docs]</a> <span class="k">def</span> <span class="nf">run</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">while</span> <span class="bp">self</span><span class="o">.</span><span class="n">running</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">data</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">inputdesc</span><span class="o">.</span><span class="n">readline</span><span class="p">()</span>
<span class="k">except</span> <span class="ne">IOError</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">logmethod</span><span class="p">(</span><span class="s">&quot;Can&#39;t read from pipe during a call to </span><span class="si">%s</span><span class="s">. &quot;</span>
<span class="s">&quot;(program terminated suddenly?)&quot;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">command</span><span class="p">)</span>
<span class="k">break</span>
<span class="k">if</span> <span class="n">data</span> <span class="o">==</span> <span class="s">&quot;&quot;</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">running</span> <span class="o">=</span> <span class="bp">False</span>
<span class="k">else</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">logmethod</span><span class="p">(</span><span class="n">data</span><span class="o">.</span><span class="n">rstrip</span><span class="p">(</span><span class="s">&#39;</span><span class="se">\n</span><span class="s">&#39;</span><span class="p">))</span>
<span class="n">os</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">outputdesc</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="tee.stop"><a class="viewcode-back" href="../../pylorax.html#pylorax.executils.tee.stop">[docs]</a> <span class="k">def</span> <span class="nf">stop</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">running</span> <span class="o">=</span> <span class="bp">False</span>
<span class="k">return</span> <span class="bp">self</span>
</div></div>
<div class="viewcode-block" id="execWithRedirect"><a class="viewcode-back" href="../../pylorax.html#pylorax.executils.execWithRedirect">[docs]</a><span class="k">def</span> <span class="nf">execWithRedirect</span><span class="p">(</span><span class="n">command</span><span class="p">,</span> <span class="n">argv</span><span class="p">,</span> <span class="n">stdin</span> <span class="o">=</span> <span class="bp">None</span><span class="p">,</span> <span class="n">stdout</span> <span class="o">=</span> <span class="bp">None</span><span class="p">,</span>
<span class="n">stderr</span> <span class="o">=</span> <span class="bp">None</span><span class="p">,</span> <span class="n">root</span> <span class="o">=</span> <span class="bp">None</span><span class="p">,</span> <span class="n">preexec_fn</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">cwd</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span>
<span class="n">raise_err</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">callback_func</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">callback_args</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot; Run an external program and redirect the output to a file.</span>
<span class="sd"> @param command The command to run.</span>
<span class="sd"> @param argv A list of arguments.</span>
<span class="sd"> @param stdin The file descriptor to read stdin from.</span>
<span class="sd"> @param stdout The file descriptor to redirect stdout to.</span>
<span class="sd"> @param stderr The file descriptor to redirect stderr to.</span>
<span class="sd"> @param root The directory to chroot to before running command.</span>
<span class="sd"> @param preexec_fn function to pass to Popen</span>
<span class="sd"> @param cwd working directory to pass to Popen</span>
<span class="sd"> @param raise_err raise CalledProcessError when the returncode is not 0</span>
<span class="sd"> @return The return code of command.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">def</span> <span class="nf">chroot</span> <span class="p">():</span>
<span class="n">os</span><span class="o">.</span><span class="n">chroot</span><span class="p">(</span><span class="n">root</span><span class="p">)</span>
<span class="n">stdinclose</span> <span class="o">=</span> <span class="n">stdoutclose</span> <span class="o">=</span> <span class="n">stderrclose</span> <span class="o">=</span> <span class="k">lambda</span> <span class="p">:</span> <span class="bp">None</span>
<span class="n">argv</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">argv</span><span class="p">)</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">stdin</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
<span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">access</span><span class="p">(</span><span class="n">stdin</span><span class="p">,</span> <span class="n">os</span><span class="o">.</span><span class="n">R_OK</span><span class="p">):</span>
<span class="n">stdin</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="n">stdin</span><span class="p">,</span> <span class="n">os</span><span class="o">.</span><span class="n">O_RDONLY</span><span class="p">)</span>
<span class="n">stdinclose</span> <span class="o">=</span> <span class="k">lambda</span> <span class="p">:</span> <span class="n">os</span><span class="o">.</span><span class="n">close</span><span class="p">(</span><span class="n">stdin</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">stdin</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">stdin</span><span class="o">.</span><span class="n">fileno</span><span class="p">()</span>
<span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">stdin</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
<span class="k">pass</span>
<span class="k">elif</span> <span class="n">stdin</span> <span class="ow">is</span> <span class="bp">None</span> <span class="ow">or</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">stdin</span><span class="p">,</span> <span class="nb">file</span><span class="p">):</span>
<span class="n">stdin</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">stdin</span><span class="o">.</span><span class="n">fileno</span><span class="p">()</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">stdout</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
<span class="n">stdout</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="n">stdout</span><span class="p">,</span> <span class="n">os</span><span class="o">.</span><span class="n">O_RDWR</span><span class="o">|</span><span class="n">os</span><span class="o">.</span><span class="n">O_CREAT</span><span class="p">)</span>
<span class="n">stdoutclose</span> <span class="o">=</span> <span class="k">lambda</span> <span class="p">:</span> <span class="n">os</span><span class="o">.</span><span class="n">close</span><span class="p">(</span><span class="n">stdout</span><span class="p">)</span>
<span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">stdout</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
<span class="k">pass</span>
<span class="k">elif</span> <span class="n">stdout</span> <span class="ow">is</span> <span class="bp">None</span> <span class="ow">or</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">stdout</span><span class="p">,</span> <span class="nb">file</span><span class="p">):</span>
<span class="n">stdout</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">stdout</span><span class="o">.</span><span class="n">fileno</span><span class="p">()</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
<span class="n">stderr</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="n">os</span><span class="o">.</span><span class="n">O_RDWR</span><span class="o">|</span><span class="n">os</span><span class="o">.</span><span class="n">O_CREAT</span><span class="p">)</span>
<span class="n">stderrclose</span> <span class="o">=</span> <span class="k">lambda</span> <span class="p">:</span> <span class="n">os</span><span class="o">.</span><span class="n">close</span><span class="p">(</span><span class="n">stderr</span><span class="p">)</span>
<span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
<span class="k">pass</span>
<span class="k">elif</span> <span class="n">stderr</span> <span class="ow">is</span> <span class="bp">None</span> <span class="ow">or</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="nb">file</span><span class="p">):</span>
<span class="n">stderr</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="o">.</span><span class="n">fileno</span><span class="p">()</span>
<span class="n">program_log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;Running... </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="s">&quot; &quot;</span><span class="o">.</span><span class="n">join</span><span class="p">([</span><span class="n">command</span><span class="p">]</span> <span class="o">+</span> <span class="n">argv</span><span class="p">))</span>
<span class="c">#prepare os pipes for feeding tee proceses</span>
<span class="n">pstdout</span><span class="p">,</span> <span class="n">pstdin</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">pipe</span><span class="p">()</span>
<span class="n">perrout</span><span class="p">,</span> <span class="n">perrin</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">pipe</span><span class="p">()</span>
<span class="n">env</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
<span class="n">env</span><span class="o">.</span><span class="n">update</span><span class="p">({</span><span class="s">&quot;LC_ALL&quot;</span><span class="p">:</span> <span class="s">&quot;C&quot;</span><span class="p">})</span>
<span class="k">if</span> <span class="n">root</span><span class="p">:</span>
<span class="n">preexec_fn</span> <span class="o">=</span> <span class="n">chroot</span>
<span class="n">cwd</span> <span class="o">=</span> <span class="n">root</span>
<span class="n">program_log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;chrooting into </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">cwd</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">cwd</span><span class="p">:</span>
<span class="n">program_log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;chdiring into </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">cwd</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="c">#prepare tee proceses</span>
<span class="n">proc_std</span> <span class="o">=</span> <span class="n">tee</span><span class="p">(</span><span class="n">pstdout</span><span class="p">,</span> <span class="n">stdout</span><span class="p">,</span> <span class="n">program_log</span><span class="o">.</span><span class="n">info</span><span class="p">,</span> <span class="n">command</span><span class="p">)</span>
<span class="n">proc_err</span> <span class="o">=</span> <span class="n">tee</span><span class="p">(</span><span class="n">perrout</span><span class="p">,</span> <span class="n">stderr</span><span class="p">,</span> <span class="n">program_log</span><span class="o">.</span><span class="n">error</span><span class="p">,</span> <span class="n">command</span><span class="p">)</span>
<span class="c">#start monitoring the outputs</span>
<span class="n">proc_std</span><span class="o">.</span><span class="n">start</span><span class="p">()</span>
<span class="n">proc_err</span><span class="o">.</span><span class="n">start</span><span class="p">()</span>
<span class="n">proc</span> <span class="o">=</span> <span class="n">subprocess</span><span class="o">.</span><span class="n">Popen</span><span class="p">([</span><span class="n">command</span><span class="p">]</span> <span class="o">+</span> <span class="n">argv</span><span class="p">,</span> <span class="n">stdin</span><span class="o">=</span><span class="n">stdin</span><span class="p">,</span>
<span class="n">stdout</span><span class="o">=</span><span class="n">pstdin</span><span class="p">,</span>
<span class="n">stderr</span><span class="o">=</span><span class="n">perrin</span><span class="p">,</span>
<span class="n">preexec_fn</span><span class="o">=</span><span class="n">preexec_fn</span><span class="p">,</span> <span class="n">cwd</span><span class="o">=</span><span class="n">cwd</span><span class="p">,</span>
<span class="n">env</span><span class="o">=</span><span class="n">env</span><span class="p">)</span>
<span class="c"># Wait for the process to finish, calling callback_func to test for early termination</span>
<span class="k">while</span> <span class="n">proc</span><span class="o">.</span><span class="n">returncode</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span>
<span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>
<span class="k">if</span> <span class="n">callback_func</span> <span class="ow">and</span> <span class="n">callback_func</span><span class="p">():</span>
<span class="n">proc</span><span class="o">.</span><span class="n">terminate</span><span class="p">()</span>
<span class="n">callback_func</span> <span class="o">=</span> <span class="bp">None</span>
<span class="n">proc</span><span class="o">.</span><span class="n">poll</span><span class="p">()</span>
<span class="n">ret</span> <span class="o">=</span> <span class="n">proc</span><span class="o">.</span><span class="n">returncode</span>
<span class="c">#close the input ends of pipes so we get EOF in the tee processes</span>
<span class="n">os</span><span class="o">.</span><span class="n">close</span><span class="p">(</span><span class="n">pstdin</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">close</span><span class="p">(</span><span class="n">perrin</span><span class="p">)</span>
<span class="c">#wait for the output to be written and destroy them</span>
<span class="n">proc_std</span><span class="o">.</span><span class="n">join</span><span class="p">()</span>
<span class="k">del</span> <span class="n">proc_std</span>
<span class="n">proc_err</span><span class="o">.</span><span class="n">join</span><span class="p">()</span>
<span class="k">del</span> <span class="n">proc_err</span>
<span class="n">stdinclose</span><span class="p">()</span>
<span class="n">stdoutclose</span><span class="p">()</span>
<span class="n">stderrclose</span><span class="p">()</span>
<span class="k">except</span> <span class="ne">OSError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="n">errstr</span> <span class="o">=</span> <span class="s">&quot;Error running </span><span class="si">%s</span><span class="s">: </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">command</span><span class="p">,</span> <span class="n">e</span><span class="o">.</span><span class="n">strerror</span><span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="n">errstr</span><span class="p">)</span>
<span class="n">program_log</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="n">errstr</span><span class="p">)</span>
<span class="c">#close the input ends of pipes so we get EOF in the tee processes</span>
<span class="n">os</span><span class="o">.</span><span class="n">close</span><span class="p">(</span><span class="n">pstdin</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">close</span><span class="p">(</span><span class="n">perrin</span><span class="p">)</span>
<span class="n">proc_std</span><span class="o">.</span><span class="n">join</span><span class="p">()</span>
<span class="n">proc_err</span><span class="o">.</span><span class="n">join</span><span class="p">()</span>
<span class="n">stdinclose</span><span class="p">()</span>
<span class="n">stdoutclose</span><span class="p">()</span>
<span class="n">stderrclose</span><span class="p">()</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">,</span> <span class="n">errstr</span>
<span class="k">if</span> <span class="n">ret</span> <span class="ow">and</span> <span class="n">raise_err</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">subprocess</span><span class="o">.</span><span class="n">CalledProcessError</span><span class="p">(</span><span class="n">ret</span><span class="p">,</span> <span class="p">[</span><span class="n">command</span><span class="p">]</span><span class="o">+</span><span class="n">argv</span><span class="p">)</span>
<span class="k">return</span> <span class="n">ret</span>
</div>
<div class="viewcode-block" id="execWithCapture"><a class="viewcode-back" href="../../pylorax.html#pylorax.executils.execWithCapture">[docs]</a><span class="k">def</span> <span class="nf">execWithCapture</span><span class="p">(</span><span class="n">command</span><span class="p">,</span> <span class="n">argv</span><span class="p">,</span> <span class="n">stdin</span> <span class="o">=</span> <span class="bp">None</span><span class="p">,</span> <span class="n">stderr</span> <span class="o">=</span> <span class="bp">None</span><span class="p">,</span> <span class="n">root</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span>
<span class="n">preexec_fn</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">cwd</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">raise_err</span><span class="o">=</span><span class="bp">False</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot; Run an external program and capture standard out.</span>
<span class="sd"> @param command The command to run.</span>
<span class="sd"> @param argv A list of arguments.</span>
<span class="sd"> @param stdin The file descriptor to read stdin from.</span>
<span class="sd"> @param stderr The file descriptor to redirect stderr to.</span>
<span class="sd"> @param root The directory to chroot to before running command.</span>
<span class="sd"> @param preexec_fn function to pass to Popen</span>
<span class="sd"> @param cwd working directory to pass to Popen</span>
<span class="sd"> @param raise_err raise CalledProcessError when the returncode is not 0</span>
<span class="sd"> @return The output of command from stdout.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">def</span> <span class="nf">chroot</span><span class="p">():</span>
<span class="n">os</span><span class="o">.</span><span class="n">chroot</span><span class="p">(</span><span class="n">root</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">closefds</span> <span class="p">():</span>
<span class="n">stdinclose</span><span class="p">()</span>
<span class="n">stderrclose</span><span class="p">()</span>
<span class="n">stdinclose</span> <span class="o">=</span> <span class="n">stderrclose</span> <span class="o">=</span> <span class="k">lambda</span> <span class="p">:</span> <span class="bp">None</span>
<span class="n">rc</span> <span class="o">=</span> <span class="s">&quot;&quot;</span>
<span class="n">argv</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">argv</span><span class="p">)</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">stdin</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
<span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">access</span><span class="p">(</span><span class="n">stdin</span><span class="p">,</span> <span class="n">os</span><span class="o">.</span><span class="n">R_OK</span><span class="p">):</span>
<span class="n">stdin</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="n">stdin</span><span class="p">,</span> <span class="n">os</span><span class="o">.</span><span class="n">O_RDONLY</span><span class="p">)</span>
<span class="n">stdinclose</span> <span class="o">=</span> <span class="k">lambda</span> <span class="p">:</span> <span class="n">os</span><span class="o">.</span><span class="n">close</span><span class="p">(</span><span class="n">stdin</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">stdin</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">stdin</span><span class="o">.</span><span class="n">fileno</span><span class="p">()</span>
<span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">stdin</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
<span class="k">pass</span>
<span class="k">elif</span> <span class="n">stdin</span> <span class="ow">is</span> <span class="bp">None</span> <span class="ow">or</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">stdin</span><span class="p">,</span> <span class="nb">file</span><span class="p">):</span>
<span class="n">stdin</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">stdin</span><span class="o">.</span><span class="n">fileno</span><span class="p">()</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
<span class="n">stderr</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="n">os</span><span class="o">.</span><span class="n">O_RDWR</span><span class="o">|</span><span class="n">os</span><span class="o">.</span><span class="n">O_CREAT</span><span class="p">)</span>
<span class="n">stderrclose</span> <span class="o">=</span> <span class="k">lambda</span> <span class="p">:</span> <span class="n">os</span><span class="o">.</span><span class="n">close</span><span class="p">(</span><span class="n">stderr</span><span class="p">)</span>
<span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
<span class="k">pass</span>
<span class="k">elif</span> <span class="n">stderr</span> <span class="ow">is</span> <span class="bp">None</span> <span class="ow">or</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="nb">file</span><span class="p">):</span>
<span class="n">stderr</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="o">.</span><span class="n">fileno</span><span class="p">()</span>
<span class="n">program_log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;Running... </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="s">&quot; &quot;</span><span class="o">.</span><span class="n">join</span><span class="p">([</span><span class="n">command</span><span class="p">]</span> <span class="o">+</span> <span class="n">argv</span><span class="p">))</span>
<span class="n">env</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
<span class="n">env</span><span class="o">.</span><span class="n">update</span><span class="p">({</span><span class="s">&quot;LC_ALL&quot;</span><span class="p">:</span> <span class="s">&quot;C&quot;</span><span class="p">})</span>
<span class="k">if</span> <span class="n">root</span><span class="p">:</span>
<span class="n">preexec_fn</span> <span class="o">=</span> <span class="n">chroot</span>
<span class="n">cwd</span> <span class="o">=</span> <span class="n">root</span>
<span class="n">program_log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;chrooting into </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">cwd</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">cwd</span><span class="p">:</span>
<span class="n">program_log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;chdiring into </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">cwd</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">proc</span> <span class="o">=</span> <span class="n">subprocess</span><span class="o">.</span><span class="n">Popen</span><span class="p">([</span><span class="n">command</span><span class="p">]</span> <span class="o">+</span> <span class="n">argv</span><span class="p">,</span> <span class="n">stdin</span><span class="o">=</span><span class="n">stdin</span><span class="p">,</span>
<span class="n">stdout</span><span class="o">=</span><span class="n">subprocess</span><span class="o">.</span><span class="n">PIPE</span><span class="p">,</span>
<span class="n">stderr</span><span class="o">=</span><span class="n">subprocess</span><span class="o">.</span><span class="n">PIPE</span><span class="p">,</span>
<span class="n">preexec_fn</span><span class="o">=</span><span class="n">preexec_fn</span><span class="p">,</span> <span class="n">cwd</span><span class="o">=</span><span class="n">cwd</span><span class="p">,</span>
<span class="n">env</span><span class="o">=</span><span class="n">env</span><span class="p">)</span>
<span class="k">while</span> <span class="bp">True</span><span class="p">:</span>
<span class="p">(</span><span class="n">outStr</span><span class="p">,</span> <span class="n">errStr</span><span class="p">)</span> <span class="o">=</span> <span class="n">proc</span><span class="o">.</span><span class="n">communicate</span><span class="p">()</span>
<span class="k">if</span> <span class="n">outStr</span><span class="p">:</span>
<span class="nb">map</span><span class="p">(</span><span class="n">program_log</span><span class="o">.</span><span class="n">info</span><span class="p">,</span> <span class="n">outStr</span><span class="o">.</span><span class="n">splitlines</span><span class="p">())</span>
<span class="n">rc</span> <span class="o">+=</span> <span class="n">outStr</span>
<span class="k">if</span> <span class="n">errStr</span><span class="p">:</span>
<span class="nb">map</span><span class="p">(</span><span class="n">program_log</span><span class="o">.</span><span class="n">error</span><span class="p">,</span> <span class="n">errStr</span><span class="o">.</span><span class="n">splitlines</span><span class="p">())</span>
<span class="n">os</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="n">errStr</span><span class="p">)</span>
<span class="k">if</span> <span class="n">proc</span><span class="o">.</span><span class="n">returncode</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span>
<span class="k">break</span>
<span class="k">except</span> <span class="ne">OSError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="n">log</span><span class="o">.</span><span class="n">error</span> <span class="p">(</span><span class="s">&quot;Error running &quot;</span> <span class="o">+</span> <span class="n">command</span> <span class="o">+</span> <span class="s">&quot;: &quot;</span> <span class="o">+</span> <span class="n">e</span><span class="o">.</span><span class="n">strerror</span><span class="p">)</span>
<span class="n">closefds</span><span class="p">()</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">,</span> <span class="s">&quot;Error running &quot;</span> <span class="o">+</span> <span class="n">command</span> <span class="o">+</span> <span class="s">&quot;: &quot;</span> <span class="o">+</span> <span class="n">e</span><span class="o">.</span><span class="n">strerror</span>
<span class="n">closefds</span><span class="p">()</span>
<span class="k">if</span> <span class="n">proc</span><span class="o">.</span><span class="n">returncode</span> <span class="ow">and</span> <span class="n">raise_err</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">subprocess</span><span class="o">.</span><span class="n">CalledProcessError</span><span class="p">(</span><span class="n">proc</span><span class="o">.</span><span class="n">returncode</span><span class="p">,</span> <span class="p">[</span><span class="n">command</span><span class="p">]</span><span class="o">+</span><span class="n">argv</span><span class="p">)</span>
<span class="k">return</span> <span class="n">rc</span>
</div>
<div class="viewcode-block" id="execWithCallback"><a class="viewcode-back" href="../../pylorax.html#pylorax.executils.execWithCallback">[docs]</a><span class="k">def</span> <span class="nf">execWithCallback</span><span class="p">(</span><span class="n">command</span><span class="p">,</span> <span class="n">argv</span><span class="p">,</span> <span class="n">stdin</span> <span class="o">=</span> <span class="bp">None</span><span class="p">,</span> <span class="n">stdout</span> <span class="o">=</span> <span class="bp">None</span><span class="p">,</span>
<span class="n">stderr</span> <span class="o">=</span> <span class="bp">None</span><span class="p">,</span> <span class="n">echo</span> <span class="o">=</span> <span class="bp">True</span><span class="p">,</span> <span class="n">callback</span> <span class="o">=</span> <span class="bp">None</span><span class="p">,</span>
<span class="n">callback_data</span> <span class="o">=</span> <span class="bp">None</span><span class="p">,</span> <span class="n">root</span> <span class="o">=</span> <span class="s">&#39;/&#39;</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">closefds</span> <span class="p">():</span>
<span class="n">stdinclose</span><span class="p">()</span>
<span class="n">stdoutclose</span><span class="p">()</span>
<span class="n">stderrclose</span><span class="p">()</span>
<span class="n">stdinclose</span> <span class="o">=</span> <span class="n">stdoutclose</span> <span class="o">=</span> <span class="n">stderrclose</span> <span class="o">=</span> <span class="k">lambda</span> <span class="p">:</span> <span class="bp">None</span>
<span class="n">argv</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">argv</span><span class="p">)</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">stdin</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
<span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">access</span><span class="p">(</span><span class="n">stdin</span><span class="p">,</span> <span class="n">os</span><span class="o">.</span><span class="n">R_OK</span><span class="p">):</span>
<span class="n">stdin</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="n">stdin</span><span class="p">,</span> <span class="n">os</span><span class="o">.</span><span class="n">O_RDONLY</span><span class="p">)</span>
<span class="n">stdinclose</span> <span class="o">=</span> <span class="k">lambda</span> <span class="p">:</span> <span class="n">os</span><span class="o">.</span><span class="n">close</span><span class="p">(</span><span class="n">stdin</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">stdin</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">stdin</span><span class="o">.</span><span class="n">fileno</span><span class="p">()</span>
<span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">stdin</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
<span class="k">pass</span>
<span class="k">elif</span> <span class="n">stdin</span> <span class="ow">is</span> <span class="bp">None</span> <span class="ow">or</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">stdin</span><span class="p">,</span> <span class="nb">file</span><span class="p">):</span>
<span class="n">stdin</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">stdin</span><span class="o">.</span><span class="n">fileno</span><span class="p">()</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">stdout</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
<span class="n">stdout</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="n">stdout</span><span class="p">,</span> <span class="n">os</span><span class="o">.</span><span class="n">O_RDWR</span><span class="o">|</span><span class="n">os</span><span class="o">.</span><span class="n">O_CREAT</span><span class="p">)</span>
<span class="n">stdoutclose</span> <span class="o">=</span> <span class="k">lambda</span> <span class="p">:</span> <span class="n">os</span><span class="o">.</span><span class="n">close</span><span class="p">(</span><span class="n">stdout</span><span class="p">)</span>
<span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">stdout</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
<span class="k">pass</span>
<span class="k">elif</span> <span class="n">stdout</span> <span class="ow">is</span> <span class="bp">None</span> <span class="ow">or</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">stdout</span><span class="p">,</span> <span class="nb">file</span><span class="p">):</span>
<span class="n">stdout</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">stdout</span><span class="o">.</span><span class="n">fileno</span><span class="p">()</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
<span class="n">stderr</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="n">os</span><span class="o">.</span><span class="n">O_RDWR</span><span class="o">|</span><span class="n">os</span><span class="o">.</span><span class="n">O_CREAT</span><span class="p">)</span>
<span class="n">stderrclose</span> <span class="o">=</span> <span class="k">lambda</span> <span class="p">:</span> <span class="n">os</span><span class="o">.</span><span class="n">close</span><span class="p">(</span><span class="n">stderr</span><span class="p">)</span>
<span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
<span class="k">pass</span>
<span class="k">elif</span> <span class="n">stderr</span> <span class="ow">is</span> <span class="bp">None</span> <span class="ow">or</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="nb">file</span><span class="p">):</span>
<span class="n">stderr</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="o">.</span><span class="n">fileno</span><span class="p">()</span>
<span class="n">program_log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;Running... </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="s">&quot; &quot;</span><span class="o">.</span><span class="n">join</span><span class="p">([</span><span class="n">command</span><span class="p">]</span> <span class="o">+</span> <span class="n">argv</span><span class="p">))</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">pipe</span><span class="p">()</span>
<span class="n">p_stderr</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">pipe</span><span class="p">()</span>
<span class="n">childpid</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">fork</span><span class="p">()</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">childpid</span><span class="p">:</span>
<span class="n">os</span><span class="o">.</span><span class="n">close</span><span class="p">(</span><span class="n">p</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
<span class="n">os</span><span class="o">.</span><span class="n">close</span><span class="p">(</span><span class="n">p_stderr</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
<span class="n">os</span><span class="o">.</span><span class="n">dup2</span><span class="p">(</span><span class="n">p</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="mi">1</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">dup2</span><span class="p">(</span><span class="n">p_stderr</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="mi">2</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">dup2</span><span class="p">(</span><span class="n">stdin</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">close</span><span class="p">(</span><span class="n">stdin</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">close</span><span class="p">(</span><span class="n">p</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
<span class="n">os</span><span class="o">.</span><span class="n">close</span><span class="p">(</span><span class="n">p_stderr</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
<span class="n">os</span><span class="o">.</span><span class="n">execvp</span><span class="p">(</span><span class="n">command</span><span class="p">,</span> <span class="p">[</span><span class="n">command</span><span class="p">]</span> <span class="o">+</span> <span class="n">argv</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">_exit</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">close</span><span class="p">(</span><span class="n">p</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
<span class="n">os</span><span class="o">.</span><span class="n">close</span><span class="p">(</span><span class="n">p_stderr</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
<span class="n">log_output</span> <span class="o">=</span> <span class="s">&#39;&#39;</span>
<span class="k">while</span> <span class="mi">1</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">s</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="n">p</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="mi">1</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">OSError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="k">if</span> <span class="n">e</span><span class="o">.</span><span class="n">errno</span> <span class="o">!=</span> <span class="mi">4</span><span class="p">:</span>
<span class="nb">map</span><span class="p">(</span><span class="n">program_log</span><span class="o">.</span><span class="n">info</span><span class="p">,</span> <span class="n">log_output</span><span class="o">.</span><span class="n">splitlines</span><span class="p">())</span>
<span class="k">raise</span> <span class="ne">IOError</span><span class="p">,</span> <span class="n">e</span><span class="o">.</span><span class="n">args</span>
<span class="k">if</span> <span class="n">echo</span><span class="p">:</span>
<span class="n">os</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">stdout</span><span class="p">,</span> <span class="n">s</span><span class="p">)</span>
<span class="n">log_output</span> <span class="o">+=</span> <span class="n">s</span>
<span class="k">if</span> <span class="n">callback</span><span class="p">:</span>
<span class="n">callback</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">callback_data</span><span class="o">=</span><span class="n">callback_data</span><span class="p">)</span>
<span class="c"># break out early if the sub-process changes status.</span>
<span class="c"># no need to flush the stream if the process has exited</span>
<span class="k">try</span><span class="p">:</span>
<span class="p">(</span><span class="n">pid</span><span class="p">,</span> <span class="n">status</span><span class="p">)</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">waitpid</span><span class="p">(</span><span class="n">childpid</span><span class="p">,</span><span class="n">os</span><span class="o">.</span><span class="n">WNOHANG</span><span class="p">)</span>
<span class="k">if</span> <span class="n">pid</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span>
<span class="k">break</span>
<span class="k">except</span> <span class="ne">OSError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="n">log</span><span class="o">.</span><span class="n">critical</span><span class="p">(</span><span class="s">&quot;exception from waitpid: </span><span class="si">%s</span><span class="s"> </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">e</span><span class="o">.</span><span class="n">errno</span><span class="p">,</span> <span class="n">e</span><span class="o">.</span><span class="n">strerror</span><span class="p">)</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">s</span><span class="p">)</span> <span class="o">&lt;</span> <span class="mi">1</span><span class="p">:</span>
<span class="k">break</span>
<span class="nb">map</span><span class="p">(</span><span class="n">program_log</span><span class="o">.</span><span class="n">info</span><span class="p">,</span> <span class="n">log_output</span><span class="o">.</span><span class="n">splitlines</span><span class="p">())</span>
<span class="n">log_errors</span> <span class="o">=</span> <span class="s">&#39;&#39;</span>
<span class="k">while</span> <span class="mi">1</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">err</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="n">p_stderr</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="mi">128</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">OSError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="k">if</span> <span class="n">e</span><span class="o">.</span><span class="n">errno</span> <span class="o">!=</span> <span class="mi">4</span><span class="p">:</span>
<span class="nb">map</span><span class="p">(</span><span class="n">program_log</span><span class="o">.</span><span class="n">error</span><span class="p">,</span> <span class="n">log_errors</span><span class="o">.</span><span class="n">splitlines</span><span class="p">())</span>
<span class="k">raise</span> <span class="ne">IOError</span><span class="p">,</span> <span class="n">e</span><span class="o">.</span><span class="n">args</span>
<span class="k">break</span>
<span class="n">log_errors</span> <span class="o">+=</span> <span class="n">err</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">err</span><span class="p">)</span> <span class="o">&lt;</span> <span class="mi">1</span><span class="p">:</span>
<span class="k">break</span>
<span class="n">os</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="n">log_errors</span><span class="p">)</span>
<span class="nb">map</span><span class="p">(</span><span class="n">program_log</span><span class="o">.</span><span class="n">error</span><span class="p">,</span> <span class="n">log_errors</span><span class="o">.</span><span class="n">splitlines</span><span class="p">())</span>
<span class="n">os</span><span class="o">.</span><span class="n">close</span><span class="p">(</span><span class="n">p</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
<span class="n">os</span><span class="o">.</span><span class="n">close</span><span class="p">(</span><span class="n">p_stderr</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
<span class="k">try</span><span class="p">:</span>
<span class="c">#if we didn&#39;t already get our child&#39;s exit status above, do so now.</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">pid</span><span class="p">:</span>
<span class="p">(</span><span class="n">pid</span><span class="p">,</span> <span class="n">status</span><span class="p">)</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">waitpid</span><span class="p">(</span><span class="n">childpid</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">OSError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="n">log</span><span class="o">.</span><span class="n">critical</span><span class="p">(</span><span class="s">&quot;exception from waitpid: </span><span class="si">%s</span><span class="s"> </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">e</span><span class="o">.</span><span class="n">errno</span><span class="p">,</span> <span class="n">e</span><span class="o">.</span><span class="n">strerror</span><span class="p">)</span>
<span class="n">closefds</span><span class="p">()</span>
<span class="n">rc</span> <span class="o">=</span> <span class="mi">1</span>
<span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">WIFEXITED</span><span class="p">(</span><span class="n">status</span><span class="p">):</span>
<span class="n">rc</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">WEXITSTATUS</span><span class="p">(</span><span class="n">status</span><span class="p">)</span>
<span class="k">return</span> <span class="n">ExecProduct</span><span class="p">(</span><span class="n">rc</span><span class="p">,</span> <span class="n">log_output</span> <span class="p">,</span> <span class="n">log_errors</span><span class="p">)</span>
</div>
<span class="k">def</span> <span class="nf">_pulseProgressCallback</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">callback_data</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
<span class="k">if</span> <span class="n">callback_data</span><span class="p">:</span>
<span class="n">callback_data</span><span class="o">.</span><span class="n">pulse</span><span class="p">()</span>
<div class="viewcode-block" id="execWithPulseProgress"><a class="viewcode-back" href="../../pylorax.html#pylorax.executils.execWithPulseProgress">[docs]</a><span class="k">def</span> <span class="nf">execWithPulseProgress</span><span class="p">(</span><span class="n">command</span><span class="p">,</span> <span class="n">argv</span><span class="p">,</span> <span class="n">stdin</span> <span class="o">=</span> <span class="bp">None</span><span class="p">,</span> <span class="n">stdout</span> <span class="o">=</span> <span class="bp">None</span><span class="p">,</span>
<span class="n">stderr</span> <span class="o">=</span> <span class="bp">None</span><span class="p">,</span> <span class="n">echo</span> <span class="o">=</span> <span class="bp">True</span><span class="p">,</span> <span class="n">progress</span> <span class="o">=</span> <span class="bp">None</span><span class="p">,</span>
<span class="n">root</span> <span class="o">=</span> <span class="s">&#39;/&#39;</span><span class="p">):</span>
<span class="k">return</span> <span class="n">execWithCallback</span><span class="p">(</span><span class="n">command</span><span class="p">,</span> <span class="n">argv</span><span class="p">,</span> <span class="n">stdin</span><span class="o">=</span><span class="n">stdin</span><span class="p">,</span> <span class="n">stdout</span><span class="o">=</span><span class="n">stdout</span><span class="p">,</span>
<span class="n">stderr</span><span class="o">=</span><span class="n">stderr</span><span class="p">,</span> <span class="n">echo</span><span class="o">=</span><span class="n">echo</span><span class="p">,</span> <span class="n">callback</span><span class="o">=</span><span class="n">_pulseProgressCallback</span><span class="p">,</span>
<span class="n">callback_data</span><span class="o">=</span><span class="n">progress</span><span class="p">,</span> <span class="n">root</span><span class="o">=</span><span class="n">root</span><span class="p">)</span>
<span class="c">## Run a shell.</span></div>
<div class="viewcode-block" id="execConsole"><a class="viewcode-back" href="../../pylorax.html#pylorax.executils.execConsole">[docs]</a><span class="k">def</span> <span class="nf">execConsole</span><span class="p">():</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">proc</span> <span class="o">=</span> <span class="n">subprocess</span><span class="o">.</span><span class="n">Popen</span><span class="p">([</span><span class="s">&quot;/bin/sh&quot;</span><span class="p">])</span>
<span class="n">proc</span><span class="o">.</span><span class="n">wait</span><span class="p">()</span>
<span class="k">except</span> <span class="ne">OSError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">,</span> <span class="s">&quot;Error running /bin/sh: &quot;</span> <span class="o">+</span> <span class="n">e</span><span class="o">.</span><span class="n">strerror</span>
</div>
<div class="viewcode-block" id="runcmd"><a class="viewcode-back" href="../../pylorax.html#pylorax.executils.runcmd">[docs]</a><span class="k">def</span> <span class="nf">runcmd</span><span class="p">(</span><span class="n">cmd</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot; run execWithRedirect with raise_err=True</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">kwargs</span><span class="p">[</span><span class="s">&quot;raise_err&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="bp">True</span>
<span class="k">return</span> <span class="n">execWithRedirect</span><span class="p">(</span><span class="n">cmd</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">cmd</span><span class="p">[</span><span class="mi">1</span><span class="p">:],</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="runcmd_output"><a class="viewcode-back" href="../../pylorax.html#pylorax.executils.runcmd_output">[docs]</a><span class="k">def</span> <span class="nf">runcmd_output</span><span class="p">(</span><span class="n">cmd</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot; run execWithCapture with raise_err=True</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">kwargs</span><span class="p">[</span><span class="s">&quot;raise_err&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="bp">True</span>
<span class="k">return</span> <span class="n">execWithCapture</span><span class="p">(</span><span class="n">cmd</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">cmd</span><span class="p">[</span><span class="mi">1</span><span class="p">:],</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
</pre></div></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">Lorax 19.7.10 documentation</a> &raquo;</li>
<li><a href="../index.html" >Module code</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2017, Red Hat, Inc..
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>

View File

@ -0,0 +1,559 @@
<!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>pylorax.imgutils &mdash; Lorax 19.7.10 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: '19.7.10',
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>
<link rel="top" title="Lorax 19.7.10 documentation" href="../../index.html" />
<link rel="up" title="Module code" href="../index.html" />
</head>
<body>
<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">Lorax 19.7.10 documentation</a> &raquo;</li>
<li><a href="../index.html" accesskey="U">Module code</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<h1>Source code for pylorax.imgutils</h1><div class="highlight"><pre>
<span class="c"># imgutils.py - utility functions/classes for building disk images</span>
<span class="c">#</span>
<span class="c"># Copyright (C) 2011 Red Hat, Inc.</span>
<span class="c">#</span>
<span class="c"># This program is free software; you can redistribute it and/or modify</span>
<span class="c"># it under the terms of the GNU General Public License as published by</span>
<span class="c"># the Free Software Foundation; either version 2 of the License, or</span>
<span class="c"># (at your option) any later version.</span>
<span class="c">#</span>
<span class="c"># This program is distributed in the hope that it will be useful,</span>
<span class="c"># but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<span class="c"># MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span>
<span class="c"># GNU General Public License for more details.</span>
<span class="c">#</span>
<span class="c"># You should have received a copy of the GNU General Public License</span>
<span class="c"># along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;.</span>
<span class="c">#</span>
<span class="c"># Author(s): Will Woods &lt;wwoods@redhat.com&gt;</span>
<span class="kn">import</span> <span class="nn">logging</span>
<span class="n">logger</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s">&quot;pylorax.imgutils&quot;</span><span class="p">)</span>
<span class="kn">import</span> <span class="nn">os</span><span class="o">,</span> <span class="nn">tempfile</span>
<span class="kn">from</span> <span class="nn">os.path</span> <span class="kn">import</span> <span class="n">join</span><span class="p">,</span> <span class="n">dirname</span>
<span class="kn">from</span> <span class="nn">subprocess</span> <span class="kn">import</span> <span class="n">Popen</span><span class="p">,</span> <span class="n">PIPE</span><span class="p">,</span> <span class="n">CalledProcessError</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">import</span> <span class="nn">time</span>
<span class="kn">import</span> <span class="nn">traceback</span>
<span class="kn">import</span> <span class="nn">multiprocessing</span>
<span class="kn">from</span> <span class="nn">time</span> <span class="kn">import</span> <span class="n">sleep</span>
<span class="kn">from</span> <span class="nn">pylorax.sysutils</span> <span class="kn">import</span> <span class="n">cpfile</span>
<span class="kn">from</span> <span class="nn">pylorax.executils</span> <span class="kn">import</span> <span class="n">execWithRedirect</span><span class="p">,</span> <span class="n">execWithCapture</span>
<span class="kn">from</span> <span class="nn">pylorax.executils</span> <span class="kn">import</span> <span class="n">runcmd</span><span class="p">,</span> <span class="n">runcmd_output</span>
<span class="c">######## Functions for making container images (cpio, tar, squashfs) ##########</span>
<div class="viewcode-block" id="compress"><a class="viewcode-back" href="../../pylorax.html#pylorax.imgutils.compress">[docs]</a><span class="k">def</span> <span class="nf">compress</span><span class="p">(</span><span class="n">command</span><span class="p">,</span> <span class="n">rootdir</span><span class="p">,</span> <span class="n">outfile</span><span class="p">,</span> <span class="n">compression</span><span class="o">=</span><span class="s">&quot;xz&quot;</span><span class="p">,</span> <span class="n">compressargs</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;Make a compressed archive of the given rootdir.</span>
<span class="sd"> command is a list of the archiver commands to run</span>
<span class="sd"> compression should be &quot;xz&quot;, &quot;gzip&quot;, &quot;lzma&quot;, &quot;bzip2&quot;, or None.</span>
<span class="sd"> compressargs will be used on the compression commandline.&#39;&#39;&#39;</span>
<span class="k">if</span> <span class="n">compressargs</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span>
<span class="n">compressargs</span> <span class="o">=</span> <span class="p">[</span><span class="s">&quot;-9&quot;</span><span class="p">]</span>
<span class="k">if</span> <span class="n">compression</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">(</span><span class="bp">None</span><span class="p">,</span> <span class="s">&quot;xz&quot;</span><span class="p">,</span> <span class="s">&quot;gzip&quot;</span><span class="p">,</span> <span class="s">&quot;lzma&quot;</span><span class="p">,</span> <span class="s">&quot;bzip2&quot;</span><span class="p">):</span>
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">,</span> <span class="s">&quot;Unknown compression type </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">compression</span>
<span class="k">if</span> <span class="n">compression</span> <span class="o">==</span> <span class="s">&quot;xz&quot;</span><span class="p">:</span>
<span class="n">compressargs</span><span class="o">.</span><span class="n">insert</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="s">&quot;--check=crc32&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">compression</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span>
<span class="n">compression</span> <span class="o">=</span> <span class="s">&quot;cat&quot;</span> <span class="c"># this is a little silly</span>
<span class="n">compressargs</span> <span class="o">=</span> <span class="p">[]</span>
<span class="c"># make compression run with multiple threads if possible</span>
<span class="k">if</span> <span class="n">compression</span> <span class="ow">in</span> <span class="p">(</span><span class="s">&quot;xz&quot;</span><span class="p">,</span> <span class="s">&quot;lzma&quot;</span><span class="p">):</span>
<span class="n">compressargs</span><span class="o">.</span><span class="n">insert</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="s">&quot;-T</span><span class="si">%d</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">multiprocessing</span><span class="o">.</span><span class="n">cpu_count</span><span class="p">())</span>
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">&quot;find </span><span class="si">%s</span><span class="s"> -print0 |</span><span class="si">%s</span><span class="s"> | </span><span class="si">%s</span><span class="s"> </span><span class="si">%s</span><span class="s"> &gt; </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">rootdir</span><span class="p">,</span> <span class="s">&quot; &quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">command</span><span class="p">),</span>
<span class="n">compression</span><span class="p">,</span> <span class="s">&quot; &quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">compressargs</span><span class="p">),</span> <span class="n">outfile</span><span class="p">)</span>
<span class="n">find</span><span class="p">,</span> <span class="n">archive</span><span class="p">,</span> <span class="n">comp</span> <span class="o">=</span> <span class="bp">None</span><span class="p">,</span> <span class="bp">None</span><span class="p">,</span> <span class="bp">None</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">find</span> <span class="o">=</span> <span class="n">Popen</span><span class="p">([</span><span class="s">&quot;find&quot;</span><span class="p">,</span> <span class="s">&quot;.&quot;</span><span class="p">,</span> <span class="s">&quot;-print0&quot;</span><span class="p">],</span> <span class="n">stdout</span><span class="o">=</span><span class="n">PIPE</span><span class="p">,</span> <span class="n">cwd</span><span class="o">=</span><span class="n">rootdir</span><span class="p">)</span>
<span class="n">archive</span> <span class="o">=</span> <span class="n">Popen</span><span class="p">(</span><span class="n">command</span><span class="p">,</span> <span class="n">stdin</span><span class="o">=</span><span class="n">find</span><span class="o">.</span><span class="n">stdout</span><span class="p">,</span> <span class="n">stdout</span><span class="o">=</span><span class="n">PIPE</span><span class="p">,</span> <span class="n">cwd</span><span class="o">=</span><span class="n">rootdir</span><span class="p">)</span>
<span class="n">comp</span> <span class="o">=</span> <span class="n">Popen</span><span class="p">([</span><span class="n">compression</span><span class="p">]</span> <span class="o">+</span> <span class="n">compressargs</span><span class="p">,</span>
<span class="n">stdin</span><span class="o">=</span><span class="n">archive</span><span class="o">.</span><span class="n">stdout</span><span class="p">,</span> <span class="n">stdout</span><span class="o">=</span><span class="nb">open</span><span class="p">(</span><span class="n">outfile</span><span class="p">,</span> <span class="s">&quot;wb&quot;</span><span class="p">))</span>
<span class="p">(</span><span class="n">_stdout</span><span class="p">,</span> <span class="n">_stderr</span><span class="p">)</span> <span class="o">=</span> <span class="n">comp</span><span class="o">.</span><span class="n">communicate</span><span class="p">()</span>
<span class="k">return</span> <span class="n">comp</span><span class="o">.</span><span class="n">returncode</span>
<span class="k">except</span> <span class="ne">OSError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="n">e</span><span class="p">)</span>
<span class="c"># Kill off any hanging processes</span>
<span class="n">_</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span><span class="o">.</span><span class="n">kill</span><span class="p">()</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="p">(</span><span class="n">find</span><span class="p">,</span> <span class="n">archive</span><span class="p">,</span> <span class="n">comp</span><span class="p">)</span> <span class="k">if</span> <span class="n">p</span><span class="p">]</span>
<span class="k">return</span> <span class="mi">1</span>
</div>
<div class="viewcode-block" id="mkcpio"><a class="viewcode-back" href="../../pylorax.html#pylorax.imgutils.mkcpio">[docs]</a><span class="k">def</span> <span class="nf">mkcpio</span><span class="p">(</span><span class="n">rootdir</span><span class="p">,</span> <span class="n">outfile</span><span class="p">,</span> <span class="n">compression</span><span class="o">=</span><span class="s">&quot;xz&quot;</span><span class="p">,</span> <span class="n">compressargs</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
<span class="k">return</span> <span class="n">compress</span><span class="p">([</span><span class="s">&quot;cpio&quot;</span><span class="p">,</span> <span class="s">&quot;--null&quot;</span><span class="p">,</span> <span class="s">&quot;--quiet&quot;</span><span class="p">,</span> <span class="s">&quot;-H&quot;</span><span class="p">,</span> <span class="s">&quot;newc&quot;</span><span class="p">,</span> <span class="s">&quot;-o&quot;</span><span class="p">],</span>
<span class="n">rootdir</span><span class="p">,</span> <span class="n">outfile</span><span class="p">,</span> <span class="n">compression</span><span class="p">,</span> <span class="n">compressargs</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="mktar"><a class="viewcode-back" href="../../pylorax.html#pylorax.imgutils.mktar">[docs]</a><span class="k">def</span> <span class="nf">mktar</span><span class="p">(</span><span class="n">rootdir</span><span class="p">,</span> <span class="n">outfile</span><span class="p">,</span> <span class="n">compression</span><span class="o">=</span><span class="s">&quot;xz&quot;</span><span class="p">,</span> <span class="n">compressargs</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
<span class="k">return</span> <span class="n">compress</span><span class="p">([</span><span class="s">&quot;tar&quot;</span><span class="p">,</span> <span class="s">&quot;--no-recursion&quot;</span><span class="p">,</span> <span class="s">&quot;--selinux&quot;</span><span class="p">,</span> <span class="s">&quot;--acls&quot;</span><span class="p">,</span> <span class="s">&quot;--xattrs&quot;</span><span class="p">,</span> <span class="s">&quot;-cf-&quot;</span><span class="p">,</span> <span class="s">&quot;--null&quot;</span><span class="p">,</span> <span class="s">&quot;-T-&quot;</span><span class="p">],</span>
<span class="n">rootdir</span><span class="p">,</span> <span class="n">outfile</span><span class="p">,</span> <span class="n">compression</span><span class="p">,</span> <span class="n">compressargs</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="mksquashfs"><a class="viewcode-back" href="../../pylorax.html#pylorax.imgutils.mksquashfs">[docs]</a><span class="k">def</span> <span class="nf">mksquashfs</span><span class="p">(</span><span class="n">rootdir</span><span class="p">,</span> <span class="n">outfile</span><span class="p">,</span> <span class="n">compression</span><span class="o">=</span><span class="s">&quot;default&quot;</span><span class="p">,</span> <span class="n">compressargs</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;Make a squashfs image containing the given rootdir.&#39;&#39;&#39;</span>
<span class="k">if</span> <span class="n">compressargs</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span>
<span class="n">compressargs</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">if</span> <span class="n">compression</span> <span class="o">!=</span> <span class="s">&quot;default&quot;</span><span class="p">:</span>
<span class="n">compressargs</span> <span class="o">=</span> <span class="p">[</span><span class="s">&quot;-comp&quot;</span><span class="p">,</span> <span class="n">compression</span><span class="p">]</span> <span class="o">+</span> <span class="n">compressargs</span>
<span class="k">return</span> <span class="n">execWithRedirect</span><span class="p">(</span><span class="s">&quot;mksquashfs&quot;</span><span class="p">,</span> <span class="p">[</span><span class="n">rootdir</span><span class="p">,</span> <span class="n">outfile</span><span class="p">]</span> <span class="o">+</span> <span class="n">compressargs</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="mkrootfsimg"><a class="viewcode-back" href="../../pylorax.html#pylorax.imgutils.mkrootfsimg">[docs]</a><span class="k">def</span> <span class="nf">mkrootfsimg</span><span class="p">(</span><span class="n">rootdir</span><span class="p">,</span> <span class="n">outfile</span><span class="p">,</span> <span class="n">label</span><span class="p">,</span> <span class="n">size</span><span class="o">=</span><span class="mi">2</span><span class="p">,</span> <span class="n">sysroot</span><span class="o">=</span><span class="s">&quot;&quot;</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Make rootfs image from a directory</span>
<span class="sd"> :param str rootdir: Root directory</span>
<span class="sd"> :param str outfile: Path of output image file</span>
<span class="sd"> :param str label: Filesystem label</span>
<span class="sd"> :param int size: Size of the image in GiB, if None computed automatically</span>
<span class="sd"> :param str sysroot: path to system (deployment) root relative to physical root</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">size</span><span class="p">:</span>
<span class="n">fssize</span> <span class="o">=</span> <span class="n">size</span> <span class="o">*</span> <span class="p">(</span><span class="mi">1024</span><span class="o">*</span><span class="mi">1024</span><span class="o">*</span><span class="mi">1024</span><span class="p">)</span> <span class="c"># 2GB sparse file compresses down to nothin&#39;</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">fssize</span> <span class="o">=</span> <span class="bp">None</span> <span class="c"># Let mkext4img figure out the needed size</span>
<span class="n">mkext4img</span><span class="p">(</span><span class="n">rootdir</span><span class="p">,</span> <span class="n">outfile</span><span class="p">,</span> <span class="n">label</span><span class="o">=</span><span class="n">label</span><span class="p">,</span> <span class="n">size</span><span class="o">=</span><span class="n">fssize</span><span class="p">)</span>
<span class="c"># Reset selinux context on new rootfs</span>
<span class="k">with</span> <span class="n">LoopDev</span><span class="p">(</span><span class="n">outfile</span><span class="p">)</span> <span class="k">as</span> <span class="n">loopdev</span><span class="p">:</span>
<span class="k">with</span> <span class="n">Mount</span><span class="p">(</span><span class="n">loopdev</span><span class="p">)</span> <span class="k">as</span> <span class="n">mnt</span><span class="p">:</span>
<span class="n">cmd</span> <span class="o">=</span> <span class="p">[</span> <span class="s">&quot;setfiles&quot;</span><span class="p">,</span> <span class="s">&quot;-e&quot;</span><span class="p">,</span> <span class="s">&quot;/proc&quot;</span><span class="p">,</span> <span class="s">&quot;-e&quot;</span><span class="p">,</span> <span class="s">&quot;/sys&quot;</span><span class="p">,</span> <span class="s">&quot;-e&quot;</span><span class="p">,</span> <span class="s">&quot;/dev&quot;</span><span class="p">,</span> <span class="s">&quot;-e&quot;</span><span class="p">,</span> <span class="s">&quot;/install&quot;</span><span class="p">,</span>
<span class="s">&quot;/etc/selinux/targeted/contexts/files/file_contexts&quot;</span><span class="p">,</span> <span class="s">&quot;/&quot;</span><span class="p">]</span>
<span class="n">root</span> <span class="o">=</span> <span class="n">join</span><span class="p">(</span><span class="n">mnt</span><span class="p">,</span> <span class="n">sysroot</span><span class="o">.</span><span class="n">lstrip</span><span class="p">(</span><span class="s">&quot;/&quot;</span><span class="p">))</span>
<span class="n">runcmd</span><span class="p">(</span><span class="n">cmd</span><span class="p">,</span> <span class="n">root</span><span class="o">=</span><span class="n">root</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="mkdiskfsimage"><a class="viewcode-back" href="../../pylorax.html#pylorax.imgutils.mkdiskfsimage">[docs]</a><span class="k">def</span> <span class="nf">mkdiskfsimage</span><span class="p">(</span><span class="n">diskimage</span><span class="p">,</span> <span class="n">fsimage</span><span class="p">,</span> <span class="n">label</span><span class="o">=</span><span class="s">&quot;Anaconda&quot;</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Copy the / partition of a partitioned disk image to an un-partitioned</span>
<span class="sd"> disk image.</span>
<span class="sd"> diskimage is the full path to partitioned disk image with a /</span>
<span class="sd"> fsimage is the full path of the output fs image file</span>
<span class="sd"> label is the label to apply to the image. Defaults to &quot;Anaconda&quot;</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">with</span> <span class="n">PartitionMount</span><span class="p">(</span><span class="n">diskimage</span><span class="p">)</span> <span class="k">as</span> <span class="n">img_mount</span><span class="p">:</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">img_mount</span> <span class="ow">or</span> <span class="ow">not</span> <span class="n">img_mount</span><span class="o">.</span><span class="n">mount_dir</span><span class="p">:</span>
<span class="k">return</span> <span class="bp">None</span>
<span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;Creating fsimage </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">fsimage</span><span class="p">)</span>
<span class="n">mkext4img</span><span class="p">(</span><span class="n">img_mount</span><span class="o">.</span><span class="n">mount_dir</span><span class="p">,</span> <span class="n">fsimage</span><span class="p">,</span> <span class="n">label</span><span class="o">=</span><span class="n">label</span><span class="p">)</span>
<span class="c">######## Utility functions ###############################################</span>
</div>
<div class="viewcode-block" id="mksparse"><a class="viewcode-back" href="../../pylorax.html#pylorax.imgutils.mksparse">[docs]</a><span class="k">def</span> <span class="nf">mksparse</span><span class="p">(</span><span class="n">outfile</span><span class="p">,</span> <span class="n">size</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;use os.ftruncate to create a sparse file of the given size.&#39;&#39;&#39;</span>
<span class="n">fobj</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">outfile</span><span class="p">,</span> <span class="s">&quot;w&quot;</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">ftruncate</span><span class="p">(</span><span class="n">fobj</span><span class="o">.</span><span class="n">fileno</span><span class="p">(),</span> <span class="n">size</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="mkqcow2"><a class="viewcode-back" href="../../pylorax.html#pylorax.imgutils.mkqcow2">[docs]</a><span class="k">def</span> <span class="nf">mkqcow2</span><span class="p">(</span><span class="n">outfile</span><span class="p">,</span> <span class="n">size</span><span class="p">,</span> <span class="n">options</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;use qemu-img to create a file of the given size.</span>
<span class="sd"> options is a list of options passed to qemu-img</span>
<span class="sd"> Default format is qcow2, override by passing &quot;-f&quot;, fmt</span>
<span class="sd"> in options.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="n">options</span> <span class="o">=</span> <span class="n">options</span> <span class="ow">or</span> <span class="p">[]</span>
<span class="k">if</span> <span class="s">&quot;-f&quot;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">options</span><span class="p">:</span>
<span class="n">options</span><span class="o">.</span><span class="n">extend</span><span class="p">([</span><span class="s">&quot;-f&quot;</span><span class="p">,</span> <span class="s">&quot;qcow2&quot;</span><span class="p">])</span>
<span class="n">runcmd</span><span class="p">([</span><span class="s">&quot;qemu-img&quot;</span><span class="p">,</span> <span class="s">&quot;create&quot;</span><span class="p">]</span> <span class="o">+</span> <span class="n">options</span> <span class="o">+</span> <span class="p">[</span><span class="n">outfile</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="n">size</span><span class="p">)])</span>
</div>
<div class="viewcode-block" id="loop_waitfor"><a class="viewcode-back" href="../../pylorax.html#pylorax.imgutils.loop_waitfor">[docs]</a><span class="k">def</span> <span class="nf">loop_waitfor</span><span class="p">(</span><span class="n">loop_dev</span><span class="p">,</span> <span class="n">outfile</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Make sure the loop device is attached to the outfile.</span>
<span class="sd"> It seems that on rare occasions losetup can return before the /dev/loopX is</span>
<span class="sd"> ready for use, causing problems with mkfs. This tries to make sure that the</span>
<span class="sd"> loop device really is associated with the backing file before continuing.</span>
<span class="sd"> Raise RuntimeError if it isn&#39;t setup after 5 tries.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nb">xrange</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="mi">5</span><span class="p">):</span>
<span class="n">runcmd</span><span class="p">([</span><span class="s">&quot;udevadm&quot;</span><span class="p">,</span> <span class="s">&quot;settle&quot;</span><span class="p">,</span> <span class="s">&quot;--timeout&quot;</span><span class="p">,</span> <span class="s">&quot;300&quot;</span><span class="p">])</span>
<span class="c">## XXX Note that losetup --list output can be truncated to 64 bytes in some</span>
<span class="c">## situations. Don&#39;t use it to lookup backing file, go the other way</span>
<span class="c">## and lookup the loop for the backing file. See util-linux lib/loopdev.c</span>
<span class="c">## loopcxt_get_backing_file()</span>
<span class="k">if</span> <span class="n">get_loop_name</span><span class="p">(</span><span class="n">outfile</span><span class="p">)</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">basename</span><span class="p">(</span><span class="n">loop_dev</span><span class="p">):</span>
<span class="k">return</span>
<span class="c"># If this really is a race, give it some time to settle down</span>
<span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s">&quot;Unable to setup </span><span class="si">%s</span><span class="s"> on </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">loop_dev</span><span class="p">,</span> <span class="n">outfile</span><span class="p">))</span>
</div>
<div class="viewcode-block" id="loop_attach"><a class="viewcode-back" href="../../pylorax.html#pylorax.imgutils.loop_attach">[docs]</a><span class="k">def</span> <span class="nf">loop_attach</span><span class="p">(</span><span class="n">outfile</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;Attach a loop device to the given file. Return the loop device name.</span>
<span class="sd"> Raises CalledProcessError if losetup fails.&#39;&#39;&#39;</span>
<span class="n">dev</span> <span class="o">=</span> <span class="n">runcmd_output</span><span class="p">([</span><span class="s">&quot;losetup&quot;</span><span class="p">,</span> <span class="s">&quot;--find&quot;</span><span class="p">,</span> <span class="s">&quot;--show&quot;</span><span class="p">,</span> <span class="n">outfile</span><span class="p">])</span>
<span class="c"># Sometimes the loop device isn&#39;t ready yet, make extra sure before returning</span>
<span class="n">loop_waitfor</span><span class="p">(</span><span class="n">dev</span><span class="o">.</span><span class="n">strip</span><span class="p">(),</span> <span class="n">outfile</span><span class="p">)</span>
<span class="k">return</span> <span class="n">dev</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
</div>
<div class="viewcode-block" id="loop_detach"><a class="viewcode-back" href="../../pylorax.html#pylorax.imgutils.loop_detach">[docs]</a><span class="k">def</span> <span class="nf">loop_detach</span><span class="p">(</span><span class="n">loopdev</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;Detach the given loop device. Return False on failure.&#39;&#39;&#39;</span>
<span class="k">return</span> <span class="p">(</span><span class="n">execWithRedirect</span><span class="p">(</span><span class="s">&quot;losetup&quot;</span><span class="p">,</span> <span class="p">[</span><span class="s">&quot;--detach&quot;</span><span class="p">,</span> <span class="n">loopdev</span><span class="p">])</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="get_loop_name"><a class="viewcode-back" href="../../pylorax.html#pylorax.imgutils.get_loop_name">[docs]</a><span class="k">def</span> <span class="nf">get_loop_name</span><span class="p">(</span><span class="n">path</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;Return the loop device associated with the path.</span>
<span class="sd"> Raises RuntimeError if more than one loop is associated&#39;&#39;&#39;</span>
<span class="n">buf</span> <span class="o">=</span> <span class="n">runcmd_output</span><span class="p">([</span><span class="s">&quot;losetup&quot;</span><span class="p">,</span> <span class="s">&quot;-j&quot;</span><span class="p">,</span> <span class="n">path</span><span class="p">])</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">buf</span><span class="o">.</span><span class="n">splitlines</span><span class="p">())</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
<span class="c"># there should never be more than one loop device listed</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s">&quot;multiple loops associated with </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">path</span><span class="p">)</span>
<span class="n">name</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">basename</span><span class="p">(</span><span class="n">buf</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">&quot;:&quot;</span><span class="p">)[</span><span class="mi">0</span><span class="p">])</span>
<span class="k">return</span> <span class="n">name</span>
</div>
<div class="viewcode-block" id="dm_attach"><a class="viewcode-back" href="../../pylorax.html#pylorax.imgutils.dm_attach">[docs]</a><span class="k">def</span> <span class="nf">dm_attach</span><span class="p">(</span><span class="n">dev</span><span class="p">,</span> <span class="n">size</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;Attach a devicemapper device to the given device, with the given size.</span>
<span class="sd"> If name is None, a random name will be chosen. Returns the device name.</span>
<span class="sd"> raises CalledProcessError if dmsetup fails.&#39;&#39;&#39;</span>
<span class="k">if</span> <span class="n">name</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span>
<span class="n">name</span> <span class="o">=</span> <span class="n">tempfile</span><span class="o">.</span><span class="n">mktemp</span><span class="p">(</span><span class="n">prefix</span><span class="o">=</span><span class="s">&quot;lorax.imgutils.&quot;</span><span class="p">,</span> <span class="nb">dir</span><span class="o">=</span><span class="s">&quot;&quot;</span><span class="p">)</span>
<span class="n">runcmd</span><span class="p">([</span><span class="s">&quot;dmsetup&quot;</span><span class="p">,</span> <span class="s">&quot;create&quot;</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="s">&quot;--table&quot;</span><span class="p">,</span>
<span class="s">&quot;0 </span><span class="si">%i</span><span class="s"> linear </span><span class="si">%s</span><span class="s"> 0&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">size</span><span class="o">/</span><span class="mi">512</span><span class="p">,</span> <span class="n">dev</span><span class="p">)])</span>
<span class="k">return</span> <span class="n">name</span>
</div>
<div class="viewcode-block" id="dm_detach"><a class="viewcode-back" href="../../pylorax.html#pylorax.imgutils.dm_detach">[docs]</a><span class="k">def</span> <span class="nf">dm_detach</span><span class="p">(</span><span class="n">dev</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;Detach the named devicemapper device. Returns False if dmsetup fails.&#39;&#39;&#39;</span>
<span class="n">dev</span> <span class="o">=</span> <span class="n">dev</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s">&quot;/dev/mapper/&quot;</span><span class="p">,</span> <span class="s">&quot;&quot;</span><span class="p">)</span> <span class="c"># strip prefix, if it&#39;s there</span>
<span class="k">return</span> <span class="n">execWithRedirect</span><span class="p">(</span><span class="s">&quot;dmsetup&quot;</span><span class="p">,</span> <span class="p">[</span><span class="s">&quot;remove&quot;</span><span class="p">,</span> <span class="n">dev</span><span class="p">])</span>
</div>
<div class="viewcode-block" id="mount"><a class="viewcode-back" href="../../pylorax.html#pylorax.imgutils.mount">[docs]</a><span class="k">def</span> <span class="nf">mount</span><span class="p">(</span><span class="n">dev</span><span class="p">,</span> <span class="n">opts</span><span class="o">=</span><span class="s">&quot;&quot;</span><span class="p">,</span> <span class="n">mnt</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;Mount the given device at the given mountpoint, using the given opts.</span>
<span class="sd"> opts should be a comma-separated string of mount options.</span>
<span class="sd"> if mnt is none, a temporary directory will be created and its path will be</span>
<span class="sd"> returned.</span>
<span class="sd"> raises CalledProcessError if mount fails.&#39;&#39;&#39;</span>
<span class="k">if</span> <span class="n">mnt</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span>
<span class="n">mnt</span> <span class="o">=</span> <span class="n">tempfile</span><span class="o">.</span><span class="n">mkdtemp</span><span class="p">(</span><span class="n">prefix</span><span class="o">=</span><span class="s">&quot;lorax.imgutils.&quot;</span><span class="p">)</span>
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">&quot;make tmp mountdir </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">mnt</span><span class="p">)</span>
<span class="n">cmd</span> <span class="o">=</span> <span class="p">[</span><span class="s">&quot;mount&quot;</span><span class="p">]</span>
<span class="k">if</span> <span class="n">opts</span><span class="p">:</span>
<span class="n">cmd</span> <span class="o">+=</span> <span class="p">[</span><span class="s">&quot;-o&quot;</span><span class="p">,</span> <span class="n">opts</span><span class="p">]</span>
<span class="n">cmd</span> <span class="o">+=</span> <span class="p">[</span><span class="n">dev</span><span class="p">,</span> <span class="n">mnt</span><span class="p">]</span>
<span class="n">runcmd</span><span class="p">(</span><span class="n">cmd</span><span class="p">)</span>
<span class="k">return</span> <span class="n">mnt</span>
</div>
<div class="viewcode-block" id="umount"><a class="viewcode-back" href="../../pylorax.html#pylorax.imgutils.umount">[docs]</a><span class="k">def</span> <span class="nf">umount</span><span class="p">(</span><span class="n">mnt</span><span class="p">,</span> <span class="n">lazy</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">maxretry</span><span class="o">=</span><span class="mi">3</span><span class="p">,</span> <span class="n">retrysleep</span><span class="o">=</span><span class="mf">1.0</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;Unmount the given mountpoint. If lazy is True, do a lazy umount (-l).</span>
<span class="sd"> If the mount was a temporary dir created by mount, it will be deleted.</span>
<span class="sd"> raises CalledProcessError if umount fails.&#39;&#39;&#39;</span>
<span class="n">cmd</span> <span class="o">=</span> <span class="p">[</span><span class="s">&quot;umount&quot;</span><span class="p">]</span>
<span class="k">if</span> <span class="n">lazy</span><span class="p">:</span> <span class="n">cmd</span> <span class="o">+=</span> <span class="p">[</span><span class="s">&quot;-l&quot;</span><span class="p">]</span>
<span class="n">cmd</span> <span class="o">+=</span> <span class="p">[</span><span class="n">mnt</span><span class="p">]</span>
<span class="n">count</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">while</span> <span class="n">maxretry</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">rv</span> <span class="o">=</span> <span class="n">runcmd</span><span class="p">(</span><span class="n">cmd</span><span class="p">)</span>
<span class="k">except</span> <span class="n">CalledProcessError</span><span class="p">:</span>
<span class="n">count</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="k">if</span> <span class="n">count</span> <span class="o">==</span> <span class="n">maxretry</span><span class="p">:</span>
<span class="k">raise</span>
<span class="n">logger</span><span class="o">.</span><span class="n">warn</span><span class="p">(</span><span class="s">&quot;failed to unmount </span><span class="si">%s</span><span class="s">. retrying (</span><span class="si">%d</span><span class="s">/</span><span class="si">%d</span><span class="s">)...&quot;</span><span class="p">,</span>
<span class="n">mnt</span><span class="p">,</span> <span class="n">count</span><span class="p">,</span> <span class="n">maxretry</span><span class="p">)</span>
<span class="k">if</span> <span class="n">logger</span><span class="o">.</span><span class="n">getEffectiveLevel</span><span class="p">()</span> <span class="o">&lt;=</span> <span class="n">logging</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">:</span>
<span class="n">fuser</span> <span class="o">=</span> <span class="n">execWithCapture</span><span class="p">(</span><span class="s">&quot;fuser&quot;</span><span class="p">,</span> <span class="p">[</span><span class="s">&quot;-vm&quot;</span><span class="p">,</span> <span class="n">mnt</span><span class="p">])</span>
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">&quot;fuser -vm:</span><span class="se">\n</span><span class="si">%s</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">fuser</span><span class="p">)</span>
<span class="n">sleep</span><span class="p">(</span><span class="n">retrysleep</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">break</span>
<span class="k">if</span> <span class="s">&#39;lorax.imgutils&#39;</span> <span class="ow">in</span> <span class="n">mnt</span><span class="p">:</span>
<span class="n">os</span><span class="o">.</span><span class="n">rmdir</span><span class="p">(</span><span class="n">mnt</span><span class="p">)</span>
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">&quot;remove tmp mountdir </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">mnt</span><span class="p">)</span>
<span class="k">return</span> <span class="p">(</span><span class="n">rv</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="copytree"><a class="viewcode-back" href="../../pylorax.html#pylorax.imgutils.copytree">[docs]</a><span class="k">def</span> <span class="nf">copytree</span><span class="p">(</span><span class="n">src</span><span class="p">,</span> <span class="n">dest</span><span class="p">,</span> <span class="n">preserve</span><span class="o">=</span><span class="bp">True</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;Copy a tree of files using cp -a, thus preserving modes, timestamps,</span>
<span class="sd"> links, acls, sparse files, xattrs, selinux contexts, etc.</span>
<span class="sd"> If preserve is False, uses cp -R (useful for modeless filesystems)</span>
<span class="sd"> raises CalledProcessError if copy fails.&#39;&#39;&#39;</span>
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">&quot;copytree </span><span class="si">%s</span><span class="s"> </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">src</span><span class="p">,</span> <span class="n">dest</span><span class="p">)</span>
<span class="n">cp</span> <span class="o">=</span> <span class="p">[</span><span class="s">&quot;cp&quot;</span><span class="p">,</span> <span class="s">&quot;-a&quot;</span><span class="p">]</span> <span class="k">if</span> <span class="n">preserve</span> <span class="k">else</span> <span class="p">[</span><span class="s">&quot;cp&quot;</span><span class="p">,</span> <span class="s">&quot;-R&quot;</span><span class="p">,</span> <span class="s">&quot;-L&quot;</span><span class="p">]</span>
<span class="n">cp</span> <span class="o">+=</span> <span class="p">[</span><span class="s">&quot;.&quot;</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">abspath</span><span class="p">(</span><span class="n">dest</span><span class="p">)]</span>
<span class="n">runcmd</span><span class="p">(</span><span class="n">cp</span><span class="p">,</span> <span class="n">cwd</span><span class="o">=</span><span class="n">src</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="do_grafts"><a class="viewcode-back" href="../../pylorax.html#pylorax.imgutils.do_grafts">[docs]</a><span class="k">def</span> <span class="nf">do_grafts</span><span class="p">(</span><span class="n">grafts</span><span class="p">,</span> <span class="n">dest</span><span class="p">,</span> <span class="n">preserve</span><span class="o">=</span><span class="bp">True</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;Copy each of the items listed in grafts into dest.</span>
<span class="sd"> If the key ends with &#39;/&#39; it&#39;s assumed to be a directory which should be</span>
<span class="sd"> created, otherwise just the leading directories will be created.&#39;&#39;&#39;</span>
<span class="k">for</span> <span class="n">imgpath</span><span class="p">,</span> <span class="n">filename</span> <span class="ow">in</span> <span class="n">grafts</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
<span class="k">if</span> <span class="n">imgpath</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="s">&#39;/&#39;</span><span class="p">:</span>
<span class="n">targetdir</span> <span class="o">=</span> <span class="n">join</span><span class="p">(</span><span class="n">dest</span><span class="p">,</span> <span class="n">imgpath</span><span class="p">)</span>
<span class="n">imgpath</span> <span class="o">=</span> <span class="n">imgpath</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">targetdir</span> <span class="o">=</span> <span class="n">join</span><span class="p">(</span><span class="n">dest</span><span class="p">,</span> <span class="n">dirname</span><span class="p">(</span><span class="n">imgpath</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">isdir</span><span class="p">(</span><span class="n">targetdir</span><span class="p">):</span>
<span class="n">os</span><span class="o">.</span><span class="n">makedirs</span><span class="p">(</span><span class="n">targetdir</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">filename</span><span class="p">):</span>
<span class="n">copytree</span><span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="n">join</span><span class="p">(</span><span class="n">dest</span><span class="p">,</span> <span class="n">imgpath</span><span class="p">),</span> <span class="n">preserve</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">cpfile</span><span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="n">join</span><span class="p">(</span><span class="n">dest</span><span class="p">,</span> <span class="n">imgpath</span><span class="p">))</span>
</div>
<div class="viewcode-block" id="round_to_blocks"><a class="viewcode-back" href="../../pylorax.html#pylorax.imgutils.round_to_blocks">[docs]</a><span class="k">def</span> <span class="nf">round_to_blocks</span><span class="p">(</span><span class="n">size</span><span class="p">,</span> <span class="n">blocksize</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;If size isn&#39;t a multiple of blocksize, round up to the next multiple&#39;&#39;&#39;</span>
<span class="n">diff</span> <span class="o">=</span> <span class="n">size</span> <span class="o">%</span> <span class="n">blocksize</span>
<span class="k">if</span> <span class="n">diff</span> <span class="ow">or</span> <span class="ow">not</span> <span class="n">size</span><span class="p">:</span>
<span class="n">size</span> <span class="o">+=</span> <span class="n">blocksize</span> <span class="o">-</span> <span class="n">diff</span>
<span class="k">return</span> <span class="n">size</span>
<span class="c"># TODO: move filesystem data outside this function</span></div>
<div class="viewcode-block" id="estimate_size"><a class="viewcode-back" href="../../pylorax.html#pylorax.imgutils.estimate_size">[docs]</a><span class="k">def</span> <span class="nf">estimate_size</span><span class="p">(</span><span class="n">rootdir</span><span class="p">,</span> <span class="n">graft</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">fstype</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">blocksize</span><span class="o">=</span><span class="mi">4096</span><span class="p">,</span> <span class="n">overhead</span><span class="o">=</span><span class="mi">128</span><span class="p">):</span>
<span class="k">if</span> <span class="n">graft</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span>
<span class="n">graft</span> <span class="o">=</span> <span class="p">{}</span>
<span class="n">getsize</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">f</span><span class="p">:</span> <span class="n">os</span><span class="o">.</span><span class="n">lstat</span><span class="p">(</span><span class="n">f</span><span class="p">)</span><span class="o">.</span><span class="n">st_size</span>
<span class="k">if</span> <span class="n">fstype</span> <span class="o">==</span> <span class="s">&quot;btrfs&quot;</span><span class="p">:</span>
<span class="n">overhead</span> <span class="o">=</span> <span class="mi">64</span><span class="o">*</span><span class="mi">1024</span> <span class="c"># don&#39;t worry, it&#39;s all sparse</span>
<span class="k">if</span> <span class="n">fstype</span> <span class="o">==</span> <span class="s">&quot;hfsplus&quot;</span><span class="p">:</span>
<span class="n">overhead</span> <span class="o">=</span> <span class="mi">200</span> <span class="c"># hack to deal with two bootloader copies</span>
<span class="k">if</span> <span class="n">fstype</span> <span class="ow">in</span> <span class="p">(</span><span class="s">&quot;vfat&quot;</span><span class="p">,</span> <span class="s">&quot;msdos&quot;</span><span class="p">):</span>
<span class="n">blocksize</span> <span class="o">=</span> <span class="mi">2048</span>
<span class="n">getsize</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">f</span><span class="p">:</span> <span class="n">os</span><span class="o">.</span><span class="n">stat</span><span class="p">(</span><span class="n">f</span><span class="p">)</span><span class="o">.</span><span class="n">st_size</span> <span class="c"># no symlinks, count as copies</span>
<span class="n">total</span> <span class="o">=</span> <span class="n">overhead</span><span class="o">*</span><span class="n">blocksize</span>
<span class="n">dirlist</span> <span class="o">=</span> <span class="n">graft</span><span class="o">.</span><span class="n">values</span><span class="p">()</span>
<span class="k">if</span> <span class="n">rootdir</span><span class="p">:</span>
<span class="n">dirlist</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">rootdir</span><span class="p">)</span>
<span class="k">for</span> <span class="n">root</span> <span class="ow">in</span> <span class="n">dirlist</span><span class="p">:</span>
<span class="k">for</span> <span class="n">top</span><span class="p">,</span> <span class="n">dirs</span><span class="p">,</span> <span class="n">files</span> <span class="ow">in</span> <span class="n">os</span><span class="o">.</span><span class="n">walk</span><span class="p">(</span><span class="n">root</span><span class="p">):</span>
<span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">files</span> <span class="o">+</span> <span class="n">dirs</span><span class="p">:</span>
<span class="n">total</span> <span class="o">+=</span> <span class="n">round_to_blocks</span><span class="p">(</span><span class="n">getsize</span><span class="p">(</span><span class="n">join</span><span class="p">(</span><span class="n">top</span><span class="p">,</span><span class="n">f</span><span class="p">)),</span> <span class="n">blocksize</span><span class="p">)</span>
<span class="k">if</span> <span class="n">fstype</span> <span class="o">==</span> <span class="s">&quot;btrfs&quot;</span><span class="p">:</span>
<span class="n">total</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span><span class="mi">256</span><span class="o">*</span><span class="mi">1024</span><span class="o">*</span><span class="mi">1024</span><span class="p">,</span> <span class="n">total</span><span class="p">)</span> <span class="c"># btrfs minimum size: 256MB</span>
<span class="k">return</span> <span class="n">total</span>
</div>
<div class="viewcode-block" id="default_image_name"><a class="viewcode-back" href="../../pylorax.html#pylorax.imgutils.default_image_name">[docs]</a><span class="k">def</span> <span class="nf">default_image_name</span><span class="p">(</span><span class="n">compression</span><span class="p">,</span> <span class="n">basename</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot; Return a default image name with the correct suffix for the compression type.</span>
<span class="sd"> :param str compression: Compression type</span>
<span class="sd"> :param str basename: Base filename</span>
<span class="sd"> :returns: basename with compression suffix</span>
<span class="sd"> If the compression is unknown it defaults to xz</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">SUFFIXES</span> <span class="o">=</span> <span class="p">{</span><span class="s">&quot;xz&quot;</span><span class="p">:</span> <span class="s">&quot;.xz&quot;</span><span class="p">,</span> <span class="s">&quot;gzip&quot;</span><span class="p">:</span> <span class="s">&quot;.gz&quot;</span><span class="p">,</span> <span class="s">&quot;bzip2&quot;</span><span class="p">:</span> <span class="s">&quot;.bz2&quot;</span><span class="p">,</span> <span class="s">&quot;lzma&quot;</span><span class="p">:</span> <span class="s">&quot;.lzma&quot;</span><span class="p">}</span>
<span class="k">return</span> <span class="n">basename</span> <span class="o">+</span> <span class="n">SUFFIXES</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">compression</span><span class="p">,</span> <span class="s">&quot;.xz&quot;</span><span class="p">)</span>
<span class="c">######## Execution contexts - use with the &#39;with&#39; statement ##############</span>
</div>
<div class="viewcode-block" id="LoopDev"><a class="viewcode-back" href="../../pylorax.html#pylorax.imgutils.LoopDev">[docs]</a><span class="k">class</span> <span class="nc">LoopDev</span><span class="p">(</span><span class="nb">object</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">filename</span><span class="p">,</span> <span class="n">size</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">loopdev</span> <span class="o">=</span> <span class="bp">None</span>
<span class="bp">self</span><span class="o">.</span><span class="n">filename</span> <span class="o">=</span> <span class="n">filename</span>
<span class="k">if</span> <span class="n">size</span><span class="p">:</span>
<span class="n">mksparse</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">filename</span><span class="p">,</span> <span class="n">size</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">__enter__</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">loopdev</span> <span class="o">=</span> <span class="n">loop_attach</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">filename</span><span class="p">)</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">loopdev</span>
<span class="k">def</span> <span class="nf">__exit__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">exc_type</span><span class="p">,</span> <span class="n">exc_value</span><span class="p">,</span> <span class="n">exc_tb</span><span class="p">):</span>
<span class="n">loop_detach</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">loopdev</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="DMDev"><a class="viewcode-back" href="../../pylorax.html#pylorax.imgutils.DMDev">[docs]</a><span class="k">class</span> <span class="nc">DMDev</span><span class="p">(</span><span class="nb">object</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">dev</span><span class="p">,</span> <span class="n">size</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
<span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">dev</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">size</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">)</span> <span class="o">=</span> <span class="p">(</span><span class="n">dev</span><span class="p">,</span> <span class="n">size</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">mapperdev</span> <span class="o">=</span> <span class="bp">None</span>
<span class="k">def</span> <span class="nf">__enter__</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">mapperdev</span> <span class="o">=</span> <span class="n">dm_attach</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">dev</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">size</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">)</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">mapperdev</span>
<span class="k">def</span> <span class="nf">__exit__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">exc_type</span><span class="p">,</span> <span class="n">exc_value</span><span class="p">,</span> <span class="n">exc_tb</span><span class="p">):</span>
<span class="n">dm_detach</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">mapperdev</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="Mount"><a class="viewcode-back" href="../../pylorax.html#pylorax.imgutils.Mount">[docs]</a><span class="k">class</span> <span class="nc">Mount</span><span class="p">(</span><span class="nb">object</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">dev</span><span class="p">,</span> <span class="n">opts</span><span class="o">=</span><span class="s">&quot;&quot;</span><span class="p">,</span> <span class="n">mnt</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
<span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">dev</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">opts</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">mnt</span><span class="p">)</span> <span class="o">=</span> <span class="p">(</span><span class="n">dev</span><span class="p">,</span> <span class="n">opts</span><span class="p">,</span> <span class="n">mnt</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">__enter__</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">mnt</span> <span class="o">=</span> <span class="n">mount</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">dev</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">opts</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">mnt</span><span class="p">)</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">mnt</span>
<span class="k">def</span> <span class="nf">__exit__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">exc_type</span><span class="p">,</span> <span class="n">exc_value</span><span class="p">,</span> <span class="n">exc_tb</span><span class="p">):</span>
<span class="n">umount</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">mnt</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="PartitionMount"><a class="viewcode-back" href="../../pylorax.html#pylorax.imgutils.PartitionMount">[docs]</a><span class="k">class</span> <span class="nc">PartitionMount</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot; Mount a partitioned image file using kpartx &quot;&quot;&quot;</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">disk_img</span><span class="p">,</span> <span class="n">mount_ok</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> disk_img is the full path to a partitioned disk image</span>
<span class="sd"> mount_ok is a function that is passed the mount point and</span>
<span class="sd"> returns True if it should be mounted.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">mount_dir</span> <span class="o">=</span> <span class="bp">None</span>
<span class="bp">self</span><span class="o">.</span><span class="n">mount_dev</span> <span class="o">=</span> <span class="bp">None</span>
<span class="bp">self</span><span class="o">.</span><span class="n">mount_size</span> <span class="o">=</span> <span class="bp">None</span>
<span class="bp">self</span><span class="o">.</span><span class="n">disk_img</span> <span class="o">=</span> <span class="n">disk_img</span>
<span class="bp">self</span><span class="o">.</span><span class="n">mount_ok</span> <span class="o">=</span> <span class="n">mount_ok</span>
<span class="c"># Default is to mount partition with /etc/passwd</span>
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">mount_ok</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">mount_ok</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">mount_dir</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">isfile</span><span class="p">(</span><span class="n">mount_dir</span><span class="o">+</span><span class="s">&quot;/etc/passwd&quot;</span><span class="p">)</span>
<span class="c"># Example kpartx output</span>
<span class="c"># kpartx -p p -v -a /tmp/diskV2DiCW.im</span>
<span class="c"># add map loop2p1 (253:2): 0 3481600 linear /dev/loop2 2048</span>
<span class="c"># add map loop2p2 (253:3): 0 614400 linear /dev/loop2 3483648</span>
<span class="n">kpartx_output</span> <span class="o">=</span> <span class="n">runcmd_output</span><span class="p">([</span><span class="s">&quot;kpartx&quot;</span><span class="p">,</span> <span class="s">&quot;-v&quot;</span><span class="p">,</span> <span class="s">&quot;-a&quot;</span><span class="p">,</span> <span class="s">&quot;-s&quot;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">disk_img</span><span class="p">])</span>
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">kpartx_output</span><span class="p">)</span>
<span class="c"># list of (deviceName, sizeInBytes)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">loop_devices</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">kpartx_output</span><span class="o">.</span><span class="n">splitlines</span><span class="p">():</span>
<span class="c"># add map loop2p3 (253:4): 0 7139328 linear /dev/loop2 528384</span>
<span class="c"># 3rd element is size in 512 byte blocks</span>
<span class="k">if</span> <span class="n">line</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s">&quot;add map &quot;</span><span class="p">):</span>
<span class="n">fields</span> <span class="o">=</span> <span class="n">line</span><span class="p">[</span><span class="mi">8</span><span class="p">:]</span><span class="o">.</span><span class="n">split</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">loop_devices</span><span class="o">.</span><span class="n">append</span><span class="p">(</span> <span class="p">(</span><span class="n">fields</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="nb">int</span><span class="p">(</span><span class="n">fields</span><span class="p">[</span><span class="mi">3</span><span class="p">])</span><span class="o">*</span><span class="mi">512</span><span class="p">)</span> <span class="p">)</span>
<span class="k">def</span> <span class="nf">__enter__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="c"># Mount the device selected by mount_ok, if possible</span>
<span class="n">mount_dir</span> <span class="o">=</span> <span class="n">tempfile</span><span class="o">.</span><span class="n">mkdtemp</span><span class="p">()</span>
<span class="k">for</span> <span class="n">dev</span><span class="p">,</span> <span class="n">size</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">loop_devices</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">mount</span><span class="p">(</span> <span class="s">&quot;/dev/mapper/&quot;</span><span class="o">+</span><span class="n">dev</span><span class="p">,</span> <span class="n">mnt</span><span class="o">=</span><span class="n">mount_dir</span> <span class="p">)</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">mount_ok</span><span class="p">(</span><span class="n">mount_dir</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">mount_dir</span> <span class="o">=</span> <span class="n">mount_dir</span>
<span class="bp">self</span><span class="o">.</span><span class="n">mount_dev</span> <span class="o">=</span> <span class="n">dev</span>
<span class="bp">self</span><span class="o">.</span><span class="n">mount_size</span> <span class="o">=</span> <span class="n">size</span>
<span class="k">break</span>
<span class="n">umount</span><span class="p">(</span> <span class="n">mount_dir</span> <span class="p">)</span>
<span class="k">except</span> <span class="n">CalledProcessError</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">traceback</span><span class="o">.</span><span class="n">format_exc</span><span class="p">())</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">mount_dir</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;Partition mounted on </span><span class="si">%s</span><span class="s"> size=</span><span class="si">%d</span><span class="s">&quot;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">mount_dir</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">mount_size</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">&quot;Unable to mount anything from </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">disk_img</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">rmdir</span><span class="p">(</span><span class="n">mount_dir</span><span class="p">)</span>
<span class="k">return</span> <span class="bp">self</span>
<span class="k">def</span> <span class="nf">__exit__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">exc_type</span><span class="p">,</span> <span class="n">exc_value</span><span class="p">,</span> <span class="n">exc_tb</span><span class="p">):</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">mount_dir</span><span class="p">:</span>
<span class="n">umount</span><span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">mount_dir</span> <span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">rmdir</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">mount_dir</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">mount_dir</span> <span class="o">=</span> <span class="bp">None</span>
<span class="n">execWithRedirect</span><span class="p">(</span><span class="s">&quot;kpartx&quot;</span><span class="p">,</span> <span class="p">[</span><span class="s">&quot;-d&quot;</span><span class="p">,</span> <span class="s">&quot;-s&quot;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">disk_img</span><span class="p">])</span>
<span class="c">######## Functions for making filesystem images ##########################</span>
</div>
<div class="viewcode-block" id="mkfsimage"><a class="viewcode-back" href="../../pylorax.html#pylorax.imgutils.mkfsimage">[docs]</a><span class="k">def</span> <span class="nf">mkfsimage</span><span class="p">(</span><span class="n">fstype</span><span class="p">,</span> <span class="n">rootdir</span><span class="p">,</span> <span class="n">outfile</span><span class="p">,</span> <span class="n">size</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">mkfsargs</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">mountargs</span><span class="o">=</span><span class="s">&quot;&quot;</span><span class="p">,</span> <span class="n">graft</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;Generic filesystem image creation function.</span>
<span class="sd"> fstype should be a filesystem type - &quot;mkfs.${fstype}&quot; must exist.</span>
<span class="sd"> graft should be a dict: {&quot;some/path/in/image&quot;: &quot;local/file/or/dir&quot;};</span>
<span class="sd"> if the path ends with a &#39;/&#39; it&#39;s assumed to be a directory.</span>
<span class="sd"> Will raise CalledProcessError if something goes wrong.&#39;&#39;&#39;</span>
<span class="k">if</span> <span class="n">mkfsargs</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span>
<span class="n">mkfsargs</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">if</span> <span class="n">graft</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span>
<span class="n">graft</span> <span class="o">=</span> <span class="p">{}</span>
<span class="n">preserve</span> <span class="o">=</span> <span class="p">(</span><span class="n">fstype</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">(</span><span class="s">&quot;msdos&quot;</span><span class="p">,</span> <span class="s">&quot;vfat&quot;</span><span class="p">))</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">size</span><span class="p">:</span>
<span class="n">size</span> <span class="o">=</span> <span class="n">estimate_size</span><span class="p">(</span><span class="n">rootdir</span><span class="p">,</span> <span class="n">graft</span><span class="p">,</span> <span class="n">fstype</span><span class="p">)</span>
<span class="k">with</span> <span class="n">LoopDev</span><span class="p">(</span><span class="n">outfile</span><span class="p">,</span> <span class="n">size</span><span class="p">)</span> <span class="k">as</span> <span class="n">loopdev</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">runcmd</span><span class="p">([</span><span class="s">&quot;mkfs.</span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">fstype</span><span class="p">]</span> <span class="o">+</span> <span class="n">mkfsargs</span> <span class="o">+</span> <span class="p">[</span><span class="n">loopdev</span><span class="p">])</span>
<span class="k">except</span> <span class="n">CalledProcessError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s">&quot;mkfs exited with a non-zero return code: </span><span class="si">%d</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">e</span><span class="o">.</span><span class="n">returncode</span><span class="p">)</span>
<span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="n">e</span><span class="o">.</span><span class="n">output</span><span class="p">)</span>
<span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="n">e</span><span class="o">.</span><span class="n">returncode</span><span class="p">)</span>
<span class="k">with</span> <span class="n">Mount</span><span class="p">(</span><span class="n">loopdev</span><span class="p">,</span> <span class="n">mountargs</span><span class="p">)</span> <span class="k">as</span> <span class="n">mnt</span><span class="p">:</span>
<span class="k">if</span> <span class="n">rootdir</span><span class="p">:</span>
<span class="n">copytree</span><span class="p">(</span><span class="n">rootdir</span><span class="p">,</span> <span class="n">mnt</span><span class="p">,</span> <span class="n">preserve</span><span class="p">)</span>
<span class="n">do_grafts</span><span class="p">(</span><span class="n">graft</span><span class="p">,</span> <span class="n">mnt</span><span class="p">,</span> <span class="n">preserve</span><span class="p">)</span>
<span class="c"># Make absolutely sure that the data has been written</span>
<span class="n">runcmd</span><span class="p">([</span><span class="s">&quot;sync&quot;</span><span class="p">])</span>
<span class="c"># convenience functions with useful defaults</span></div>
<div class="viewcode-block" id="mkdosimg"><a class="viewcode-back" href="../../pylorax.html#pylorax.imgutils.mkdosimg">[docs]</a><span class="k">def</span> <span class="nf">mkdosimg</span><span class="p">(</span><span class="n">rootdir</span><span class="p">,</span> <span class="n">outfile</span><span class="p">,</span> <span class="n">size</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">label</span><span class="o">=</span><span class="s">&quot;&quot;</span><span class="p">,</span> <span class="n">mountargs</span><span class="o">=</span><span class="s">&quot;shortname=winnt,umask=0077&quot;</span><span class="p">,</span> <span class="n">graft</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
<span class="n">mkfsimage</span><span class="p">(</span><span class="s">&quot;msdos&quot;</span><span class="p">,</span> <span class="n">rootdir</span><span class="p">,</span> <span class="n">outfile</span><span class="p">,</span> <span class="n">size</span><span class="p">,</span> <span class="n">mountargs</span><span class="o">=</span><span class="n">mountargs</span><span class="p">,</span>
<span class="n">mkfsargs</span><span class="o">=</span><span class="p">[</span><span class="s">&quot;-n&quot;</span><span class="p">,</span> <span class="n">label</span><span class="p">],</span> <span class="n">graft</span><span class="o">=</span><span class="n">graft</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="mkext4img"><a class="viewcode-back" href="../../pylorax.html#pylorax.imgutils.mkext4img">[docs]</a><span class="k">def</span> <span class="nf">mkext4img</span><span class="p">(</span><span class="n">rootdir</span><span class="p">,</span> <span class="n">outfile</span><span class="p">,</span> <span class="n">size</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">label</span><span class="o">=</span><span class="s">&quot;&quot;</span><span class="p">,</span> <span class="n">mountargs</span><span class="o">=</span><span class="s">&quot;&quot;</span><span class="p">,</span> <span class="n">graft</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
<span class="n">mkfsimage</span><span class="p">(</span><span class="s">&quot;ext4&quot;</span><span class="p">,</span> <span class="n">rootdir</span><span class="p">,</span> <span class="n">outfile</span><span class="p">,</span> <span class="n">size</span><span class="p">,</span> <span class="n">mountargs</span><span class="o">=</span><span class="n">mountargs</span><span class="p">,</span>
<span class="n">mkfsargs</span><span class="o">=</span><span class="p">[</span><span class="s">&quot;-L&quot;</span><span class="p">,</span> <span class="n">label</span><span class="p">,</span> <span class="s">&quot;-b&quot;</span><span class="p">,</span> <span class="s">&quot;1024&quot;</span><span class="p">,</span> <span class="s">&quot;-m&quot;</span><span class="p">,</span> <span class="s">&quot;0&quot;</span><span class="p">],</span> <span class="n">graft</span><span class="o">=</span><span class="n">graft</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="mkbtrfsimg"><a class="viewcode-back" href="../../pylorax.html#pylorax.imgutils.mkbtrfsimg">[docs]</a><span class="k">def</span> <span class="nf">mkbtrfsimg</span><span class="p">(</span><span class="n">rootdir</span><span class="p">,</span> <span class="n">outfile</span><span class="p">,</span> <span class="n">size</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">label</span><span class="o">=</span><span class="s">&quot;&quot;</span><span class="p">,</span> <span class="n">mountargs</span><span class="o">=</span><span class="s">&quot;&quot;</span><span class="p">,</span> <span class="n">graft</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
<span class="n">mkfsimage</span><span class="p">(</span><span class="s">&quot;btrfs&quot;</span><span class="p">,</span> <span class="n">rootdir</span><span class="p">,</span> <span class="n">outfile</span><span class="p">,</span> <span class="n">size</span><span class="p">,</span> <span class="n">mountargs</span><span class="o">=</span><span class="n">mountargs</span><span class="p">,</span>
<span class="n">mkfsargs</span><span class="o">=</span><span class="p">[</span><span class="s">&quot;-L&quot;</span><span class="p">,</span> <span class="n">label</span><span class="p">],</span> <span class="n">graft</span><span class="o">=</span><span class="n">graft</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="mkhfsimg"><a class="viewcode-back" href="../../pylorax.html#pylorax.imgutils.mkhfsimg">[docs]</a><span class="k">def</span> <span class="nf">mkhfsimg</span><span class="p">(</span><span class="n">rootdir</span><span class="p">,</span> <span class="n">outfile</span><span class="p">,</span> <span class="n">size</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">label</span><span class="o">=</span><span class="s">&quot;&quot;</span><span class="p">,</span> <span class="n">mountargs</span><span class="o">=</span><span class="s">&quot;&quot;</span><span class="p">,</span> <span class="n">graft</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
<span class="n">mkfsimage</span><span class="p">(</span><span class="s">&quot;hfsplus&quot;</span><span class="p">,</span> <span class="n">rootdir</span><span class="p">,</span> <span class="n">outfile</span><span class="p">,</span> <span class="n">size</span><span class="p">,</span> <span class="n">mountargs</span><span class="o">=</span><span class="n">mountargs</span><span class="p">,</span>
<span class="n">mkfsargs</span><span class="o">=</span><span class="p">[</span><span class="s">&quot;-v&quot;</span><span class="p">,</span> <span class="n">label</span><span class="p">],</span> <span class="n">graft</span><span class="o">=</span><span class="n">graft</span><span class="p">)</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">Lorax 19.7.10 documentation</a> &raquo;</li>
<li><a href="../index.html" >Module code</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2017, Red Hat, Inc..
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>

View File

@ -0,0 +1,482 @@
<!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>pylorax.installer &mdash; Lorax 19.7.10 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: '19.7.10',
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>
<link rel="top" title="Lorax 19.7.10 documentation" href="../../index.html" />
<link rel="up" title="Module code" href="../index.html" />
</head>
<body>
<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">Lorax 19.7.10 documentation</a> &raquo;</li>
<li><a href="../index.html" accesskey="U">Module code</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<h1>Source code for pylorax.installer</h1><div class="highlight"><pre>
<span class="c">#</span>
<span class="c"># Copyright (C) 2011-2017 Red Hat, Inc.</span>
<span class="c">#</span>
<span class="c"># This program is free software; you can redistribute it and/or modify</span>
<span class="c"># it under the terms of the GNU General Public License as published by</span>
<span class="c"># the Free Software Foundation; either version 2 of the License, or</span>
<span class="c"># (at your option) any later version.</span>
<span class="c">#</span>
<span class="c"># This program is distributed in the hope that it will be useful,</span>
<span class="c"># but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<span class="c"># MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span>
<span class="c"># GNU General Public License for more details.</span>
<span class="c">#</span>
<span class="c"># You should have received a copy of the GNU General Public License</span>
<span class="c"># along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;.</span>
<span class="c">#</span>
<span class="kn">import</span> <span class="nn">logging</span>
<span class="n">log</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s">&quot;pylorax&quot;</span><span class="p">)</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">shutil</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">import</span> <span class="nn">subprocess</span>
<span class="kn">import</span> <span class="nn">tempfile</span>
<span class="kn">from</span> <span class="nn">time</span> <span class="kn">import</span> <span class="n">sleep</span>
<span class="kn">import</span> <span class="nn">uuid</span>
<span class="kn">from</span> <span class="nn">pylorax.executils</span> <span class="kn">import</span> <span class="n">execWithRedirect</span><span class="p">,</span> <span class="n">execWithCapture</span>
<span class="kn">from</span> <span class="nn">pylorax.imgutils</span> <span class="kn">import</span> <span class="n">get_loop_name</span><span class="p">,</span> <span class="n">dm_detach</span><span class="p">,</span> <span class="n">mount</span><span class="p">,</span> <span class="n">umount</span>
<span class="kn">from</span> <span class="nn">pylorax.imgutils</span> <span class="kn">import</span> <span class="n">PartitionMount</span><span class="p">,</span> <span class="n">mksparse</span><span class="p">,</span> <span class="n">mkext4img</span><span class="p">,</span> <span class="n">loop_detach</span>
<span class="kn">from</span> <span class="nn">pylorax.imgutils</span> <span class="kn">import</span> <span class="n">mktar</span><span class="p">,</span> <span class="n">mkdiskfsimage</span><span class="p">,</span> <span class="n">mkqcow2</span>
<span class="kn">from</span> <span class="nn">pylorax.logmonitor</span> <span class="kn">import</span> <span class="n">LogMonitor</span>
<span class="kn">from</span> <span class="nn">pylorax.sysutils</span> <span class="kn">import</span> <span class="n">joinpaths</span>
<span class="kn">from</span> <span class="nn">pylorax.treebuilder</span> <span class="kn">import</span> <span class="n">udev_escape</span>
<span class="n">ROOT_PATH</span> <span class="o">=</span> <span class="s">&quot;/mnt/sysimage/&quot;</span>
<span class="c"># no-virt mode doesn&#39;t need libvirt, so make it optional</span>
<span class="k">try</span><span class="p">:</span>
<span class="kn">import</span> <span class="nn">libvirt</span>
<span class="k">except</span> <span class="ne">ImportError</span><span class="p">:</span>
<span class="n">libvirt</span> <span class="o">=</span> <span class="bp">None</span>
<div class="viewcode-block" id="InstallError"><a class="viewcode-back" href="../../pylorax.html#pylorax.installer.InstallError">[docs]</a><span class="k">class</span> <span class="nc">InstallError</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
<span class="k">pass</span>
</div>
<div class="viewcode-block" id="IsoMountpoint"><a class="viewcode-back" href="../../pylorax.html#pylorax.installer.IsoMountpoint">[docs]</a><span class="k">class</span> <span class="nc">IsoMountpoint</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Mount the iso on a temporary directory and check to make sure the</span>
<span class="sd"> vmlinuz and initrd.img files exist</span>
<span class="sd"> Check the iso for a LiveOS directory and set a flag.</span>
<span class="sd"> Extract the iso&#39;s label.</span>
<span class="sd"> initrd_path can be used to point to a boot.iso tree with a newer</span>
<span class="sd"> initrd.img than the iso has. The iso is still used for stage2.</span>
<span class="sd"> &quot;&quot;&quot;</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">iso_path</span><span class="p">,</span> <span class="n">initrd_path</span><span class="o">=</span><span class="bp">None</span> <span class="p">):</span>
<span class="sd">&quot;&quot;&quot; iso_path is the path to a boot.iso</span>
<span class="sd"> initrd_path overrides mounting the iso for access to</span>
<span class="sd"> initrd and vmlinuz.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">label</span> <span class="o">=</span> <span class="bp">None</span>
<span class="bp">self</span><span class="o">.</span><span class="n">iso_path</span> <span class="o">=</span> <span class="n">iso_path</span>
<span class="bp">self</span><span class="o">.</span><span class="n">initrd_path</span> <span class="o">=</span> <span class="n">initrd_path</span>
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">initrd_path</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">mount_dir</span> <span class="o">=</span> <span class="n">mount</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">iso_path</span><span class="p">,</span> <span class="n">opts</span><span class="o">=</span><span class="s">&quot;loop&quot;</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">mount_dir</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">initrd_path</span>
<span class="n">kernel_list</span> <span class="o">=</span> <span class="p">[(</span><span class="s">&quot;/isolinux/vmlinuz&quot;</span><span class="p">,</span> <span class="s">&quot;/isolinux/initrd.img&quot;</span><span class="p">),</span>
<span class="p">(</span><span class="s">&quot;/ppc/ppc64/vmlinuz&quot;</span><span class="p">,</span> <span class="s">&quot;/ppc/ppc64/initrd.img&quot;</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="bp">self</span><span class="o">.</span><span class="n">mount_dir</span><span class="o">+</span><span class="s">&quot;/repodata&quot;</span> <span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">repo</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">mount_dir</span>
<span class="k">else</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">repo</span> <span class="o">=</span> <span class="bp">None</span>
<span class="bp">self</span><span class="o">.</span><span class="n">liveos</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">isdir</span><span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">mount_dir</span><span class="o">+</span><span class="s">&quot;/LiveOS&quot;</span> <span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">for</span> <span class="n">kernel</span><span class="p">,</span> <span class="n">initrd</span> <span class="ow">in</span> <span class="n">kernel_list</span><span class="p">:</span>
<span class="k">if</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">isfile</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">mount_dir</span><span class="o">+</span><span class="n">kernel</span><span class="p">)</span> <span class="ow">and</span>
<span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">isfile</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">mount_dir</span><span class="o">+</span><span class="n">initrd</span><span class="p">)):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">kernel</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">mount_dir</span><span class="o">+</span><span class="n">kernel</span>
<span class="bp">self</span><span class="o">.</span><span class="n">initrd</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">mount_dir</span><span class="o">+</span><span class="n">initrd</span>
<span class="k">break</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="s">&quot;Missing kernel and initrd file in iso, failed&quot;</span>
<span class="s">&quot; to search under: {0}&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">kernel_list</span><span class="p">))</span>
<span class="k">except</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">umount</span><span class="p">()</span>
<span class="k">raise</span>
<span class="bp">self</span><span class="o">.</span><span class="n">get_iso_label</span><span class="p">()</span>
<div class="viewcode-block" id="IsoMountpoint.umount"><a class="viewcode-back" href="../../pylorax.html#pylorax.installer.IsoMountpoint.umount">[docs]</a> <span class="k">def</span> <span class="nf">umount</span><span class="p">(</span> <span class="bp">self</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">initrd_path</span><span class="p">:</span>
<span class="n">umount</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">mount_dir</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="IsoMountpoint.get_iso_label"><a class="viewcode-back" href="../../pylorax.html#pylorax.installer.IsoMountpoint.get_iso_label">[docs]</a> <span class="k">def</span> <span class="nf">get_iso_label</span><span class="p">(</span> <span class="bp">self</span> <span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Get the iso&#39;s label using isoinfo</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">isoinfo_output</span> <span class="o">=</span> <span class="n">execWithCapture</span><span class="p">(</span><span class="s">&quot;isoinfo&quot;</span><span class="p">,</span> <span class="p">[</span><span class="s">&quot;-d&quot;</span><span class="p">,</span> <span class="s">&quot;-i&quot;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">iso_path</span><span class="p">])</span>
<span class="n">log</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span> <span class="n">isoinfo_output</span> <span class="p">)</span>
<span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">isoinfo_output</span><span class="o">.</span><span class="n">splitlines</span><span class="p">():</span>
<span class="k">if</span> <span class="n">line</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s">&quot;Volume id: &quot;</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">label</span> <span class="o">=</span> <span class="n">line</span><span class="p">[</span><span class="mi">11</span><span class="p">:]</span>
<span class="k">return</span>
</div></div>
<div class="viewcode-block" id="VirtualInstall"><a class="viewcode-back" href="../../pylorax.html#pylorax.installer.VirtualInstall">[docs]</a><span class="k">class</span> <span class="nc">VirtualInstall</span><span class="p">(</span> <span class="nb">object</span> <span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Run virt-install using an iso and kickstart(s)</span>
<span class="sd"> &quot;&quot;&quot;</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">iso</span><span class="p">,</span> <span class="n">ks_paths</span><span class="p">,</span> <span class="n">disk_img</span><span class="p">,</span> <span class="n">img_size</span><span class="o">=</span><span class="mi">2</span><span class="p">,</span>
<span class="n">kernel_args</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">memory</span><span class="o">=</span><span class="mi">1024</span><span class="p">,</span> <span class="n">vnc</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">arch</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span>
<span class="n">log_check</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">virtio_host</span><span class="o">=</span><span class="s">&quot;127.0.0.1&quot;</span><span class="p">,</span> <span class="n">virtio_port</span><span class="o">=</span><span class="mi">6080</span><span class="p">,</span>
<span class="n">qcow2</span><span class="o">=</span><span class="bp">False</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> iso is an instance of IsoMountpoint</span>
<span class="sd"> ks_paths is a list of paths to a kickstart files. All are injected, the</span>
<span class="sd"> first one is the one executed.</span>
<span class="sd"> disk_img is the path to a disk image (doesn&#39;t need to exist)</span>
<span class="sd"> img_size is the size, in GiB, of the image if it doesn&#39;t exist</span>
<span class="sd"> kernel_args are extra arguments to pass on the kernel cmdline</span>
<span class="sd"> memory is the amount of ram to assign to the virt</span>
<span class="sd"> vnc is passed to the --graphics command verbatim</span>
<span class="sd"> arch is the optional architecture to use in the virt</span>
<span class="sd"> log_check is a method that returns True of the log indicates an error</span>
<span class="sd"> virtio_host and virtio_port are used to communicate with the log monitor</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">virt_name</span> <span class="o">=</span> <span class="s">&quot;LiveOS-&quot;</span><span class="o">+</span><span class="nb">str</span><span class="p">(</span><span class="n">uuid</span><span class="o">.</span><span class="n">uuid4</span><span class="p">())</span>
<span class="c"># add --graphics none later</span>
<span class="c"># add whatever serial cmds are needed later</span>
<span class="n">args</span> <span class="o">=</span> <span class="p">[</span><span class="s">&quot;-n&quot;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">virt_name</span><span class="p">,</span>
<span class="s">&quot;-r&quot;</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="n">memory</span><span class="p">),</span>
<span class="s">&quot;--noreboot&quot;</span><span class="p">,</span>
<span class="s">&quot;--noautoconsole&quot;</span><span class="p">]</span>
<span class="n">args</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s">&quot;--graphics&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">vnc</span><span class="p">:</span>
<span class="n">args</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">vnc</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">args</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s">&quot;none&quot;</span><span class="p">)</span>
<span class="k">for</span> <span class="n">ks</span> <span class="ow">in</span> <span class="n">ks_paths</span><span class="p">:</span>
<span class="n">args</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s">&quot;--initrd-inject&quot;</span><span class="p">)</span>
<span class="n">args</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">ks</span><span class="p">)</span>
<span class="n">disk_opts</span> <span class="o">=</span> <span class="s">&quot;path={0}&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">disk_img</span><span class="p">)</span>
<span class="k">if</span> <span class="n">qcow2</span><span class="p">:</span>
<span class="n">disk_opts</span> <span class="o">+=</span> <span class="s">&quot;,format=qcow2&quot;</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">disk_opts</span> <span class="o">+=</span> <span class="s">&quot;,format=raw&quot;</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">isfile</span><span class="p">(</span><span class="n">disk_img</span><span class="p">):</span>
<span class="n">disk_opts</span> <span class="o">+=</span> <span class="s">&quot;,size={0}&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">img_size</span><span class="p">)</span>
<span class="n">args</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s">&quot;--disk&quot;</span><span class="p">)</span>
<span class="n">args</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">disk_opts</span><span class="p">)</span>
<span class="k">if</span> <span class="n">iso</span><span class="o">.</span><span class="n">liveos</span><span class="p">:</span>
<span class="n">disk_opts</span> <span class="o">=</span> <span class="s">&quot;path={0},device=cdrom&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">iso</span><span class="o">.</span><span class="n">iso_path</span><span class="p">)</span>
<span class="n">args</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s">&quot;--disk&quot;</span><span class="p">)</span>
<span class="n">args</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">disk_opts</span><span class="p">)</span>
<span class="n">extra_args</span> <span class="o">=</span> <span class="s">&quot;ks=file:/{0}&quot;</span><span class="o">.</span><span class="n">format</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">ks_paths</span><span class="p">[</span><span class="mi">0</span><span class="p">]))</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">vnc</span><span class="p">:</span>
<span class="n">extra_args</span> <span class="o">+=</span> <span class="s">&quot; inst.cmdline console=ttyS0&quot;</span>
<span class="k">if</span> <span class="n">kernel_args</span><span class="p">:</span>
<span class="n">extra_args</span> <span class="o">+=</span> <span class="s">&quot; &quot;</span><span class="o">+</span><span class="n">kernel_args</span>
<span class="k">if</span> <span class="n">iso</span><span class="o">.</span><span class="n">liveos</span><span class="p">:</span>
<span class="n">extra_args</span> <span class="o">+=</span> <span class="s">&quot; stage2=hd:LABEL={0}&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">udev_escape</span><span class="p">(</span><span class="n">iso</span><span class="o">.</span><span class="n">label</span><span class="p">))</span>
<span class="n">args</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s">&quot;--extra-args&quot;</span><span class="p">)</span>
<span class="n">args</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">extra_args</span><span class="p">)</span>
<span class="n">args</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s">&quot;--location&quot;</span><span class="p">)</span>
<span class="n">args</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">iso</span><span class="o">.</span><span class="n">mount_dir</span><span class="p">)</span>
<span class="n">channel_args</span> <span class="o">=</span> <span class="s">&quot;tcp,host={0}:{1},mode=connect,target_type=virtio&quot;</span> \
<span class="s">&quot;,name=org.fedoraproject.anaconda.log.0&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span>
<span class="n">virtio_host</span><span class="p">,</span> <span class="n">virtio_port</span><span class="p">)</span>
<span class="n">args</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s">&quot;--channel&quot;</span><span class="p">)</span>
<span class="n">args</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">channel_args</span><span class="p">)</span>
<span class="k">if</span> <span class="n">arch</span><span class="p">:</span>
<span class="n">args</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s">&quot;--arch&quot;</span><span class="p">)</span>
<span class="n">args</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">arch</span><span class="p">)</span>
<span class="n">rc</span> <span class="o">=</span> <span class="n">execWithRedirect</span><span class="p">(</span><span class="s">&quot;virt-install&quot;</span><span class="p">,</span> <span class="n">args</span><span class="p">)</span>
<span class="k">if</span> <span class="n">rc</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="s">&quot;Problem starting virtual install&quot;</span><span class="p">)</span>
<span class="n">conn</span> <span class="o">=</span> <span class="n">libvirt</span><span class="o">.</span><span class="n">openReadOnly</span><span class="p">(</span><span class="bp">None</span><span class="p">)</span>
<span class="n">dom</span> <span class="o">=</span> <span class="n">conn</span><span class="o">.</span><span class="n">lookupByName</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">virt_name</span><span class="p">)</span>
<span class="c"># TODO: If vnc has been passed, we should look up the port and print that</span>
<span class="c"># for the user at this point</span>
<span class="k">while</span> <span class="n">dom</span><span class="o">.</span><span class="n">isActive</span><span class="p">()</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">log_check</span><span class="p">():</span>
<span class="n">sys</span><span class="o">.</span><span class="n">stdout</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">&quot;.&quot;</span><span class="p">)</span>
<span class="n">sys</span><span class="o">.</span><span class="n">stdout</span><span class="o">.</span><span class="n">flush</span><span class="p">()</span>
<span class="n">sleep</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span>
<span class="k">print</span>
<span class="k">if</span> <span class="n">log_check</span><span class="p">():</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span> <span class="s">&quot;Installation error detected. See logfile.&quot;</span> <span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span> <span class="s">&quot;Install finished. Or at least virt shut down.&quot;</span> <span class="p">)</span>
<div class="viewcode-block" id="VirtualInstall.destroy"><a class="viewcode-back" href="../../pylorax.html#pylorax.installer.VirtualInstall.destroy">[docs]</a> <span class="k">def</span> <span class="nf">destroy</span><span class="p">(</span> <span class="bp">self</span> <span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Make sure the virt has been shut down and destroyed</span>
<span class="sd"> Could use libvirt for this instead.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span> <span class="s">&quot;Shutting down </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">virt_name</span><span class="p">)</span>
<span class="n">subprocess</span><span class="o">.</span><span class="n">call</span><span class="p">([</span><span class="s">&quot;virsh&quot;</span><span class="p">,</span> <span class="s">&quot;destroy&quot;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">virt_name</span><span class="p">])</span>
<span class="n">subprocess</span><span class="o">.</span><span class="n">call</span><span class="p">([</span><span class="s">&quot;virsh&quot;</span><span class="p">,</span> <span class="s">&quot;undefine&quot;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">virt_name</span><span class="p">])</span>
</div></div>
<div class="viewcode-block" id="novirt_install"><a class="viewcode-back" href="../../pylorax.html#pylorax.installer.novirt_install">[docs]</a><span class="k">def</span> <span class="nf">novirt_install</span><span class="p">(</span><span class="n">opts</span><span class="p">,</span> <span class="n">disk_img</span><span class="p">,</span> <span class="n">disk_size</span><span class="p">,</span> <span class="n">repo_url</span><span class="p">,</span> <span class="n">callback_func</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Use Anaconda to install to a disk image</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="kn">import</span> <span class="nn">selinux</span>
<span class="c"># Set selinux to Permissive if it is Enforcing</span>
<span class="n">selinux_enforcing</span> <span class="o">=</span> <span class="bp">False</span>
<span class="k">if</span> <span class="n">selinux</span><span class="o">.</span><span class="n">is_selinux_enabled</span><span class="p">()</span> <span class="ow">and</span> <span class="n">selinux</span><span class="o">.</span><span class="n">security_getenforce</span><span class="p">():</span>
<span class="n">selinux_enforcing</span> <span class="o">=</span> <span class="bp">True</span>
<span class="n">selinux</span><span class="o">.</span><span class="n">security_setenforce</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="c"># Clean up /tmp/ from previous runs to prevent stale info from being used</span>
<span class="k">for</span> <span class="n">path</span> <span class="ow">in</span> <span class="p">[</span><span class="s">&quot;/tmp/yum.repos.d/&quot;</span><span class="p">,</span> <span class="s">&quot;/tmp/yum.cache/&quot;</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">path</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">path</span><span class="p">)</span>
<span class="n">args</span> <span class="o">=</span> <span class="p">[</span><span class="s">&quot;--kickstart&quot;</span><span class="p">,</span> <span class="n">opts</span><span class="o">.</span><span class="n">ks</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="s">&quot;--cmdline&quot;</span><span class="p">,</span> <span class="s">&quot;--repo&quot;</span><span class="p">,</span> <span class="n">repo_url</span><span class="p">]</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">anaconda_args</span><span class="p">:</span>
<span class="k">for</span> <span class="n">arg</span> <span class="ow">in</span> <span class="n">opts</span><span class="o">.</span><span class="n">anaconda_args</span><span class="p">:</span>
<span class="n">args</span> <span class="o">+=</span> <span class="n">arg</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">&quot; &quot;</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">proxy</span><span class="p">:</span>
<span class="n">args</span> <span class="o">+=</span> <span class="p">[</span><span class="s">&quot;--proxy&quot;</span><span class="p">,</span> <span class="n">opts</span><span class="o">.</span><span class="n">proxy</span><span class="p">]</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">armplatform</span><span class="p">:</span>
<span class="n">args</span> <span class="o">+=</span> <span class="p">[</span><span class="s">&quot;--armplatform&quot;</span><span class="p">,</span> <span class="n">opts</span><span class="o">.</span><span class="n">armplatform</span><span class="p">]</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">make_iso</span> <span class="ow">or</span> <span class="n">opts</span><span class="o">.</span><span class="n">make_fsimage</span><span class="p">:</span>
<span class="c"># Make a blank fs image</span>
<span class="n">args</span> <span class="o">+=</span> <span class="p">[</span><span class="s">&quot;--dirinstall&quot;</span><span class="p">]</span>
<span class="n">mkext4img</span><span class="p">(</span><span class="bp">None</span><span class="p">,</span> <span class="n">disk_img</span><span class="p">,</span> <span class="n">label</span><span class="o">=</span><span class="n">opts</span><span class="o">.</span><span class="n">fs_label</span><span class="p">,</span> <span class="n">size</span><span class="o">=</span><span class="n">disk_size</span> <span class="o">*</span> <span class="mi">1024</span><span class="o">**</span><span class="mi">3</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">isdir</span><span class="p">(</span><span class="n">ROOT_PATH</span><span class="p">):</span>
<span class="n">os</span><span class="o">.</span><span class="n">mkdir</span><span class="p">(</span><span class="n">ROOT_PATH</span><span class="p">)</span>
<span class="n">mount</span><span class="p">(</span><span class="n">disk_img</span><span class="p">,</span> <span class="n">opts</span><span class="o">=</span><span class="s">&quot;loop&quot;</span><span class="p">,</span> <span class="n">mnt</span><span class="o">=</span><span class="n">ROOT_PATH</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">opts</span><span class="o">.</span><span class="n">make_tar</span><span class="p">:</span>
<span class="n">args</span> <span class="o">+=</span> <span class="p">[</span><span class="s">&quot;--dirinstall&quot;</span><span class="p">]</span>
<span class="c"># Install directly into ROOT_PATH, make sure it starts clean</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">exists</span><span class="p">(</span><span class="n">ROOT_PATH</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">ROOT_PATH</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">isdir</span><span class="p">(</span><span class="n">ROOT_PATH</span><span class="p">):</span>
<span class="n">os</span><span class="o">.</span><span class="n">mkdir</span><span class="p">(</span><span class="n">ROOT_PATH</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">args</span> <span class="o">+=</span> <span class="p">[</span><span class="s">&quot;--image&quot;</span><span class="p">,</span> <span class="n">disk_img</span><span class="p">]</span>
<span class="c"># Create the sparse image</span>
<span class="n">mksparse</span><span class="p">(</span><span class="n">disk_img</span><span class="p">,</span> <span class="n">disk_size</span> <span class="o">*</span> <span class="mi">1024</span><span class="o">**</span><span class="mi">3</span><span class="p">)</span>
<span class="c"># Make sure anaconda has the right product and release</span>
<span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="p">[</span><span class="s">&quot;ANACONDA_PRODUCTNAME&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">opts</span><span class="o">.</span><span class="n">project</span>
<span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="p">[</span><span class="s">&quot;ANACONDA_PRODUCTVERSION&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">opts</span><span class="o">.</span><span class="n">releasever</span>
<span class="n">rc</span> <span class="o">=</span> <span class="n">execWithRedirect</span><span class="p">(</span><span class="s">&quot;anaconda&quot;</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">callback_func</span><span class="o">=</span><span class="n">callback_func</span><span class="p">)</span>
<span class="c"># Move the anaconda logs over to a log directory</span>
<span class="n">log_dir</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">abspath</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">dirname</span><span class="p">(</span><span class="n">opts</span><span class="o">.</span><span class="n">logfile</span><span class="p">))</span>
<span class="n">log_anaconda</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">log_dir</span><span class="p">,</span> <span class="s">&quot;anaconda&quot;</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">isdir</span><span class="p">(</span><span class="n">log_anaconda</span><span class="p">):</span>
<span class="n">os</span><span class="o">.</span><span class="n">mkdir</span><span class="p">(</span><span class="n">log_anaconda</span><span class="p">)</span>
<span class="k">for</span> <span class="n">l</span> <span class="ow">in</span> <span class="p">[</span><span class="s">&quot;anaconda.log&quot;</span><span class="p">,</span> <span class="s">&quot;ifcfg.log&quot;</span><span class="p">,</span> <span class="s">&quot;program.log&quot;</span><span class="p">,</span> <span class="s">&quot;storage.log&quot;</span><span class="p">,</span>
<span class="s">&quot;packaging.log&quot;</span><span class="p">,</span> <span class="s">&quot;yum.log&quot;</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">exists</span><span class="p">(</span><span class="s">&quot;/tmp/&quot;</span><span class="o">+</span><span class="n">l</span><span class="p">):</span>
<span class="n">shutil</span><span class="o">.</span><span class="n">copy2</span><span class="p">(</span><span class="s">&quot;/tmp/&quot;</span><span class="o">+</span><span class="n">l</span><span class="p">,</span> <span class="n">log_anaconda</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="s">&quot;/tmp/&quot;</span><span class="o">+</span><span class="n">l</span><span class="p">)</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">make_iso</span> <span class="ow">or</span> <span class="n">opts</span><span class="o">.</span><span class="n">make_fsimage</span><span class="p">:</span>
<span class="n">umount</span><span class="p">(</span><span class="n">ROOT_PATH</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="c"># If anaconda failed the disk image may still be in use by dm</span>
<span class="n">execWithRedirect</span><span class="p">(</span><span class="s">&quot;anaconda-cleanup&quot;</span><span class="p">,</span> <span class="p">[])</span>
<span class="k">if</span> <span class="n">disk_img</span><span class="p">:</span>
<span class="n">dm_name</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">splitext</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">disk_img</span><span class="p">))[</span><span class="mi">0</span><span class="p">]</span>
<span class="n">dm_path</span> <span class="o">=</span> <span class="s">&quot;/dev/mapper/&quot;</span><span class="o">+</span><span class="n">dm_name</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">exists</span><span class="p">(</span><span class="n">dm_path</span><span class="p">):</span>
<span class="n">dm_detach</span><span class="p">(</span><span class="n">dm_path</span><span class="p">)</span>
<span class="n">loop_detach</span><span class="p">(</span><span class="n">get_loop_name</span><span class="p">(</span><span class="n">disk_img</span><span class="p">))</span>
<span class="k">if</span> <span class="n">selinux_enforcing</span><span class="p">:</span>
<span class="n">selinux</span><span class="o">.</span><span class="n">security_setenforce</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="k">if</span> <span class="n">rc</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">InstallError</span><span class="p">(</span><span class="s">&quot;novirt_install failed&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">make_tar</span><span class="p">:</span>
<span class="n">compress_args</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">arg</span> <span class="ow">in</span> <span class="n">opts</span><span class="o">.</span><span class="n">compress_args</span><span class="p">:</span>
<span class="n">compress_args</span> <span class="o">+=</span> <span class="n">arg</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">&quot; &quot;</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="n">rc</span> <span class="o">=</span> <span class="n">mktar</span><span class="p">(</span><span class="n">ROOT_PATH</span><span class="p">,</span> <span class="n">disk_img</span><span class="p">,</span> <span class="n">opts</span><span class="o">.</span><span class="n">compression</span><span class="p">,</span> <span class="n">compress_args</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">ROOT_PATH</span><span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;tar finished with rc=</span><span class="si">%d</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">rc</span><span class="p">)</span>
<span class="k">if</span> <span class="n">rc</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">InstallError</span><span class="p">(</span><span class="s">&quot;novirt_install failed&quot;</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">opts</span><span class="o">.</span><span class="n">qcow2</span><span class="p">:</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;Converting </span><span class="si">%s</span><span class="s"> to qcow2&quot;</span><span class="p">,</span> <span class="n">disk_img</span><span class="p">)</span>
<span class="n">qcow2_args</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">arg</span> <span class="ow">in</span> <span class="n">opts</span><span class="o">.</span><span class="n">qcow2_args</span><span class="p">:</span>
<span class="n">qcow2_args</span> <span class="o">+=</span> <span class="n">arg</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">&quot; &quot;</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="c"># convert the image to qcow2 format</span>
<span class="k">if</span> <span class="s">&quot;-O&quot;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">qcow2_args</span><span class="p">:</span>
<span class="n">qcow2_args</span><span class="o">.</span><span class="n">extend</span><span class="p">([</span><span class="s">&quot;-O&quot;</span><span class="p">,</span> <span class="s">&quot;qcow2&quot;</span><span class="p">])</span>
<span class="n">qcow2_img</span> <span class="o">=</span> <span class="n">tempfile</span><span class="o">.</span><span class="n">mktemp</span><span class="p">(</span><span class="n">prefix</span><span class="o">=</span><span class="s">&quot;disk&quot;</span><span class="p">,</span> <span class="n">suffix</span><span class="o">=</span><span class="s">&quot;.img&quot;</span><span class="p">)</span>
<span class="n">execWithRedirect</span><span class="p">(</span><span class="s">&quot;qemu-img&quot;</span><span class="p">,</span> <span class="p">[</span><span class="s">&quot;convert&quot;</span><span class="p">]</span> <span class="o">+</span> <span class="n">qcow2_args</span> <span class="o">+</span> <span class="p">[</span><span class="n">disk_img</span><span class="p">,</span> <span class="n">qcow2_img</span><span class="p">],</span> <span class="n">raise_err</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
<span class="n">execWithRedirect</span><span class="p">(</span><span class="s">&quot;mv&quot;</span><span class="p">,</span> <span class="p">[</span><span class="s">&quot;-f&quot;</span><span class="p">,</span> <span class="n">qcow2_img</span><span class="p">,</span> <span class="n">disk_img</span><span class="p">],</span> <span class="n">raise_err</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="virt_install"><a class="viewcode-back" href="../../pylorax.html#pylorax.installer.virt_install">[docs]</a><span class="k">def</span> <span class="nf">virt_install</span><span class="p">(</span><span class="n">opts</span><span class="p">,</span> <span class="n">install_log</span><span class="p">,</span> <span class="n">disk_img</span><span class="p">,</span> <span class="n">disk_size</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Use virt-install to install to a disk image</span>
<span class="sd"> install_log is the path to write the log from virt-install</span>
<span class="sd"> disk_img is the full path to the final disk or filesystem image</span>
<span class="sd"> disk_size is the size of the disk to create in GiB</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">iso_mount</span> <span class="o">=</span> <span class="n">IsoMountpoint</span><span class="p">(</span><span class="n">opts</span><span class="o">.</span><span class="n">iso</span><span class="p">,</span> <span class="n">opts</span><span class="o">.</span><span class="n">location</span><span class="p">)</span>
<span class="n">log_monitor</span> <span class="o">=</span> <span class="n">LogMonitor</span><span class="p">(</span><span class="n">install_log</span><span class="p">)</span>
<span class="n">kernel_args</span> <span class="o">=</span> <span class="s">&quot;&quot;</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">kernel_args</span><span class="p">:</span>
<span class="n">kernel_args</span> <span class="o">+=</span> <span class="n">opts</span><span class="o">.</span><span class="n">kernel_args</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">proxy</span><span class="p">:</span>
<span class="n">kernel_args</span> <span class="o">+=</span> <span class="s">&quot; proxy=&quot;</span><span class="o">+</span><span class="n">opts</span><span class="o">.</span><span class="n">proxy</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">qcow2</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">opts</span><span class="o">.</span><span class="n">make_fsimage</span><span class="p">:</span>
<span class="c"># virt-install can&#39;t take all the qcow2 options so create the image first</span>
<span class="n">qcow2_args</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">arg</span> <span class="ow">in</span> <span class="n">opts</span><span class="o">.</span><span class="n">qcow2_args</span><span class="p">:</span>
<span class="n">qcow2_args</span> <span class="o">+=</span> <span class="n">arg</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">&quot; &quot;</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="n">mkqcow2</span><span class="p">(</span><span class="n">disk_img</span><span class="p">,</span> <span class="n">disk_size</span><span class="o">*</span><span class="mi">1024</span><span class="o">**</span><span class="mi">3</span><span class="p">,</span> <span class="n">qcow2_args</span><span class="p">)</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">make_fsimage</span> <span class="ow">or</span> <span class="n">opts</span><span class="o">.</span><span class="n">make_tar</span><span class="p">:</span>
<span class="n">diskimg_path</span> <span class="o">=</span> <span class="n">tempfile</span><span class="o">.</span><span class="n">mktemp</span><span class="p">(</span><span class="n">prefix</span><span class="o">=</span><span class="s">&quot;disk&quot;</span><span class="p">,</span> <span class="n">suffix</span><span class="o">=</span><span class="s">&quot;.img&quot;</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">diskimg_path</span> <span class="o">=</span> <span class="n">disk_img</span>
<span class="n">virt</span> <span class="o">=</span> <span class="n">VirtualInstall</span><span class="p">(</span><span class="n">iso_mount</span><span class="p">,</span> <span class="n">opts</span><span class="o">.</span><span class="n">ks</span><span class="p">,</span> <span class="n">diskimg_path</span><span class="p">,</span> <span class="n">disk_size</span><span class="p">,</span>
<span class="n">kernel_args</span><span class="p">,</span> <span class="n">opts</span><span class="o">.</span><span class="n">ram</span><span class="p">,</span> <span class="n">opts</span><span class="o">.</span><span class="n">vnc</span><span class="p">,</span> <span class="n">opts</span><span class="o">.</span><span class="n">arch</span><span class="p">,</span>
<span class="n">log_check</span> <span class="o">=</span> <span class="n">log_monitor</span><span class="o">.</span><span class="n">server</span><span class="o">.</span><span class="n">log_check</span><span class="p">,</span>
<span class="n">virtio_host</span> <span class="o">=</span> <span class="n">log_monitor</span><span class="o">.</span><span class="n">host</span><span class="p">,</span>
<span class="n">virtio_port</span> <span class="o">=</span> <span class="n">log_monitor</span><span class="o">.</span><span class="n">port</span><span class="p">,</span>
<span class="n">qcow2</span><span class="o">=</span><span class="n">opts</span><span class="o">.</span><span class="n">qcow2</span><span class="p">)</span>
<span class="n">virt</span><span class="o">.</span><span class="n">destroy</span><span class="p">()</span>
<span class="n">log_monitor</span><span class="o">.</span><span class="n">shutdown</span><span class="p">()</span>
<span class="n">iso_mount</span><span class="o">.</span><span class="n">umount</span><span class="p">()</span>
<span class="k">if</span> <span class="n">log_monitor</span><span class="o">.</span><span class="n">server</span><span class="o">.</span><span class="n">log_check</span><span class="p">():</span>
<span class="k">raise</span> <span class="n">InstallError</span><span class="p">(</span><span class="s">&quot;virt_install failed&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">make_fsimage</span><span class="p">:</span>
<span class="n">mkdiskfsimage</span><span class="p">(</span><span class="n">diskimg_path</span><span class="p">,</span> <span class="n">disk_img</span><span class="p">,</span> <span class="n">label</span><span class="o">=</span><span class="n">opts</span><span class="o">.</span><span class="n">fs_label</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">diskimg_path</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">opts</span><span class="o">.</span><span class="n">make_tar</span><span class="p">:</span>
<span class="n">compress_args</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">arg</span> <span class="ow">in</span> <span class="n">opts</span><span class="o">.</span><span class="n">compress_args</span><span class="p">:</span>
<span class="n">compress_args</span> <span class="o">+=</span> <span class="n">arg</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">&quot; &quot;</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="k">with</span> <span class="n">PartitionMount</span><span class="p">(</span><span class="n">diskimg_path</span><span class="p">)</span> <span class="k">as</span> <span class="n">img_mount</span><span class="p">:</span>
<span class="k">if</span> <span class="n">img_mount</span> <span class="ow">and</span> <span class="n">img_mount</span><span class="o">.</span><span class="n">mount_dir</span><span class="p">:</span>
<span class="n">rc</span> <span class="o">=</span> <span class="n">mktar</span><span class="p">(</span><span class="n">img_mount</span><span class="o">.</span><span class="n">mount_dir</span><span class="p">,</span> <span class="n">disk_img</span><span class="p">,</span> <span class="n">opts</span><span class="o">.</span><span class="n">compression</span><span class="p">,</span> <span class="n">compress_args</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">diskimg_path</span><span class="p">)</span>
<span class="k">if</span> <span class="n">rc</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">InstallError</span><span class="p">(</span><span class="s">&quot;virt_install failed&quot;</span><span class="p">)</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">Lorax 19.7.10 documentation</a> &raquo;</li>
<li><a href="../index.html" >Module code</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2017, Red Hat, Inc..
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>

View File

@ -0,0 +1,217 @@
<!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>pylorax.logmonitor &mdash; Lorax 19.7.10 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: '19.7.10',
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>
<link rel="top" title="Lorax 19.7.10 documentation" href="../../index.html" />
<link rel="up" title="Module code" href="../index.html" />
</head>
<body>
<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">Lorax 19.7.10 documentation</a> &raquo;</li>
<li><a href="../index.html" accesskey="U">Module code</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<h1>Source code for pylorax.logmonitor</h1><div class="highlight"><pre>
<span class="c">#</span>
<span class="c"># Copyright (C) 2011-2017 Red Hat, Inc.</span>
<span class="c">#</span>
<span class="c"># This program is free software; you can redistribute it and/or modify</span>
<span class="c"># it under the terms of the GNU General Public License as published by</span>
<span class="c"># the Free Software Foundation; either version 2 of the License, or</span>
<span class="c"># (at your option) any later version.</span>
<span class="c">#</span>
<span class="c"># This program is distributed in the hope that it will be useful,</span>
<span class="c"># but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<span class="c"># MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span>
<span class="c"># GNU General Public License for more details.</span>
<span class="c">#</span>
<span class="c"># You should have received a copy of the GNU General Public License</span>
<span class="c"># along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;.</span>
<span class="c">#</span>
<span class="kn">import</span> <span class="nn">re</span>
<span class="kn">import</span> <span class="nn">socket</span>
<span class="kn">import</span> <span class="nn">SocketServer</span>
<span class="kn">import</span> <span class="nn">threading</span>
<div class="viewcode-block" id="LogRequestHandler"><a class="viewcode-back" href="../../pylorax.html#pylorax.logmonitor.LogRequestHandler">[docs]</a><span class="k">class</span> <span class="nc">LogRequestHandler</span><span class="p">(</span><span class="n">SocketServer</span><span class="o">.</span><span class="n">BaseRequestHandler</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Handle monitoring and saving the logfiles from the virtual install</span>
<span class="sd"> &quot;&quot;&quot;</span>
<div class="viewcode-block" id="LogRequestHandler.setup"><a class="viewcode-back" href="../../pylorax.html#pylorax.logmonitor.LogRequestHandler.setup">[docs]</a> <span class="k">def</span> <span class="nf">setup</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">server</span><span class="o">.</span><span class="n">log_path</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">fp</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">server</span><span class="o">.</span><span class="n">log_path</span><span class="p">,</span> <span class="s">&quot;w&quot;</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">print</span> <span class="s">&quot;no log_path specified&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">request</span><span class="o">.</span><span class="n">settimeout</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="LogRequestHandler.handle"><a class="viewcode-back" href="../../pylorax.html#pylorax.logmonitor.LogRequestHandler.handle">[docs]</a> <span class="k">def</span> <span class="nf">handle</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Handle writing incoming data to a logfile and</span>
<span class="sd"> checking the logs for any Tracebacks or other errors that indicate</span>
<span class="sd"> that the install failed.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">line</span> <span class="o">=</span> <span class="s">&quot;&quot;</span>
<span class="k">while</span> <span class="bp">True</span><span class="p">:</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">server</span><span class="o">.</span><span class="n">kill</span><span class="p">:</span>
<span class="k">break</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">data</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">request</span><span class="o">.</span><span class="n">recv</span><span class="p">(</span><span class="mi">4096</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">fp</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">fp</span><span class="o">.</span><span class="n">flush</span><span class="p">()</span>
<span class="c"># check the data for errors and set error flag</span>
<span class="c"># need to assemble it into lines so we can test for the error</span>
<span class="c"># string.</span>
<span class="k">while</span> <span class="n">data</span><span class="p">:</span>
<span class="n">more</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">&quot;</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="n">line</span> <span class="o">+=</span> <span class="n">more</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">more</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">iserror</span><span class="p">(</span><span class="n">line</span><span class="p">)</span>
<span class="n">line</span> <span class="o">=</span> <span class="s">&quot;&quot;</span>
<span class="n">data</span> <span class="o">=</span> <span class="n">more</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">data</span> <span class="o">=</span> <span class="bp">None</span>
<span class="k">except</span> <span class="n">socket</span><span class="o">.</span><span class="n">timeout</span><span class="p">:</span>
<span class="k">pass</span>
<span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
<span class="k">break</span>
</div>
<div class="viewcode-block" id="LogRequestHandler.finish"><a class="viewcode-back" href="../../pylorax.html#pylorax.logmonitor.LogRequestHandler.finish">[docs]</a> <span class="k">def</span> <span class="nf">finish</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">fp</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
</div>
<div class="viewcode-block" id="LogRequestHandler.iserror"><a class="viewcode-back" href="../../pylorax.html#pylorax.logmonitor.LogRequestHandler.iserror">[docs]</a> <span class="k">def</span> <span class="nf">iserror</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">line</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Check a line to see if it contains an error indicating install failure</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">simple_tests</span> <span class="o">=</span> <span class="p">[</span><span class="s">&quot;Traceback (&quot;</span><span class="p">,</span>
<span class="s">&quot;Out of memory:&quot;</span><span class="p">,</span>
<span class="s">&quot;Call Trace:&quot;</span><span class="p">,</span>
<span class="s">&quot;insufficient disk space:&quot;</span><span class="p">]</span>
<span class="n">re_tests</span> <span class="o">=</span> <span class="p">[</span><span class="s">r&quot;packaging: base repo .* not valid&quot;</span><span class="p">]</span>
<span class="k">for</span> <span class="n">t</span> <span class="ow">in</span> <span class="n">simple_tests</span><span class="p">:</span>
<span class="k">if</span> <span class="n">line</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="n">t</span><span class="p">)</span> <span class="o">&gt;</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">server</span><span class="o">.</span><span class="n">log_error</span> <span class="o">=</span> <span class="bp">True</span>
<span class="k">return</span>
<span class="k">for</span> <span class="n">t</span> <span class="ow">in</span> <span class="n">re_tests</span><span class="p">:</span>
<span class="k">if</span> <span class="n">re</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="n">t</span><span class="p">,</span> <span class="n">line</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">server</span><span class="o">.</span><span class="n">log_error</span> <span class="o">=</span> <span class="bp">True</span>
<span class="k">return</span>
</div></div>
<div class="viewcode-block" id="LogServer"><a class="viewcode-back" href="../../pylorax.html#pylorax.logmonitor.LogServer">[docs]</a><span class="k">class</span> <span class="nc">LogServer</span><span class="p">(</span><span class="n">SocketServer</span><span class="o">.</span><span class="n">TCPServer</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Add path to logfile</span>
<span class="sd"> Add log error flag</span>
<span class="sd"> Add a kill switch</span>
<span class="sd"> &quot;&quot;&quot;</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">log_path</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">kill</span> <span class="o">=</span> <span class="bp">False</span>
<span class="bp">self</span><span class="o">.</span><span class="n">log_error</span> <span class="o">=</span> <span class="bp">False</span>
<span class="bp">self</span><span class="o">.</span><span class="n">log_path</span> <span class="o">=</span> <span class="n">log_path</span>
<span class="n">SocketServer</span><span class="o">.</span><span class="n">TCPServer</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="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
<div class="viewcode-block" id="LogServer.log_check"><a class="viewcode-back" href="../../pylorax.html#pylorax.logmonitor.LogServer.log_check">[docs]</a> <span class="k">def</span> <span class="nf">log_check</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">log_error</span>
</div></div>
<div class="viewcode-block" id="LogMonitor"><a class="viewcode-back" href="../../pylorax.html#pylorax.logmonitor.LogMonitor">[docs]</a><span class="k">class</span> <span class="nc">LogMonitor</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Contains all the stuff needed to setup a thread to listen to the logs</span>
<span class="sd"> from the virtual install</span>
<span class="sd"> &quot;&quot;&quot;</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">log_path</span><span class="p">,</span> <span class="n">host</span><span class="o">=</span><span class="s">&quot;localhost&quot;</span><span class="p">,</span> <span class="n">port</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Fire up the thread listening for logs</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">server</span> <span class="o">=</span> <span class="n">LogServer</span><span class="p">(</span><span class="n">log_path</span><span class="p">,</span> <span class="p">(</span><span class="n">host</span><span class="p">,</span> <span class="n">port</span><span class="p">),</span> <span class="n">LogRequestHandler</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">host</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">port</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">server</span><span class="o">.</span><span class="n">server_address</span>
<span class="bp">self</span><span class="o">.</span><span class="n">log_path</span> <span class="o">=</span> <span class="n">log_path</span>
<span class="bp">self</span><span class="o">.</span><span class="n">server_thread</span> <span class="o">=</span> <span class="n">threading</span><span class="o">.</span><span class="n">Thread</span><span class="p">(</span><span class="n">target</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">server</span><span class="o">.</span><span class="n">handle_request</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">server_thread</span><span class="o">.</span><span class="n">daemon</span> <span class="o">=</span> <span class="bp">True</span>
<span class="bp">self</span><span class="o">.</span><span class="n">server_thread</span><span class="o">.</span><span class="n">start</span><span class="p">()</span>
<div class="viewcode-block" id="LogMonitor.shutdown"><a class="viewcode-back" href="../../pylorax.html#pylorax.logmonitor.LogMonitor.shutdown">[docs]</a> <span class="k">def</span> <span class="nf">shutdown</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">server</span><span class="o">.</span><span class="n">kill</span> <span class="o">=</span> <span class="bp">True</span>
<span class="bp">self</span><span class="o">.</span><span class="n">server_thread</span><span class="o">.</span><span class="n">join</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">Lorax 19.7.10 documentation</a> &raquo;</li>
<li><a href="../index.html" >Module code</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2017, Red Hat, Inc..
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>

View File

@ -0,0 +1,759 @@
<!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>pylorax.ltmpl &mdash; Lorax 19.7.10 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: '19.7.10',
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>
<link rel="top" title="Lorax 19.7.10 documentation" href="../../index.html" />
<link rel="up" title="Module code" href="../index.html" />
</head>
<body>
<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">Lorax 19.7.10 documentation</a> &raquo;</li>
<li><a href="../index.html" accesskey="U">Module code</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<h1>Source code for pylorax.ltmpl</h1><div class="highlight"><pre>
<span class="c">#</span>
<span class="c"># ltmpl.py</span>
<span class="c">#</span>
<span class="c"># Copyright (C) 2009 Red Hat, Inc.</span>
<span class="c">#</span>
<span class="c"># This program is free software; you can redistribute it and/or modify</span>
<span class="c"># it under the terms of the GNU General Public License as published by</span>
<span class="c"># the Free Software Foundation; either version 2 of the License, or</span>
<span class="c"># (at your option) any later version.</span>
<span class="c">#</span>
<span class="c"># This program is distributed in the hope that it will be useful,</span>
<span class="c"># but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<span class="c"># MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span>
<span class="c"># GNU General Public License for more details.</span>
<span class="c">#</span>
<span class="c"># You should have received a copy of the GNU General Public License</span>
<span class="c"># along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;.</span>
<span class="c">#</span>
<span class="c"># Red Hat Author(s): Martin Gracik &lt;mgracik@redhat.com&gt;</span>
<span class="c"># Will Woods &lt;wwoods@redhat.com&gt;</span>
<span class="c">#</span>
<span class="kn">import</span> <span class="nn">logging</span>
<span class="n">logger</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s">&quot;pylorax.ltmpl&quot;</span><span class="p">)</span>
<span class="kn">import</span> <span class="nn">os</span><span class="o">,</span> <span class="nn">re</span><span class="o">,</span> <span class="nn">glob</span><span class="o">,</span> <span class="nn">shlex</span><span class="o">,</span> <span class="nn">fnmatch</span>
<span class="kn">from</span> <span class="nn">os.path</span> <span class="kn">import</span> <span class="n">basename</span><span class="p">,</span> <span class="n">isdir</span>
<span class="kn">from</span> <span class="nn">subprocess</span> <span class="kn">import</span> <span class="n">CalledProcessError</span>
<span class="kn">import</span> <span class="nn">shutil</span>
<span class="kn">from</span> <span class="nn">pylorax.sysutils</span> <span class="kn">import</span> <span class="n">joinpaths</span><span class="p">,</span> <span class="n">cpfile</span><span class="p">,</span> <span class="n">mvfile</span><span class="p">,</span> <span class="n">replace</span><span class="p">,</span> <span class="n">remove</span>
<span class="kn">from</span> <span class="nn">pylorax</span> <span class="kn">import</span> <span class="n">yumhelper</span>
<span class="kn">from</span> <span class="nn">pylorax.base</span> <span class="kn">import</span> <span class="n">DataHolder</span>
<span class="kn">from</span> <span class="nn">pylorax.executils</span> <span class="kn">import</span> <span class="n">runcmd</span><span class="p">,</span> <span class="n">runcmd_output</span>
<span class="kn">from</span> <span class="nn">pylorax.imgutils</span> <span class="kn">import</span> <span class="n">mkcpio</span>
<span class="kn">from</span> <span class="nn">mako.lookup</span> <span class="kn">import</span> <span class="n">TemplateLookup</span>
<span class="kn">from</span> <span class="nn">mako.exceptions</span> <span class="kn">import</span> <span class="n">text_error_template</span>
<span class="kn">import</span> <span class="nn">sys</span><span class="o">,</span> <span class="nn">traceback</span>
<span class="kn">import</span> <span class="nn">struct</span>
<div class="viewcode-block" id="LoraxTemplate"><a class="viewcode-back" href="../../pylorax.html#pylorax.ltmpl.LoraxTemplate">[docs]</a><span class="k">class</span> <span class="nc">LoraxTemplate</span><span class="p">(</span><span class="nb">object</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">directories</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
<span class="k">if</span> <span class="n">directories</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span>
<span class="n">directories</span> <span class="o">=</span> <span class="p">[</span><span class="s">&quot;/usr/share/lorax&quot;</span><span class="p">]</span>
<span class="c"># we have to add [&quot;/&quot;] to the template lookup directories or the</span>
<span class="c"># file includes won&#39;t work properly for absolute paths</span>
<span class="bp">self</span><span class="o">.</span><span class="n">directories</span> <span class="o">=</span> <span class="p">[</span><span class="s">&quot;/&quot;</span><span class="p">]</span> <span class="o">+</span> <span class="n">directories</span>
<span class="bp">self</span><span class="o">.</span><span class="n">lines</span> <span class="o">=</span> <span class="p">[]</span>
<div class="viewcode-block" id="LoraxTemplate.parse"><a class="viewcode-back" href="../../pylorax.html#pylorax.ltmpl.LoraxTemplate.parse">[docs]</a> <span class="k">def</span> <span class="nf">parse</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">template_file</span><span class="p">,</span> <span class="n">variables</span><span class="p">):</span>
<span class="n">lookup</span> <span class="o">=</span> <span class="n">TemplateLookup</span><span class="p">(</span><span class="n">directories</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">directories</span><span class="p">)</span>
<span class="n">template</span> <span class="o">=</span> <span class="n">lookup</span><span class="o">.</span><span class="n">get_template</span><span class="p">(</span><span class="n">template_file</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">textbuf</span> <span class="o">=</span> <span class="n">template</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="o">**</span><span class="n">variables</span><span class="p">)</span>
<span class="k">except</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="n">text_error_template</span><span class="p">()</span><span class="o">.</span><span class="n">render</span><span class="p">())</span>
<span class="k">raise</span>
<span class="c"># split, strip and remove empty lines</span>
<span class="n">lines</span> <span class="o">=</span> <span class="n">textbuf</span><span class="o">.</span><span class="n">splitlines</span><span class="p">()</span>
<span class="n">lines</span> <span class="o">=</span> <span class="nb">map</span><span class="p">(</span><span class="k">lambda</span> <span class="n">line</span><span class="p">:</span> <span class="n">line</span><span class="o">.</span><span class="n">strip</span><span class="p">(),</span> <span class="n">lines</span><span class="p">)</span>
<span class="n">lines</span> <span class="o">=</span> <span class="nb">filter</span><span class="p">(</span><span class="k">lambda</span> <span class="n">line</span><span class="p">:</span> <span class="n">line</span><span class="p">,</span> <span class="n">lines</span><span class="p">)</span>
<span class="c"># remove comments</span>
<span class="n">lines</span> <span class="o">=</span> <span class="nb">filter</span><span class="p">(</span><span class="k">lambda</span> <span class="n">line</span><span class="p">:</span> <span class="ow">not</span> <span class="n">line</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s">&quot;#&quot;</span><span class="p">),</span> <span class="n">lines</span><span class="p">)</span>
<span class="c"># mako template now returns unicode strings</span>
<span class="n">lines</span> <span class="o">=</span> <span class="nb">map</span><span class="p">(</span><span class="k">lambda</span> <span class="n">line</span><span class="p">:</span> <span class="n">line</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s">&quot;utf8&quot;</span><span class="p">),</span> <span class="n">lines</span><span class="p">)</span>
<span class="c"># split with shlex and perform brace expansion</span>
<span class="n">lines</span> <span class="o">=</span> <span class="nb">map</span><span class="p">(</span><span class="n">split_and_expand</span><span class="p">,</span> <span class="n">lines</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">lines</span> <span class="o">=</span> <span class="n">lines</span>
<span class="k">return</span> <span class="n">lines</span>
</div></div>
<div class="viewcode-block" id="split_and_expand"><a class="viewcode-back" href="../../pylorax.html#pylorax.ltmpl.split_and_expand">[docs]</a><span class="k">def</span> <span class="nf">split_and_expand</span><span class="p">(</span><span class="n">line</span><span class="p">):</span>
<span class="k">return</span> <span class="p">[</span><span class="n">exp</span> <span class="k">for</span> <span class="n">word</span> <span class="ow">in</span> <span class="n">shlex</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="n">line</span><span class="p">)</span> <span class="k">for</span> <span class="n">exp</span> <span class="ow">in</span> <span class="n">brace_expand</span><span class="p">(</span><span class="n">word</span><span class="p">)]</span>
</div>
<div class="viewcode-block" id="brace_expand"><a class="viewcode-back" href="../../pylorax.html#pylorax.ltmpl.brace_expand">[docs]</a><span class="k">def</span> <span class="nf">brace_expand</span><span class="p">(</span><span class="n">s</span><span class="p">):</span>
<span class="k">if</span> <span class="ow">not</span> <span class="p">(</span><span class="s">&#39;{&#39;</span> <span class="ow">in</span> <span class="n">s</span> <span class="ow">and</span> <span class="s">&#39;,&#39;</span> <span class="ow">in</span> <span class="n">s</span> <span class="ow">and</span> <span class="s">&#39;}&#39;</span> <span class="ow">in</span> <span class="n">s</span><span class="p">):</span>
<span class="k">yield</span> <span class="n">s</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">right</span> <span class="o">=</span> <span class="n">s</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="s">&#39;}&#39;</span><span class="p">)</span>
<span class="n">left</span> <span class="o">=</span> <span class="n">s</span><span class="p">[:</span><span class="n">right</span><span class="p">]</span><span class="o">.</span><span class="n">rfind</span><span class="p">(</span><span class="s">&#39;{&#39;</span><span class="p">)</span>
<span class="p">(</span><span class="n">prefix</span><span class="p">,</span> <span class="n">choices</span><span class="p">,</span> <span class="n">suffix</span><span class="p">)</span> <span class="o">=</span> <span class="p">(</span><span class="n">s</span><span class="p">[:</span><span class="n">left</span><span class="p">],</span> <span class="n">s</span><span class="p">[</span><span class="n">left</span><span class="o">+</span><span class="mi">1</span><span class="p">:</span><span class="n">right</span><span class="p">],</span> <span class="n">s</span><span class="p">[</span><span class="n">right</span><span class="o">+</span><span class="mi">1</span><span class="p">:])</span>
<span class="k">for</span> <span class="n">choice</span> <span class="ow">in</span> <span class="n">choices</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">&#39;,&#39;</span><span class="p">):</span>
<span class="k">for</span> <span class="n">alt</span> <span class="ow">in</span> <span class="n">brace_expand</span><span class="p">(</span><span class="n">prefix</span><span class="o">+</span><span class="n">choice</span><span class="o">+</span><span class="n">suffix</span><span class="p">):</span>
<span class="k">yield</span> <span class="n">alt</span>
</div>
<div class="viewcode-block" id="rglob"><a class="viewcode-back" href="../../pylorax.html#pylorax.ltmpl.rglob">[docs]</a><span class="k">def</span> <span class="nf">rglob</span><span class="p">(</span><span class="n">pathname</span><span class="p">,</span> <span class="n">root</span><span class="o">=</span><span class="s">&quot;/&quot;</span><span class="p">,</span> <span class="n">fatal</span><span class="o">=</span><span class="bp">False</span><span class="p">):</span>
<span class="n">seen</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
<span class="n">rootlen</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">root</span><span class="p">)</span><span class="o">+</span><span class="mi">1</span>
<span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">glob</span><span class="o">.</span><span class="n">iglob</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">root</span><span class="p">,</span> <span class="n">pathname</span><span class="p">)):</span>
<span class="k">if</span> <span class="n">f</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">seen</span><span class="p">:</span>
<span class="n">seen</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
<span class="k">yield</span> <span class="n">f</span><span class="p">[</span><span class="n">rootlen</span><span class="p">:]</span> <span class="c"># remove the root to produce relative path</span>
<span class="k">if</span> <span class="n">fatal</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">seen</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">IOError</span><span class="p">,</span> <span class="s">&quot;nothing matching </span><span class="si">%s</span><span class="s"> in </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">pathname</span><span class="p">,</span> <span class="n">root</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="rexists"><a class="viewcode-back" href="../../pylorax.html#pylorax.ltmpl.rexists">[docs]</a><span class="k">def</span> <span class="nf">rexists</span><span class="p">(</span><span class="n">pathname</span><span class="p">,</span> <span class="n">root</span><span class="o">=</span><span class="s">&quot;&quot;</span><span class="p">):</span>
<span class="c"># Generator is always True, even with no values;</span>
<span class="c"># bool(rglob(...)) won&#39;t work here.</span>
<span class="k">for</span> <span class="n">_path</span> <span class="ow">in</span> <span class="n">rglob</span><span class="p">(</span><span class="n">pathname</span><span class="p">,</span> <span class="n">root</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>
<span class="c"># TODO: operate inside an actual chroot for safety? Not that RPM bothers..</span></div>
<div class="viewcode-block" id="LoraxTemplateRunner"><a class="viewcode-back" href="../../pylorax.html#pylorax.ltmpl.LoraxTemplateRunner">[docs]</a><span class="k">class</span> <span class="nc">LoraxTemplateRunner</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> This class parses and executes Lorax templates. Sample usage:</span>
<span class="sd"> # install a bunch of packages</span>
<span class="sd"> runner = LoraxTemplateRunner(inroot=rundir, outroot=rundir, yum=yum_obj)</span>
<span class="sd"> runner.run(&quot;install-packages.ltmpl&quot;)</span>
<span class="sd"> # modify a runtime dir</span>
<span class="sd"> runner = LoraxTemplateRunner(inroot=rundir, outroot=newrun)</span>
<span class="sd"> runner.run(&quot;runtime-transmogrify.ltmpl&quot;)</span>
<span class="sd"> NOTES:</span>
<span class="sd"> * Parsing procedure is roughly:</span>
<span class="sd"> 1. Mako template expansion (on the whole file)</span>
<span class="sd"> 2. For each line of the result,</span>
<span class="sd"> a. Whitespace splitting (using shlex.split())</span>
<span class="sd"> b. Brace expansion (using brace_expand())</span>
<span class="sd"> c. If the first token is the name of a function, call that function</span>
<span class="sd"> with the rest of the line as arguments</span>
<span class="sd"> * Parsing and execution are *separate* passes - so you can&#39;t use the result</span>
<span class="sd"> of a command in an %if statement (or any other control statements)!</span>
<span class="sd"> * Commands that run external programs (systemctl, gconfset) currently use</span>
<span class="sd"> the *host*&#39;s copy of that program, which may cause problems if there&#39;s a</span>
<span class="sd"> big enough difference between the host and the image you&#39;re modifying.</span>
<span class="sd"> * The commands are not executed under a real chroot, so absolute symlinks</span>
<span class="sd"> will point *outside* the inroot/outroot. Be careful with symlinks!</span>
<span class="sd"> ADDING NEW COMMANDS:</span>
<span class="sd"> * Each template command is just a method of the LoraxTemplateRunner</span>
<span class="sd"> object - so adding a new command is as easy as adding a new function.</span>
<span class="sd"> * Each function gets arguments that correspond to the rest of the tokens</span>
<span class="sd"> on that line (after word splitting and brace expansion)</span>
<span class="sd"> * Commands should raise exceptions for errors - don&#39;t use sys.exit()</span>
<span class="sd"> &#39;&#39;&#39;</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">inroot</span><span class="p">,</span> <span class="n">outroot</span><span class="p">,</span> <span class="n">yum_obj</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">fatalerrors</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span>
<span class="n">templatedir</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">defaults</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
<span class="k">if</span> <span class="n">defaults</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span>
<span class="n">defaults</span> <span class="o">=</span> <span class="p">{}</span>
<span class="bp">self</span><span class="o">.</span><span class="n">inroot</span> <span class="o">=</span> <span class="n">inroot</span>
<span class="bp">self</span><span class="o">.</span><span class="n">outroot</span> <span class="o">=</span> <span class="n">outroot</span>
<span class="bp">self</span><span class="o">.</span><span class="n">yum</span> <span class="o">=</span> <span class="n">yum_obj</span>
<span class="bp">self</span><span class="o">.</span><span class="n">fatalerrors</span> <span class="o">=</span> <span class="n">fatalerrors</span>
<span class="bp">self</span><span class="o">.</span><span class="n">templatedir</span> <span class="o">=</span> <span class="n">templatedir</span> <span class="ow">or</span> <span class="s">&quot;/usr/share/lorax&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">templatefile</span> <span class="o">=</span> <span class="bp">None</span>
<span class="c"># some builtin methods</span>
<span class="bp">self</span><span class="o">.</span><span class="n">builtins</span> <span class="o">=</span> <span class="n">DataHolder</span><span class="p">(</span><span class="n">exists</span><span class="o">=</span><span class="k">lambda</span> <span class="n">p</span><span class="p">:</span> <span class="n">rexists</span><span class="p">(</span><span class="n">p</span><span class="p">,</span> <span class="n">root</span><span class="o">=</span><span class="n">inroot</span><span class="p">),</span>
<span class="n">glob</span><span class="o">=</span><span class="k">lambda</span> <span class="n">g</span><span class="p">:</span> <span class="nb">list</span><span class="p">(</span><span class="n">rglob</span><span class="p">(</span><span class="n">g</span><span class="p">,</span> <span class="n">root</span><span class="o">=</span><span class="n">inroot</span><span class="p">)))</span>
<span class="bp">self</span><span class="o">.</span><span class="n">defaults</span> <span class="o">=</span> <span class="n">defaults</span>
<span class="bp">self</span><span class="o">.</span><span class="n">results</span> <span class="o">=</span> <span class="n">DataHolder</span><span class="p">(</span><span class="n">treeinfo</span><span class="o">=</span><span class="nb">dict</span><span class="p">())</span> <span class="c"># just treeinfo for now</span>
<span class="c"># TODO: set up custom logger with a filter to add line info</span>
<span class="k">def</span> <span class="nf">_out</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">path</span><span class="p">):</span>
<span class="k">return</span> <span class="n">joinpaths</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">outroot</span><span class="p">,</span> <span class="n">path</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">_in</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">path</span><span class="p">):</span>
<span class="k">return</span> <span class="n">joinpaths</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">inroot</span><span class="p">,</span> <span class="n">path</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">_filelist</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">pkgs</span><span class="p">):</span>
<span class="n">pkglist</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">yum</span><span class="o">.</span><span class="n">doPackageLists</span><span class="p">(</span><span class="n">pkgnarrow</span><span class="o">=</span><span class="s">&quot;installed&quot;</span><span class="p">,</span> <span class="n">patterns</span><span class="o">=</span><span class="n">pkgs</span><span class="p">)</span>
<span class="k">return</span> <span class="nb">set</span><span class="p">([</span><span class="n">f</span> <span class="k">for</span> <span class="n">pkg</span> <span class="ow">in</span> <span class="n">pkglist</span><span class="o">.</span><span class="n">installed</span> <span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">pkg</span><span class="o">.</span><span class="n">filelist</span><span class="o">+</span><span class="n">pkg</span><span class="o">.</span><span class="n">ghostlist</span><span class="p">])</span>
<span class="k">def</span> <span class="nf">_getsize</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">files</span><span class="p">):</span>
<span class="k">return</span> <span class="nb">sum</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">getsize</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_out</span><span class="p">(</span><span class="n">f</span><span class="p">))</span> <span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">files</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">isfile</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_out</span><span class="p">(</span><span class="n">f</span><span class="p">)))</span>
<div class="viewcode-block" id="LoraxTemplateRunner.run"><a class="viewcode-back" href="../../pylorax.html#pylorax.ltmpl.LoraxTemplateRunner.run">[docs]</a> <span class="k">def</span> <span class="nf">run</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">templatefile</span><span class="p">,</span> <span class="o">**</span><span class="n">variables</span><span class="p">):</span>
<span class="k">for</span> <span class="n">k</span><span class="p">,</span><span class="n">v</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">defaults</span><span class="o">.</span><span class="n">items</span><span class="p">()</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">builtins</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
<span class="n">variables</span><span class="o">.</span><span class="n">setdefault</span><span class="p">(</span><span class="n">k</span><span class="p">,</span><span class="n">v</span><span class="p">)</span>
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">&quot;executing </span><span class="si">%s</span><span class="s"> with variables=</span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">templatefile</span><span class="p">,</span> <span class="n">variables</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">templatefile</span> <span class="o">=</span> <span class="n">templatefile</span>
<span class="n">t</span> <span class="o">=</span> <span class="n">LoraxTemplate</span><span class="p">(</span><span class="n">directories</span><span class="o">=</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">templatedir</span><span class="p">])</span>
<span class="n">commands</span> <span class="o">=</span> <span class="n">t</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="n">templatefile</span><span class="p">,</span> <span class="n">variables</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_run</span><span class="p">(</span><span class="n">commands</span><span class="p">)</span>
</div>
<span class="k">def</span> <span class="nf">_run</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">parsed_template</span><span class="p">):</span>
<span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;running </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">templatefile</span><span class="p">)</span>
<span class="k">for</span> <span class="p">(</span><span class="n">num</span><span class="p">,</span> <span class="n">line</span><span class="p">)</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">parsed_template</span><span class="p">,</span><span class="mi">1</span><span class="p">):</span>
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">&quot;template line </span><span class="si">%i</span><span class="s">: </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">num</span><span class="p">,</span> <span class="s">&quot; &quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">line</span><span class="p">))</span>
<span class="n">skiperror</span> <span class="o">=</span> <span class="bp">False</span>
<span class="p">(</span><span class="n">cmd</span><span class="p">,</span> <span class="n">args</span><span class="p">)</span> <span class="o">=</span> <span class="p">(</span><span class="n">line</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">line</span><span class="p">[</span><span class="mi">1</span><span class="p">:])</span>
<span class="c"># Following Makefile convention, if the command is prefixed with</span>
<span class="c"># a dash (&#39;-&#39;), we&#39;ll ignore any errors on that line.</span>
<span class="k">if</span> <span class="n">cmd</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s">&#39;-&#39;</span><span class="p">):</span>
<span class="n">cmd</span> <span class="o">=</span> <span class="n">cmd</span><span class="p">[</span><span class="mi">1</span><span class="p">:]</span>
<span class="n">skiperror</span> <span class="o">=</span> <span class="bp">True</span>
<span class="k">try</span><span class="p">:</span>
<span class="c"># grab the method named in cmd and pass it the given arguments</span>
<span class="n">f</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">cmd</span><span class="p">,</span> <span class="bp">None</span><span class="p">)</span>
<span class="k">if</span> <span class="n">cmd</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="s">&#39;_&#39;</span> <span class="ow">or</span> <span class="n">cmd</span> <span class="o">==</span> <span class="s">&#39;run&#39;</span> <span class="ow">or</span> <span class="ow">not</span> <span class="nb">callable</span><span class="p">(</span><span class="n">f</span><span class="p">):</span>
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">,</span> <span class="s">&quot;unknown command </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">cmd</span>
<span class="n">f</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
<span class="k">if</span> <span class="n">skiperror</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">&quot;ignoring error&quot;</span><span class="p">)</span>
<span class="k">continue</span>
<span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s">&quot;template command error in </span><span class="si">%s</span><span class="s">:&quot;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">templatefile</span><span class="p">)</span>
<span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s">&quot; </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="s">&quot; &quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">line</span><span class="p">))</span>
<span class="c"># format the exception traceback</span>
<span class="n">exclines</span> <span class="o">=</span> <span class="n">traceback</span><span class="o">.</span><span class="n">format_exception</span><span class="p">(</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="c"># skip the bit about &quot;ltmpl.py, in _run()&quot; - we know that</span>
<span class="n">exclines</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="c"># log the &quot;ErrorType: this is what happened&quot; line</span>
<span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s">&quot; &quot;</span> <span class="o">+</span> <span class="n">exclines</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">strip</span><span class="p">())</span>
<span class="c"># and log the entire traceback to the debug log</span>
<span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="s">&#39;&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">exclines</span><span class="p">)</span><span class="o">.</span><span class="n">splitlines</span><span class="p">():</span>
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">&quot; &quot;</span> <span class="o">+</span> <span class="n">line</span><span class="p">)</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">fatalerrors</span><span class="p">:</span>
<span class="k">raise</span>
<div class="viewcode-block" id="LoraxTemplateRunner.install"><a class="viewcode-back" href="../../pylorax.html#pylorax.ltmpl.LoraxTemplateRunner.install">[docs]</a> <span class="k">def</span> <span class="nf">install</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">srcglob</span><span class="p">,</span> <span class="n">dest</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> install SRC DEST</span>
<span class="sd"> Copy the given file (or files, if a glob is used) from the input</span>
<span class="sd"> tree to the given destination in the output tree.</span>
<span class="sd"> The path to DEST must exist in the output tree.</span>
<span class="sd"> If DEST is a directory, SRC will be copied into that directory.</span>
<span class="sd"> If DEST doesn&#39;t exist, SRC will be copied to a file with that name,</span>
<span class="sd"> assuming the rest of the path exists.</span>
<span class="sd"> This is pretty much like how the &#39;cp&#39; command works.</span>
<span class="sd"> Examples:</span>
<span class="sd"> install usr/share/myconfig/grub.conf /boot</span>
<span class="sd"> install /usr/share/myconfig/grub.conf.in /boot/grub.conf</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">for</span> <span class="n">src</span> <span class="ow">in</span> <span class="n">rglob</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_in</span><span class="p">(</span><span class="n">srcglob</span><span class="p">),</span> <span class="n">fatal</span><span class="o">=</span><span class="bp">True</span><span class="p">):</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">cpfile</span><span class="p">(</span><span class="n">src</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_out</span><span class="p">(</span><span class="n">dest</span><span class="p">))</span>
<span class="k">except</span> <span class="n">shutil</span><span class="o">.</span><span class="n">Error</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="n">e</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="LoraxTemplateRunner.installimg"><a class="viewcode-back" href="../../pylorax.html#pylorax.ltmpl.LoraxTemplateRunner.installimg">[docs]</a> <span class="k">def</span> <span class="nf">installimg</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">srcdir</span><span class="p">,</span> <span class="n">destfile</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> installimg SRCDIR DESTFILE</span>
<span class="sd"> Create a compressed cpio archive of the contents of SRCDIR and place</span>
<span class="sd"> it in DESTFILE.</span>
<span class="sd"> If SRCDIR doesn&#39;t exist or is empty nothing is created.</span>
<span class="sd"> Examples:</span>
<span class="sd"> installimg ${LORAXDIR}/product/ images/product.img</span>
<span class="sd"> installimg ${LORAXDIR}/updates/ images/updates.img</span>
<span class="sd"> &#39;&#39;&#39;</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">isdir</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_in</span><span class="p">(</span><span class="n">srcdir</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">listdir</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_in</span><span class="p">(</span><span class="n">srcdir</span><span class="p">)):</span>
<span class="k">return</span>
<span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;Creating image file </span><span class="si">%s</span><span class="s"> from contents of </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_out</span><span class="p">(</span><span class="n">destfile</span><span class="p">),</span> <span class="bp">self</span><span class="o">.</span><span class="n">_in</span><span class="p">(</span><span class="n">srcdir</span><span class="p">))</span>
<span class="n">mkcpio</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_in</span><span class="p">(</span><span class="n">srcdir</span><span class="p">),</span> <span class="bp">self</span><span class="o">.</span><span class="n">_out</span><span class="p">(</span><span class="n">destfile</span><span class="p">))</span>
</div>
<div class="viewcode-block" id="LoraxTemplateRunner.mkdir"><a class="viewcode-back" href="../../pylorax.html#pylorax.ltmpl.LoraxTemplateRunner.mkdir">[docs]</a> <span class="k">def</span> <span class="nf">mkdir</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">dirs</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> mkdir DIR [DIR ...]</span>
<span class="sd"> Create the named DIR(s). Will create leading directories as needed.</span>
<span class="sd"> Example:</span>
<span class="sd"> mkdir /images</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">for</span> <span class="n">d</span> <span class="ow">in</span> <span class="n">dirs</span><span class="p">:</span>
<span class="n">d</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_out</span><span class="p">(</span><span class="n">d</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">isdir</span><span class="p">(</span><span class="n">d</span><span class="p">):</span>
<span class="n">os</span><span class="o">.</span><span class="n">makedirs</span><span class="p">(</span><span class="n">d</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="LoraxTemplateRunner.replace"><a class="viewcode-back" href="../../pylorax.html#pylorax.ltmpl.LoraxTemplateRunner.replace">[docs]</a> <span class="k">def</span> <span class="nf">replace</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">pat</span><span class="p">,</span> <span class="n">repl</span><span class="p">,</span> <span class="o">*</span><span class="n">fileglobs</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> replace PATTERN REPLACEMENT FILEGLOB [FILEGLOB ...]</span>
<span class="sd"> Find-and-replace the given PATTERN (Python-style regex) with the given</span>
<span class="sd"> REPLACEMENT string for each of the files listed.</span>
<span class="sd"> Example:</span>
<span class="sd"> replace @VERSION@ ${product.version} /boot/grub.conf /boot/isolinux.cfg</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="n">match</span> <span class="o">=</span> <span class="bp">False</span>
<span class="k">for</span> <span class="n">g</span> <span class="ow">in</span> <span class="n">fileglobs</span><span class="p">:</span>
<span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">rglob</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_out</span><span class="p">(</span><span class="n">g</span><span class="p">)):</span>
<span class="n">match</span> <span class="o">=</span> <span class="bp">True</span>
<span class="n">replace</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">pat</span><span class="p">,</span> <span class="n">repl</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">match</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">IOError</span><span class="p">,</span> <span class="s">&quot;no files matched </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">fileglobs</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="LoraxTemplateRunner.append"><a class="viewcode-back" href="../../pylorax.html#pylorax.ltmpl.LoraxTemplateRunner.append">[docs]</a> <span class="k">def</span> <span class="nf">append</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">filename</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> append FILE STRING</span>
<span class="sd"> Append STRING (followed by a newline character) to FILE.</span>
<span class="sd"> Python character escape sequences (&#39;\\n&#39;, &#39;\\t&#39;, etc.) will be</span>
<span class="sd"> converted to the appropriate characters.</span>
<span class="sd"> Examples:</span>
<span class="sd"> append /etc/depmod.d/dd.conf &quot;search updates built-in&quot;</span>
<span class="sd"> append /etc/resolv.conf &quot;&quot;</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_out</span><span class="p">(</span><span class="n">filename</span><span class="p">),</span> <span class="s">&quot;a&quot;</span><span class="p">)</span> <span class="k">as</span> <span class="n">fobj</span><span class="p">:</span>
<span class="n">fobj</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">data</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s">&#39;string_escape&#39;</span><span class="p">)</span><span class="o">+</span><span class="s">&quot;</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="LoraxTemplateRunner.treeinfo"><a class="viewcode-back" href="../../pylorax.html#pylorax.ltmpl.LoraxTemplateRunner.treeinfo">[docs]</a> <span class="k">def</span> <span class="nf">treeinfo</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">section</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="o">*</span><span class="n">valuetoks</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> treeinfo SECTION KEY ARG [ARG ...]</span>
<span class="sd"> Add an item to the treeinfo data store.</span>
<span class="sd"> The given SECTION will have a new item added where</span>
<span class="sd"> KEY = ARG ARG ...</span>
<span class="sd"> Example:</span>
<span class="sd"> treeinfo images-${kernel.arch} boot.iso images/boot.iso</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">if</span> <span class="n">section</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">results</span><span class="o">.</span><span class="n">treeinfo</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">results</span><span class="o">.</span><span class="n">treeinfo</span><span class="p">[</span><span class="n">section</span><span class="p">]</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">results</span><span class="o">.</span><span class="n">treeinfo</span><span class="p">[</span><span class="n">section</span><span class="p">][</span><span class="n">key</span><span class="p">]</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">valuetoks</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="LoraxTemplateRunner.installkernel"><a class="viewcode-back" href="../../pylorax.html#pylorax.ltmpl.LoraxTemplateRunner.installkernel">[docs]</a> <span class="k">def</span> <span class="nf">installkernel</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">section</span><span class="p">,</span> <span class="n">src</span><span class="p">,</span> <span class="n">dest</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> installkernel SECTION SRC DEST</span>
<span class="sd"> Install the kernel from SRC in the input tree to DEST in the output</span>
<span class="sd"> tree, and then add an item to the treeinfo data store, in the named</span>
<span class="sd"> SECTION, where &quot;kernel&quot; = DEST.</span>
<span class="sd"> Equivalent to:</span>
<span class="sd"> install SRC DEST</span>
<span class="sd"> treeinfo SECTION kernel DEST</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">install</span><span class="p">(</span><span class="n">src</span><span class="p">,</span> <span class="n">dest</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">treeinfo</span><span class="p">(</span><span class="n">section</span><span class="p">,</span> <span class="s">&quot;kernel&quot;</span><span class="p">,</span> <span class="n">dest</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="LoraxTemplateRunner.installinitrd"><a class="viewcode-back" href="../../pylorax.html#pylorax.ltmpl.LoraxTemplateRunner.installinitrd">[docs]</a> <span class="k">def</span> <span class="nf">installinitrd</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">section</span><span class="p">,</span> <span class="n">src</span><span class="p">,</span> <span class="n">dest</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> installinitrd SECTION SRC DEST</span>
<span class="sd"> Same as installkernel, but for &quot;initrd&quot;.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">install</span><span class="p">(</span><span class="n">src</span><span class="p">,</span> <span class="n">dest</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">chmod</span><span class="p">(</span><span class="n">dest</span><span class="p">,</span> <span class="s">&#39;644&#39;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">treeinfo</span><span class="p">(</span><span class="n">section</span><span class="p">,</span> <span class="s">&quot;initrd&quot;</span><span class="p">,</span> <span class="n">dest</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="LoraxTemplateRunner.installupgradeinitrd"><a class="viewcode-back" href="../../pylorax.html#pylorax.ltmpl.LoraxTemplateRunner.installupgradeinitrd">[docs]</a> <span class="k">def</span> <span class="nf">installupgradeinitrd</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">section</span><span class="p">,</span> <span class="n">src</span><span class="p">,</span> <span class="n">dest</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> installupgradeinitrd SECTION SRC DEST</span>
<span class="sd"> Same as installkernel, but for &quot;upgrade&quot;.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">install</span><span class="p">(</span><span class="n">src</span><span class="p">,</span> <span class="n">dest</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">chmod</span><span class="p">(</span><span class="n">dest</span><span class="p">,</span> <span class="s">&#39;644&#39;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">treeinfo</span><span class="p">(</span><span class="n">section</span><span class="p">,</span> <span class="s">&quot;upgrade&quot;</span><span class="p">,</span> <span class="n">dest</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="LoraxTemplateRunner.hardlink"><a class="viewcode-back" href="../../pylorax.html#pylorax.ltmpl.LoraxTemplateRunner.hardlink">[docs]</a> <span class="k">def</span> <span class="nf">hardlink</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">src</span><span class="p">,</span> <span class="n">dest</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> hardlink SRC DEST</span>
<span class="sd"> Create a hardlink at DEST which is linked to SRC.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">if</span> <span class="n">isdir</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_out</span><span class="p">(</span><span class="n">dest</span><span class="p">)):</span>
<span class="n">dest</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">dest</span><span class="p">,</span> <span class="n">basename</span><span class="p">(</span><span class="n">src</span><span class="p">))</span>
<span class="n">os</span><span class="o">.</span><span class="n">link</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_out</span><span class="p">(</span><span class="n">src</span><span class="p">),</span> <span class="bp">self</span><span class="o">.</span><span class="n">_out</span><span class="p">(</span><span class="n">dest</span><span class="p">))</span>
</div>
<div class="viewcode-block" id="LoraxTemplateRunner.symlink"><a class="viewcode-back" href="../../pylorax.html#pylorax.ltmpl.LoraxTemplateRunner.symlink">[docs]</a> <span class="k">def</span> <span class="nf">symlink</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">target</span><span class="p">,</span> <span class="n">dest</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> symlink SRC DEST</span>
<span class="sd"> Create a symlink at DEST which points to SRC.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">if</span> <span class="n">rexists</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_out</span><span class="p">(</span><span class="n">dest</span><span class="p">)):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">dest</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">symlink</span><span class="p">(</span><span class="n">target</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_out</span><span class="p">(</span><span class="n">dest</span><span class="p">))</span>
</div>
<div class="viewcode-block" id="LoraxTemplateRunner.copy"><a class="viewcode-back" href="../../pylorax.html#pylorax.ltmpl.LoraxTemplateRunner.copy">[docs]</a> <span class="k">def</span> <span class="nf">copy</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">src</span><span class="p">,</span> <span class="n">dest</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> copy SRC DEST</span>
<span class="sd"> Copy SRC to DEST.</span>
<span class="sd"> If DEST is a directory, SRC will be copied inside it.</span>
<span class="sd"> If DEST doesn&#39;t exist, SRC will be copied to a file with</span>
<span class="sd"> that name, if the path leading to it exists.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">cpfile</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_out</span><span class="p">(</span><span class="n">src</span><span class="p">),</span> <span class="bp">self</span><span class="o">.</span><span class="n">_out</span><span class="p">(</span><span class="n">dest</span><span class="p">))</span>
<span class="k">except</span> <span class="n">shutil</span><span class="o">.</span><span class="n">Error</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="n">e</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="LoraxTemplateRunner.move"><a class="viewcode-back" href="../../pylorax.html#pylorax.ltmpl.LoraxTemplateRunner.move">[docs]</a> <span class="k">def</span> <span class="nf">move</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">src</span><span class="p">,</span> <span class="n">dest</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> move SRC DEST</span>
<span class="sd"> Move SRC to DEST.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="n">mvfile</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_out</span><span class="p">(</span><span class="n">src</span><span class="p">),</span> <span class="bp">self</span><span class="o">.</span><span class="n">_out</span><span class="p">(</span><span class="n">dest</span><span class="p">))</span>
</div>
<div class="viewcode-block" id="LoraxTemplateRunner.remove"><a class="viewcode-back" href="../../pylorax.html#pylorax.ltmpl.LoraxTemplateRunner.remove">[docs]</a> <span class="k">def</span> <span class="nf">remove</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">fileglobs</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> remove FILEGLOB [FILEGLOB ...]</span>
<span class="sd"> Remove all the named files or directories.</span>
<span class="sd"> Will *not* raise exceptions if the file(s) are not found.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">for</span> <span class="n">g</span> <span class="ow">in</span> <span class="n">fileglobs</span><span class="p">:</span>
<span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">rglob</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_out</span><span class="p">(</span><span class="n">g</span><span class="p">)):</span>
<span class="n">remove</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">&quot;removed </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">f</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="LoraxTemplateRunner.chmod"><a class="viewcode-back" href="../../pylorax.html#pylorax.ltmpl.LoraxTemplateRunner.chmod">[docs]</a> <span class="k">def</span> <span class="nf">chmod</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">fileglob</span><span class="p">,</span> <span class="n">mode</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> chmod FILEGLOB OCTALMODE</span>
<span class="sd"> Change the mode of all the files matching FILEGLOB to OCTALMODE.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">rglob</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_out</span><span class="p">(</span><span class="n">fileglob</span><span class="p">),</span> <span class="n">fatal</span><span class="o">=</span><span class="bp">True</span><span class="p">):</span>
<span class="n">os</span><span class="o">.</span><span class="n">chmod</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">mode</span><span class="p">,</span><span class="mi">8</span><span class="p">))</span>
<span class="c"># TODO: do we need a new command for gsettings?</span></div>
<div class="viewcode-block" id="LoraxTemplateRunner.gconfset"><a class="viewcode-back" href="../../pylorax.html#pylorax.ltmpl.LoraxTemplateRunner.gconfset">[docs]</a> <span class="k">def</span> <span class="nf">gconfset</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">keytype</span><span class="p">,</span> <span class="n">value</span><span class="p">,</span> <span class="n">outfile</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> gconfset PATH KEYTYPE VALUE [OUTFILE]</span>
<span class="sd"> Set the given gconf PATH, with type KEYTYPE, to the given value.</span>
<span class="sd"> OUTFILE defaults to /etc/gconf/gconf.xml.defaults if not given.</span>
<span class="sd"> Example:</span>
<span class="sd"> gconfset /apps/metacity/general/num_workspaces int 1</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">if</span> <span class="n">outfile</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span>
<span class="n">outfile</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_out</span><span class="p">(</span><span class="s">&quot;etc/gconf/gconf.xml.defaults&quot;</span><span class="p">)</span>
<span class="n">cmd</span> <span class="o">=</span> <span class="p">[</span><span class="s">&quot;gconftool-2&quot;</span><span class="p">,</span> <span class="s">&quot;--direct&quot;</span><span class="p">,</span>
<span class="s">&quot;--config-source=xml:readwrite:</span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">outfile</span><span class="p">,</span>
<span class="s">&quot;--set&quot;</span><span class="p">,</span> <span class="s">&quot;--type&quot;</span><span class="p">,</span> <span class="n">keytype</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">value</span><span class="p">]</span>
<span class="n">runcmd</span><span class="p">(</span><span class="n">cmd</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="LoraxTemplateRunner.log"><a class="viewcode-back" href="../../pylorax.html#pylorax.ltmpl.LoraxTemplateRunner.log">[docs]</a> <span class="k">def</span> <span class="nf">log</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">msg</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> log MESSAGE</span>
<span class="sd"> Emit the given log message. Be sure to put it in quotes!</span>
<span class="sd"> Example:</span>
<span class="sd"> log &quot;Reticulating splines, please wait...&quot;</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
<span class="c"># TODO: add ssh-keygen, mkisofs(?), find, and other useful commands</span></div>
<div class="viewcode-block" id="LoraxTemplateRunner.runcmd"><a class="viewcode-back" href="../../pylorax.html#pylorax.ltmpl.LoraxTemplateRunner.runcmd">[docs]</a> <span class="k">def</span> <span class="nf">runcmd</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">cmdlist</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> runcmd CMD [--chdir=DIR] [ARG ...]</span>
<span class="sd"> Run the given command with the given arguments.</span>
<span class="sd"> If &quot;--chdir=DIR&quot; is given, change to the named directory</span>
<span class="sd"> before executing the command.</span>
<span class="sd"> NOTE: All paths given MUST be COMPLETE, ABSOLUTE PATHS to the file</span>
<span class="sd"> or files mentioned. ${root}/${inroot}/${outroot} are good for</span>
<span class="sd"> constructing these paths.</span>
<span class="sd"> FURTHER NOTE: Please use this command only as a last resort!</span>
<span class="sd"> Whenever possible, you should use the existing template commands.</span>
<span class="sd"> If the existing commands don&#39;t do what you need, fix them!</span>
<span class="sd"> Examples:</span>
<span class="sd"> (this should be replaced with a &quot;find&quot; function)</span>
<span class="sd"> runcmd find ${root} -name &quot;*.pyo&quot; -type f -delete</span>
<span class="sd"> %for f in find(root, name=&quot;*.pyo&quot;):</span>
<span class="sd"> remove ${f}</span>
<span class="sd"> %endfor</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="n">cwd</span> <span class="o">=</span> <span class="bp">None</span>
<span class="n">cmd</span> <span class="o">=</span> <span class="n">cmdlist</span>
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">&#39;running command: </span><span class="si">%s</span><span class="s">&#39;</span><span class="p">,</span> <span class="n">cmd</span><span class="p">)</span>
<span class="k">if</span> <span class="n">cmd</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s">&quot;--chdir=&quot;</span><span class="p">):</span>
<span class="n">cwd</span> <span class="o">=</span> <span class="n">cmd</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">&#39;=&#39;</span><span class="p">,</span><span class="mi">1</span><span class="p">)[</span><span class="mi">1</span><span class="p">]</span>
<span class="n">cmd</span> <span class="o">=</span> <span class="n">cmd</span><span class="p">[</span><span class="mi">1</span><span class="p">:]</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">_output</span> <span class="o">=</span> <span class="n">runcmd_output</span><span class="p">(</span><span class="n">cmd</span><span class="p">,</span> <span class="n">cwd</span><span class="o">=</span><span class="n">cwd</span><span class="p">)</span>
<span class="k">if</span> <span class="n">_output</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">&#39;command output:</span><span class="se">\n</span><span class="si">%s</span><span class="s">&#39;</span><span class="p">,</span> <span class="n">_output</span><span class="p">)</span>
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">&quot;command finished successfully&quot;</span><span class="p">)</span>
<span class="k">except</span> <span class="n">CalledProcessError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="k">if</span> <span class="n">e</span><span class="o">.</span><span class="n">output</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">&#39;command output:</span><span class="se">\n</span><span class="si">%s</span><span class="s">&#39;</span><span class="p">,</span> <span class="n">e</span><span class="o">.</span><span class="n">output</span><span class="p">)</span>
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">&#39;command returned failure (</span><span class="si">%d</span><span class="s">)&#39;</span><span class="p">,</span> <span class="n">e</span><span class="o">.</span><span class="n">returncode</span><span class="p">)</span>
<span class="k">raise</span>
</div>
<div class="viewcode-block" id="LoraxTemplateRunner.installpkg"><a class="viewcode-back" href="../../pylorax.html#pylorax.ltmpl.LoraxTemplateRunner.installpkg">[docs]</a> <span class="k">def</span> <span class="nf">installpkg</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">pkgs</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> installpkg [--required] PKGGLOB [PKGGLOB ...]</span>
<span class="sd"> Request installation of all packages matching the given globs.</span>
<span class="sd"> Note that this is just a *request* - nothing is *actually* installed</span>
<span class="sd"> until the &#39;run_pkg_transaction&#39; command is given.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="n">required</span> <span class="o">=</span> <span class="bp">False</span>
<span class="k">if</span> <span class="n">pkgs</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="s">&#39;--required&#39;</span><span class="p">:</span>
<span class="n">pkgs</span> <span class="o">=</span> <span class="n">pkgs</span><span class="p">[</span><span class="mi">1</span><span class="p">:]</span>
<span class="n">required</span> <span class="o">=</span> <span class="bp">True</span>
<span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">pkgs</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">yum</span><span class="o">.</span><span class="n">install</span><span class="p">(</span><span class="n">pattern</span><span class="o">=</span><span class="n">p</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="c"># FIXME: save exception and re-raise after the loop finishes</span>
<span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s">&quot;installpkg </span><span class="si">%s</span><span class="s"> failed: </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span><span class="n">p</span><span class="p">,</span><span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">))</span>
<span class="k">if</span> <span class="n">required</span><span class="p">:</span>
<span class="k">raise</span>
</div>
<div class="viewcode-block" id="LoraxTemplateRunner.removepkg"><a class="viewcode-back" href="../../pylorax.html#pylorax.ltmpl.LoraxTemplateRunner.removepkg">[docs]</a> <span class="k">def</span> <span class="nf">removepkg</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">pkgs</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> removepkg PKGGLOB [PKGGLOB...]</span>
<span class="sd"> Delete the named package(s).</span>
<span class="sd"> IMPLEMENTATION NOTES:</span>
<span class="sd"> RPM scriptlets (%preun/%postun) are *not* run.</span>
<span class="sd"> Files are deleted, but directories are left behind.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">pkgs</span><span class="p">:</span>
<span class="n">filepaths</span> <span class="o">=</span> <span class="p">[</span><span class="n">f</span><span class="o">.</span><span class="n">lstrip</span><span class="p">(</span><span class="s">&#39;/&#39;</span><span class="p">)</span> <span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_filelist</span><span class="p">(</span><span class="n">p</span><span class="p">)]</span>
<span class="c"># TODO: also remove directories that aren&#39;t owned by anything else</span>
<span class="k">if</span> <span class="n">filepaths</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">&quot;removepkg </span><span class="si">%s</span><span class="s">: </span><span class="si">%i</span><span class="s">kb&quot;</span><span class="p">,</span> <span class="n">p</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_getsize</span><span class="p">(</span><span class="o">*</span><span class="n">filepaths</span><span class="p">)</span><span class="o">/</span><span class="mi">1024</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="o">*</span><span class="n">filepaths</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">&quot;removepkg </span><span class="si">%s</span><span class="s">: no files to remove!&quot;</span><span class="p">,</span> <span class="n">p</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="LoraxTemplateRunner.run_pkg_transaction"><a class="viewcode-back" href="../../pylorax.html#pylorax.ltmpl.LoraxTemplateRunner.run_pkg_transaction">[docs]</a> <span class="k">def</span> <span class="nf">run_pkg_transaction</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> run_pkg_transaction</span>
<span class="sd"> Actually install all the packages requested by previous &#39;installpkg&#39;</span>
<span class="sd"> commands.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">yum</span><span class="o">.</span><span class="n">buildTransaction</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">yum</span><span class="o">.</span><span class="n">repos</span><span class="o">.</span><span class="n">setProgressBar</span><span class="p">(</span><span class="n">yumhelper</span><span class="o">.</span><span class="n">LoraxDownloadCallback</span><span class="p">())</span>
<span class="bp">self</span><span class="o">.</span><span class="n">yum</span><span class="o">.</span><span class="n">processTransaction</span><span class="p">(</span><span class="n">callback</span><span class="o">=</span><span class="n">yumhelper</span><span class="o">.</span><span class="n">LoraxTransactionCallback</span><span class="p">(),</span>
<span class="n">rpmDisplay</span><span class="o">=</span><span class="n">yumhelper</span><span class="o">.</span><span class="n">LoraxRpmCallback</span><span class="p">())</span>
<span class="c"># verify if all packages that were supposed to be installed,</span>
<span class="c"># are really installed</span>
<span class="n">errs</span> <span class="o">=</span> <span class="p">[</span><span class="n">t</span><span class="o">.</span><span class="n">po</span> <span class="k">for</span> <span class="n">t</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">yum</span><span class="o">.</span><span class="n">tsInfo</span> <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">yum</span><span class="o">.</span><span class="n">rpmdb</span><span class="o">.</span><span class="n">contains</span><span class="p">(</span><span class="n">po</span><span class="o">=</span><span class="n">t</span><span class="o">.</span><span class="n">po</span><span class="p">)]</span>
<span class="k">for</span> <span class="n">po</span> <span class="ow">in</span> <span class="n">errs</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s">&quot;package &#39;</span><span class="si">%s</span><span class="s">&#39; was not installed&quot;</span><span class="p">,</span> <span class="n">po</span><span class="p">)</span>
<span class="c"># Write the manifest of installed files to /root/lorax-packages.log</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_out</span><span class="p">(</span><span class="s">&quot;root/lorax-packages.log&quot;</span><span class="p">),</span> <span class="s">&quot;w&quot;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
<span class="k">for</span> <span class="n">t</span> <span class="ow">in</span> <span class="nb">sorted</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">yum</span><span class="o">.</span><span class="n">tsInfo</span><span class="p">):</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">&quot;</span><span class="si">%s</span><span class="se">\n</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">t</span><span class="o">.</span><span class="n">po</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">yum</span><span class="o">.</span><span class="n">closeRpmDB</span><span class="p">()</span>
</div>
<div class="viewcode-block" id="LoraxTemplateRunner.removefrom"><a class="viewcode-back" href="../../pylorax.html#pylorax.ltmpl.LoraxTemplateRunner.removefrom">[docs]</a> <span class="k">def</span> <span class="nf">removefrom</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">pkg</span><span class="p">,</span> <span class="o">*</span><span class="n">globs</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> removefrom PKGGLOB [--allbut] FILEGLOB [FILEGLOB...]</span>
<span class="sd"> Remove all files matching the given file globs from the package</span>
<span class="sd"> (or packages) named.</span>
<span class="sd"> If &#39;--allbut&#39; is used, all the files from the given package(s) will</span>
<span class="sd"> be removed *except* the ones which match the file globs.</span>
<span class="sd"> Examples:</span>
<span class="sd"> removefrom usbutils /usr/bin/*</span>
<span class="sd"> removefrom xfsprogs --allbut /sbin/*</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="n">cmd</span> <span class="o">=</span> <span class="s">&quot;</span><span class="si">%s</span><span class="s"> </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">pkg</span><span class="p">,</span> <span class="s">&quot; &quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">globs</span><span class="p">))</span> <span class="c"># save for later logging</span>
<span class="n">keepmatches</span> <span class="o">=</span> <span class="bp">False</span>
<span class="k">if</span> <span class="n">globs</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="s">&#39;--allbut&#39;</span><span class="p">:</span>
<span class="n">keepmatches</span> <span class="o">=</span> <span class="bp">True</span>
<span class="n">globs</span> <span class="o">=</span> <span class="n">globs</span><span class="p">[</span><span class="mi">1</span><span class="p">:]</span>
<span class="c"># get pkg filelist and find files that match the globs</span>
<span class="n">filelist</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_filelist</span><span class="p">(</span><span class="n">pkg</span><span class="p">)</span>
<span class="n">matches</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
<span class="k">for</span> <span class="n">g</span> <span class="ow">in</span> <span class="n">globs</span><span class="p">:</span>
<span class="n">globs_re</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="n">fnmatch</span><span class="o">.</span><span class="n">translate</span><span class="p">(</span><span class="n">g</span><span class="p">))</span>
<span class="n">m</span> <span class="o">=</span> <span class="nb">filter</span><span class="p">(</span><span class="n">globs_re</span><span class="o">.</span><span class="n">match</span><span class="p">,</span> <span class="n">filelist</span><span class="p">)</span>
<span class="k">if</span> <span class="n">m</span><span class="p">:</span>
<span class="n">matches</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">&quot;removefrom </span><span class="si">%s</span><span class="s"> </span><span class="si">%s</span><span class="s">: no files matched!&quot;</span><span class="p">,</span> <span class="n">pkg</span><span class="p">,</span> <span class="n">g</span><span class="p">)</span>
<span class="c"># are we removing the matches, or keeping only the matches?</span>
<span class="k">if</span> <span class="n">keepmatches</span><span class="p">:</span>
<span class="n">files_to_remove</span> <span class="o">=</span> <span class="n">filelist</span><span class="o">.</span><span class="n">difference</span><span class="p">(</span><span class="n">matches</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">files_to_remove</span> <span class="o">=</span> <span class="n">matches</span>
<span class="c"># remove the files</span>
<span class="k">if</span> <span class="n">files_to_remove</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">&quot;</span><span class="si">%s</span><span class="s">: removed </span><span class="si">%i</span><span class="s">/</span><span class="si">%i</span><span class="s"> files, </span><span class="si">%i</span><span class="s">kb/</span><span class="si">%i</span><span class="s">kb&quot;</span><span class="p">,</span> <span class="n">cmd</span><span class="p">,</span>
<span class="nb">len</span><span class="p">(</span><span class="n">files_to_remove</span><span class="p">),</span> <span class="nb">len</span><span class="p">(</span><span class="n">filelist</span><span class="p">),</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_getsize</span><span class="p">(</span><span class="o">*</span><span class="n">files_to_remove</span><span class="p">)</span><span class="o">/</span><span class="mi">1024</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_getsize</span><span class="p">(</span><span class="o">*</span><span class="n">filelist</span><span class="p">)</span><span class="o">/</span><span class="mi">1024</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="o">*</span><span class="n">files_to_remove</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">&quot;removefrom </span><span class="si">%s</span><span class="s">: no files to remove!&quot;</span><span class="p">,</span> <span class="n">cmd</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="LoraxTemplateRunner.removekmod"><a class="viewcode-back" href="../../pylorax.html#pylorax.ltmpl.LoraxTemplateRunner.removekmod">[docs]</a> <span class="k">def</span> <span class="nf">removekmod</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">globs</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> removekmod GLOB [GLOB...] [--allbut] KEEPGLOB [KEEPGLOB...]</span>
<span class="sd"> Remove all files and directories matching the given file globs from the kernel</span>
<span class="sd"> modules directory.</span>
<span class="sd"> If &#39;--allbut&#39; is used, all the files from the modules will be removed *except*</span>
<span class="sd"> the ones which match the file globs. There must be at least one initial GLOB</span>
<span class="sd"> to search and one KEEPGLOB to keep. The KEEPGLOB is expanded to be *KEEPGLOB*</span>
<span class="sd"> so that it will match anywhere in the path.</span>
<span class="sd"> This only removes files from under /lib/modules/*/kernel/</span>
<span class="sd"> Examples:</span>
<span class="sd"> removekmod sound drivers/media drivers/hwmon drivers/video</span>
<span class="sd"> removekmod drivers/char --allbut virtio_console hw_random</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="n">cmd</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">globs</span><span class="p">)</span>
<span class="k">if</span> <span class="s">&quot;--allbut&quot;</span> <span class="ow">in</span> <span class="n">globs</span><span class="p">:</span>
<span class="n">idx</span> <span class="o">=</span> <span class="n">globs</span><span class="o">.</span><span class="n">index</span><span class="p">(</span><span class="s">&quot;--allbut&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">idx</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s">&quot;removekmod needs at least one GLOB before --allbut&quot;</span><span class="p">)</span>
<span class="c"># Apply keepglobs anywhere they appear in the path</span>
<span class="n">keepglobs</span> <span class="o">=</span> <span class="n">globs</span><span class="p">[</span><span class="n">idx</span><span class="o">+</span><span class="mi">1</span><span class="p">:]</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">keepglobs</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s">&quot;removekmod needs at least one GLOB after --allbut&quot;</span><span class="p">)</span>
<span class="n">globs</span> <span class="o">=</span> <span class="n">globs</span><span class="p">[:</span><span class="n">idx</span><span class="p">]</span>
<span class="k">else</span><span class="p">:</span>
<span class="c"># Nothing to keep</span>
<span class="n">keepglobs</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">filelist</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
<span class="k">for</span> <span class="n">g</span> <span class="ow">in</span> <span class="n">globs</span><span class="p">:</span>
<span class="k">for</span> <span class="n">top_dir</span> <span class="ow">in</span> <span class="n">rglob</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_out</span><span class="p">(</span><span class="s">&quot;/lib/modules/*/kernel/&quot;</span><span class="o">+</span><span class="n">g</span><span class="p">)):</span>
<span class="k">for</span> <span class="n">root</span><span class="p">,</span> <span class="n">_dirs</span><span class="p">,</span> <span class="n">files</span> <span class="ow">in</span> <span class="n">os</span><span class="o">.</span><span class="n">walk</span><span class="p">(</span><span class="n">top_dir</span><span class="p">):</span>
<span class="n">filelist</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">root</span><span class="o">+</span><span class="s">&quot;/&quot;</span><span class="o">+</span><span class="n">f</span> <span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">files</span><span class="p">)</span>
<span class="c"># Remove anything matching keepglobs from the list</span>
<span class="n">matches</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
<span class="k">for</span> <span class="n">g</span> <span class="ow">in</span> <span class="n">keepglobs</span><span class="p">:</span>
<span class="n">globs_re</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="n">fnmatch</span><span class="o">.</span><span class="n">translate</span><span class="p">(</span><span class="s">&quot;*&quot;</span><span class="o">+</span><span class="n">g</span><span class="o">+</span><span class="s">&quot;*&quot;</span><span class="p">))</span>
<span class="n">m</span> <span class="o">=</span> <span class="nb">filter</span><span class="p">(</span><span class="n">globs_re</span><span class="o">.</span><span class="n">match</span><span class="p">,</span> <span class="n">filelist</span><span class="p">)</span>
<span class="k">if</span> <span class="n">m</span><span class="p">:</span>
<span class="n">matches</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">&quot;removekmod </span><span class="si">%s</span><span class="s">: no files matched!&quot;</span><span class="p">,</span> <span class="n">g</span><span class="p">)</span>
<span class="n">remove_files</span> <span class="o">=</span> <span class="n">filelist</span><span class="o">.</span><span class="n">difference</span><span class="p">(</span><span class="n">matches</span><span class="p">)</span>
<span class="k">if</span> <span class="n">remove_files</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">&quot;removekmod: removing </span><span class="si">%d</span><span class="s"> files&quot;</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">remove_files</span><span class="p">))</span>
<span class="nb">map</span><span class="p">(</span><span class="n">remove</span><span class="p">,</span> <span class="n">remove_files</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">&quot;removekmod </span><span class="si">%s</span><span class="s">: no files to remove!&quot;</span><span class="p">,</span> <span class="n">cmd</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="LoraxTemplateRunner.createaddrsize"><a class="viewcode-back" href="../../pylorax.html#pylorax.ltmpl.LoraxTemplateRunner.createaddrsize">[docs]</a> <span class="k">def</span> <span class="nf">createaddrsize</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">addr</span><span class="p">,</span> <span class="n">src</span><span class="p">,</span> <span class="n">dest</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> createaddrsize INITRD_ADDRESS INITRD ADDRSIZE</span>
<span class="sd"> Create the initrd.addrsize file required in LPAR boot process.</span>
<span class="sd"> Examples:</span>
<span class="sd"> createaddrsize ${INITRD_ADDRESS} ${outroot}/${BOOTDIR}/initrd.img ${outroot}/${BOOTDIR}/initrd.addrsize</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="n">addrsize</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">dest</span><span class="p">,</span> <span class="s">&quot;wb&quot;</span><span class="p">)</span>
<span class="n">addrsize_data</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&gt;iiii&quot;</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">addr</span><span class="p">,</span> <span class="mi">16</span><span class="p">),</span> <span class="mi">0</span><span class="p">,</span> <span class="n">os</span><span class="o">.</span><span class="n">stat</span><span class="p">(</span><span class="n">src</span><span class="p">)</span><span class="o">.</span><span class="n">st_size</span><span class="p">)</span>
<span class="n">addrsize</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">addrsize_data</span><span class="p">)</span>
<span class="n">addrsize</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
</div>
<div class="viewcode-block" id="LoraxTemplateRunner.systemctl"><a class="viewcode-back" href="../../pylorax.html#pylorax.ltmpl.LoraxTemplateRunner.systemctl">[docs]</a> <span class="k">def</span> <span class="nf">systemctl</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">cmd</span><span class="p">,</span> <span class="o">*</span><span class="n">units</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> systemctl [enable|disable|mask] UNIT [UNIT...]</span>
<span class="sd"> Enable, disable, or mask the given systemd units.</span>
<span class="sd"> Examples:</span>
<span class="sd"> systemctl disable lvm2-monitor.service</span>
<span class="sd"> systemctl mask fedora-storage-init.service fedora-configure.service</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">if</span> <span class="n">cmd</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">(</span><span class="s">&#39;enable&#39;</span><span class="p">,</span> <span class="s">&#39;disable&#39;</span><span class="p">,</span> <span class="s">&#39;mask&#39;</span><span class="p">):</span>
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s">&#39;unsupported systemctl cmd: </span><span class="si">%s</span><span class="s">&#39;</span> <span class="o">%</span> <span class="n">cmd</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">units</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">&quot;systemctl: no units given for </span><span class="si">%s</span><span class="s">, ignoring&quot;</span><span class="p">,</span> <span class="n">cmd</span><span class="p">)</span>
<span class="k">return</span>
<span class="bp">self</span><span class="o">.</span><span class="n">mkdir</span><span class="p">(</span><span class="s">&quot;/run/systemd/system&quot;</span><span class="p">)</span> <span class="c"># XXX workaround for systemctl bug</span>
<span class="n">systemctl</span> <span class="o">=</span> <span class="p">[</span><span class="s">&#39;systemctl&#39;</span><span class="p">,</span> <span class="s">&#39;--root&#39;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">outroot</span><span class="p">,</span> <span class="s">&#39;--no-reload&#39;</span><span class="p">,</span>
<span class="n">cmd</span><span class="p">]</span>
<span class="c"># When a unit doesn&#39;t exist systemd aborts the command. Run them one at a time.</span>
<span class="c"># XXX for some reason &#39;systemctl enable/disable&#39; always returns 1</span>
<span class="k">for</span> <span class="n">unit</span> <span class="ow">in</span> <span class="n">units</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">cmd</span> <span class="o">=</span> <span class="n">systemctl</span> <span class="o">+</span> <span class="p">[</span><span class="n">unit</span><span class="p">]</span>
<span class="n">runcmd</span><span class="p">(</span><span class="n">cmd</span><span class="p">)</span>
<span class="k">except</span> <span class="n">CalledProcessError</span><span class="p">:</span>
<span class="k">pass</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">Lorax 19.7.10 documentation</a> &raquo;</li>
<li><a href="../index.html" >Module code</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2017, Red Hat, Inc..
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>

View File

@ -0,0 +1,202 @@
<!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>pylorax.sysutils &mdash; Lorax 19.7.10 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: '19.7.10',
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>
<link rel="top" title="Lorax 19.7.10 documentation" href="../../index.html" />
<link rel="up" title="Module code" href="../index.html" />
</head>
<body>
<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">Lorax 19.7.10 documentation</a> &raquo;</li>
<li><a href="../index.html" accesskey="U">Module code</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<h1>Source code for pylorax.sysutils</h1><div class="highlight"><pre>
<span class="c">#</span>
<span class="c"># sysutils.py</span>
<span class="c">#</span>
<span class="c"># Copyright (C) 2009 Red Hat, Inc.</span>
<span class="c">#</span>
<span class="c"># This program is free software; you can redistribute it and/or modify</span>
<span class="c"># it under the terms of the GNU General Public License as published by</span>
<span class="c"># the Free Software Foundation; either version 2 of the License, or</span>
<span class="c"># (at your option) any later version.</span>
<span class="c">#</span>
<span class="c"># This program is distributed in the hope that it will be useful,</span>
<span class="c"># but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<span class="c"># MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span>
<span class="c"># GNU General Public License for more details.</span>
<span class="c">#</span>
<span class="c"># You should have received a copy of the GNU General Public License</span>
<span class="c"># along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;.</span>
<span class="c">#</span>
<span class="c"># Red Hat Author(s): Martin Gracik &lt;mgracik@redhat.com&gt;</span>
<span class="c">#</span>
<span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span><span class="s">&quot;joinpaths&quot;</span><span class="p">,</span> <span class="s">&quot;touch&quot;</span><span class="p">,</span> <span class="s">&quot;replace&quot;</span><span class="p">,</span> <span class="s">&quot;chown_&quot;</span><span class="p">,</span> <span class="s">&quot;chmod_&quot;</span><span class="p">,</span> <span class="s">&quot;remove&quot;</span><span class="p">,</span>
<span class="s">&quot;linktree&quot;</span><span class="p">]</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">re</span>
<span class="kn">import</span> <span class="nn">fileinput</span>
<span class="kn">import</span> <span class="nn">pwd</span>
<span class="kn">import</span> <span class="nn">grp</span>
<span class="kn">import</span> <span class="nn">glob</span>
<span class="kn">import</span> <span class="nn">shutil</span>
<span class="kn">from</span> <span class="nn">pylorax.executils</span> <span class="kn">import</span> <span class="n">runcmd</span>
<div class="viewcode-block" id="joinpaths"><a class="viewcode-back" href="../../pylorax.html#pylorax.sysutils.joinpaths">[docs]</a><span class="k">def</span> <span class="nf">joinpaths</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="n">path</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">sep</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">args</span><span class="p">)</span>
<span class="k">if</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">&quot;follow_symlinks&quot;</span><span class="p">):</span>
<span class="k">return</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">realpath</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="n">path</span>
</div>
<div class="viewcode-block" id="touch"><a class="viewcode-back" href="../../pylorax.html#pylorax.sysutils.touch">[docs]</a><span class="k">def</span> <span class="nf">touch</span><span class="p">(</span><span class="n">fname</span><span class="p">):</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">fname</span><span class="p">,</span> <span class="s">&quot;w&quot;</span><span class="p">)</span> <span class="k">as</span> <span class="n">_</span><span class="p">:</span>
<span class="k">pass</span>
</div>
<div class="viewcode-block" id="replace"><a class="viewcode-back" href="../../pylorax.html#pylorax.sysutils.replace">[docs]</a><span class="k">def</span> <span class="nf">replace</span><span class="p">(</span><span class="n">fname</span><span class="p">,</span> <span class="n">find</span><span class="p">,</span> <span class="n">substitute</span><span class="p">):</span>
<span class="n">fin</span> <span class="o">=</span> <span class="n">fileinput</span><span class="o">.</span><span class="n">input</span><span class="p">(</span><span class="n">fname</span><span class="p">,</span> <span class="n">inplace</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
<span class="n">pattern</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="n">find</span><span class="p">)</span>
<span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">fin</span><span class="p">:</span>
<span class="n">line</span> <span class="o">=</span> <span class="n">pattern</span><span class="o">.</span><span class="n">sub</span><span class="p">(</span><span class="n">substitute</span><span class="p">,</span> <span class="n">line</span><span class="p">)</span>
<span class="n">sys</span><span class="o">.</span><span class="n">stdout</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">line</span><span class="p">)</span>
<span class="n">fin</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
</div>
<div class="viewcode-block" id="chown_"><a class="viewcode-back" href="../../pylorax.html#pylorax.sysutils.chown_">[docs]</a><span class="k">def</span> <span class="nf">chown_</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="n">user</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">group</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">recursive</span><span class="o">=</span><span class="bp">False</span><span class="p">):</span>
<span class="n">uid</span> <span class="o">=</span> <span class="n">gid</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span>
<span class="k">if</span> <span class="n">user</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span>
<span class="n">uid</span> <span class="o">=</span> <span class="n">pwd</span><span class="o">.</span><span class="n">getpwnam</span><span class="p">(</span><span class="n">user</span><span class="p">)[</span><span class="mi">2</span><span class="p">]</span>
<span class="k">if</span> <span class="n">group</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span>
<span class="n">gid</span> <span class="o">=</span> <span class="n">grp</span><span class="o">.</span><span class="n">getgrnam</span><span class="p">(</span><span class="n">group</span><span class="p">)[</span><span class="mi">2</span><span class="p">]</span>
<span class="k">for</span> <span class="n">fname</span> <span class="ow">in</span> <span class="n">glob</span><span class="o">.</span><span class="n">iglob</span><span class="p">(</span><span class="n">path</span><span class="p">):</span>
<span class="n">os</span><span class="o">.</span><span class="n">chown</span><span class="p">(</span><span class="n">fname</span><span class="p">,</span> <span class="n">uid</span><span class="p">,</span> <span class="n">gid</span><span class="p">)</span>
<span class="k">if</span> <span class="n">recursive</span> <span class="ow">and</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">fname</span><span class="p">):</span>
<span class="k">for</span> <span class="n">nested</span> <span class="ow">in</span> <span class="n">os</span><span class="o">.</span><span class="n">listdir</span><span class="p">(</span><span class="n">fname</span><span class="p">):</span>
<span class="n">nested</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">fname</span><span class="p">,</span> <span class="n">nested</span><span class="p">)</span>
<span class="n">chown_</span><span class="p">(</span><span class="n">nested</span><span class="p">,</span> <span class="n">user</span><span class="p">,</span> <span class="n">group</span><span class="p">,</span> <span class="n">recursive</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="chmod_"><a class="viewcode-back" href="../../pylorax.html#pylorax.sysutils.chmod_">[docs]</a><span class="k">def</span> <span class="nf">chmod_</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="n">mode</span><span class="p">,</span> <span class="n">recursive</span><span class="o">=</span><span class="bp">False</span><span class="p">):</span>
<span class="k">for</span> <span class="n">fname</span> <span class="ow">in</span> <span class="n">glob</span><span class="o">.</span><span class="n">iglob</span><span class="p">(</span><span class="n">path</span><span class="p">):</span>
<span class="n">os</span><span class="o">.</span><span class="n">chmod</span><span class="p">(</span><span class="n">fname</span><span class="p">,</span> <span class="n">mode</span><span class="p">)</span>
<span class="k">if</span> <span class="n">recursive</span> <span class="ow">and</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">fname</span><span class="p">):</span>
<span class="k">for</span> <span class="n">nested</span> <span class="ow">in</span> <span class="n">os</span><span class="o">.</span><span class="n">listdir</span><span class="p">(</span><span class="n">fname</span><span class="p">):</span>
<span class="n">nested</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">fname</span><span class="p">,</span> <span class="n">nested</span><span class="p">)</span>
<span class="n">chmod_</span><span class="p">(</span><span class="n">nested</span><span class="p">,</span> <span class="n">mode</span><span class="p">,</span> <span class="n">recursive</span><span class="p">)</span>
</div>
<span class="k">def</span> <span class="nf">cpfile</span><span class="p">(</span><span class="n">src</span><span class="p">,</span> <span class="n">dst</span><span class="p">):</span>
<span class="n">shutil</span><span class="o">.</span><span class="n">copy2</span><span class="p">(</span><span class="n">src</span><span class="p">,</span> <span class="n">dst</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">dst</span><span class="p">):</span>
<span class="n">dst</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">dst</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">src</span><span class="p">))</span>
<span class="k">return</span> <span class="n">dst</span>
<span class="k">def</span> <span class="nf">mvfile</span><span class="p">(</span><span class="n">src</span><span class="p">,</span> <span class="n">dst</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">dst</span><span class="p">):</span>
<span class="n">dst</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">dst</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">src</span><span class="p">))</span>
<span class="n">os</span><span class="o">.</span><span class="n">rename</span><span class="p">(</span><span class="n">src</span><span class="p">,</span> <span class="n">dst</span><span class="p">)</span>
<span class="k">return</span> <span class="n">dst</span>
<div class="viewcode-block" id="remove"><a class="viewcode-back" href="../../pylorax.html#pylorax.sysutils.remove">[docs]</a><span class="k">def</span> <span class="nf">remove</span><span class="p">(</span><span class="n">target</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">target</span><span class="p">)</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">islink</span><span class="p">(</span><span class="n">target</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">target</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">target</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="linktree"><a class="viewcode-back" href="../../pylorax.html#pylorax.sysutils.linktree">[docs]</a><span class="k">def</span> <span class="nf">linktree</span><span class="p">(</span><span class="n">src</span><span class="p">,</span> <span class="n">dst</span><span class="p">):</span>
<span class="n">runcmd</span><span class="p">([</span><span class="s">&quot;/bin/cp&quot;</span><span class="p">,</span> <span class="s">&quot;-alx&quot;</span><span class="p">,</span> <span class="n">src</span><span class="p">,</span> <span class="n">dst</span><span class="p">])</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">Lorax 19.7.10 documentation</a> &raquo;</li>
<li><a href="../index.html" >Module code</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2017, Red Hat, Inc..
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>

View File

@ -0,0 +1,414 @@
<!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>pylorax.treebuilder &mdash; Lorax 19.7.10 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: '19.7.10',
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>
<link rel="top" title="Lorax 19.7.10 documentation" href="../../index.html" />
<link rel="up" title="Module code" href="../index.html" />
</head>
<body>
<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">Lorax 19.7.10 documentation</a> &raquo;</li>
<li><a href="../index.html" accesskey="U">Module code</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<h1>Source code for pylorax.treebuilder</h1><div class="highlight"><pre>
<span class="c"># treebuilder.py - handle arch-specific tree building stuff using templates</span>
<span class="c">#</span>
<span class="c"># Copyright (C) 2011 Red Hat, Inc.</span>
<span class="c">#</span>
<span class="c"># This program is free software; you can redistribute it and/or modify</span>
<span class="c"># it under the terms of the GNU General Public License as published by</span>
<span class="c"># the Free Software Foundation; either version 2 of the License, or</span>
<span class="c"># (at your option) any later version.</span>
<span class="c">#</span>
<span class="c"># This program is distributed in the hope that it will be useful,</span>
<span class="c"># but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<span class="c"># MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span>
<span class="c"># GNU General Public License for more details.</span>
<span class="c">#</span>
<span class="c"># You should have received a copy of the GNU General Public License</span>
<span class="c"># along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;.</span>
<span class="c">#</span>
<span class="c"># Author(s): Will Woods &lt;wwoods@redhat.com&gt;</span>
<span class="kn">import</span> <span class="nn">logging</span>
<span class="n">logger</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s">&quot;pylorax.treebuilder&quot;</span><span class="p">)</span>
<span class="kn">import</span> <span class="nn">os</span><span class="o">,</span> <span class="nn">re</span>
<span class="kn">from</span> <span class="nn">os.path</span> <span class="kn">import</span> <span class="n">basename</span>
<span class="kn">from</span> <span class="nn">pylorax.sysutils</span> <span class="kn">import</span> <span class="n">joinpaths</span><span class="p">,</span> <span class="n">remove</span>
<span class="kn">from</span> <span class="nn">shutil</span> <span class="kn">import</span> <span class="n">copytree</span><span class="p">,</span> <span class="n">copy2</span>
<span class="kn">from</span> <span class="nn">pylorax.base</span> <span class="kn">import</span> <span class="n">DataHolder</span>
<span class="kn">from</span> <span class="nn">pylorax.ltmpl</span> <span class="kn">import</span> <span class="n">LoraxTemplateRunner</span>
<span class="kn">import</span> <span class="nn">pylorax.imgutils</span> <span class="kn">as</span> <span class="nn">imgutils</span>
<span class="kn">from</span> <span class="nn">pylorax.executils</span> <span class="kn">import</span> <span class="n">runcmd</span><span class="p">,</span> <span class="n">runcmd_output</span>
<span class="n">templatemap</span> <span class="o">=</span> <span class="p">{</span>
<span class="s">&#39;i386&#39;</span><span class="p">:</span> <span class="s">&#39;x86.tmpl&#39;</span><span class="p">,</span>
<span class="s">&#39;x86_64&#39;</span><span class="p">:</span> <span class="s">&#39;x86.tmpl&#39;</span><span class="p">,</span>
<span class="s">&#39;ppc&#39;</span><span class="p">:</span> <span class="s">&#39;ppc.tmpl&#39;</span><span class="p">,</span>
<span class="s">&#39;ppc64&#39;</span><span class="p">:</span> <span class="s">&#39;ppc.tmpl&#39;</span><span class="p">,</span>
<span class="s">&#39;ppc64le&#39;</span><span class="p">:</span> <span class="s">&#39;ppc.tmpl&#39;</span><span class="p">,</span>
<span class="s">&#39;s390&#39;</span><span class="p">:</span> <span class="s">&#39;s390.tmpl&#39;</span><span class="p">,</span>
<span class="s">&#39;s390x&#39;</span><span class="p">:</span> <span class="s">&#39;s390.tmpl&#39;</span><span class="p">,</span>
<span class="s">&#39;aarch64&#39;</span><span class="p">:</span> <span class="s">&#39;aarch64.tmpl&#39;</span><span class="p">,</span>
<span class="s">&#39;arm&#39;</span><span class="p">:</span> <span class="s">&#39;arm.tmpl&#39;</span><span class="p">,</span>
<span class="s">&#39;armhfp&#39;</span><span class="p">:</span> <span class="s">&#39;arm.tmpl&#39;</span><span class="p">,</span>
<span class="p">}</span>
<div class="viewcode-block" id="generate_module_info"><a class="viewcode-back" href="../../pylorax.html#pylorax.treebuilder.generate_module_info">[docs]</a><span class="k">def</span> <span class="nf">generate_module_info</span><span class="p">(</span><span class="n">moddir</span><span class="p">,</span> <span class="n">outfile</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">module_desc</span><span class="p">(</span><span class="n">mod</span><span class="p">):</span>
<span class="n">output</span> <span class="o">=</span> <span class="n">runcmd_output</span><span class="p">([</span><span class="s">&quot;modinfo&quot;</span><span class="p">,</span> <span class="s">&quot;-F&quot;</span><span class="p">,</span> <span class="s">&quot;description&quot;</span><span class="p">,</span> <span class="n">mod</span><span class="p">])</span>
<span class="k">return</span> <span class="n">output</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">read_module_set</span><span class="p">(</span><span class="n">name</span><span class="p">):</span>
<span class="k">return</span> <span class="nb">set</span><span class="p">(</span><span class="n">l</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span> <span class="k">for</span> <span class="n">l</span> <span class="ow">in</span> <span class="nb">open</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">moddir</span><span class="p">,</span><span class="n">name</span><span class="p">))</span> <span class="k">if</span> <span class="s">&quot;.ko&quot;</span> <span class="ow">in</span> <span class="n">l</span><span class="p">)</span>
<span class="n">modsets</span> <span class="o">=</span> <span class="p">{</span><span class="s">&#39;scsi&#39;</span><span class="p">:</span><span class="n">read_module_set</span><span class="p">(</span><span class="s">&quot;modules.block&quot;</span><span class="p">),</span>
<span class="s">&#39;eth&#39;</span><span class="p">:</span><span class="n">read_module_set</span><span class="p">(</span><span class="s">&quot;modules.networking&quot;</span><span class="p">)}</span>
<span class="n">modinfo</span> <span class="o">=</span> <span class="nb">list</span><span class="p">()</span>
<span class="k">for</span> <span class="n">root</span><span class="p">,</span> <span class="n">_dirs</span><span class="p">,</span> <span class="n">files</span> <span class="ow">in</span> <span class="n">os</span><span class="o">.</span><span class="n">walk</span><span class="p">(</span><span class="n">moddir</span><span class="p">):</span>
<span class="k">for</span> <span class="n">modtype</span><span class="p">,</span> <span class="n">modset</span> <span class="ow">in</span> <span class="n">modsets</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
<span class="k">for</span> <span class="n">mod</span> <span class="ow">in</span> <span class="n">modset</span><span class="o">.</span><span class="n">intersection</span><span class="p">(</span><span class="n">files</span><span class="p">):</span> <span class="c"># modules in this dir</span>
<span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">_ext</span><span class="p">)</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">splitext</span><span class="p">(</span><span class="n">mod</span><span class="p">)</span> <span class="c"># foo.ko -&gt; (foo, .ko)</span>
<span class="n">desc</span> <span class="o">=</span> <span class="n">module_desc</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">root</span><span class="p">,</span><span class="n">mod</span><span class="p">))</span> <span class="ow">or</span> <span class="s">&quot;</span><span class="si">%s</span><span class="s"> driver&quot;</span> <span class="o">%</span> <span class="n">name</span>
<span class="n">modinfo</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="nb">dict</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="n">name</span><span class="p">,</span> <span class="nb">type</span><span class="o">=</span><span class="n">modtype</span><span class="p">,</span> <span class="n">desc</span><span class="o">=</span><span class="n">desc</span><span class="p">))</span>
<span class="n">out</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">outfile</span> <span class="ow">or</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">moddir</span><span class="p">,</span><span class="s">&quot;module-info&quot;</span><span class="p">),</span> <span class="s">&quot;w&quot;</span><span class="p">)</span>
<span class="n">out</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">&quot;Version 0</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">)</span>
<span class="k">for</span> <span class="n">mod</span> <span class="ow">in</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">modinfo</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">m</span><span class="p">:</span> <span class="n">m</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">&#39;name&#39;</span><span class="p">)):</span>
<span class="n">out</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">&#39;{name}</span><span class="se">\n\t</span><span class="s">{type}</span><span class="se">\n\t</span><span class="s">&quot;{desc:.65}&quot;</span><span class="se">\n</span><span class="s">&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="o">**</span><span class="n">mod</span><span class="p">))</span>
</div>
<div class="viewcode-block" id="RuntimeBuilder"><a class="viewcode-back" href="../../pylorax.html#pylorax.treebuilder.RuntimeBuilder">[docs]</a><span class="k">class</span> <span class="nc">RuntimeBuilder</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;Builds the anaconda runtime image.&#39;&#39;&#39;</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">product</span><span class="p">,</span> <span class="n">arch</span><span class="p">,</span> <span class="n">yum</span><span class="p">,</span> <span class="n">templatedir</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span>
<span class="n">installpkgs</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span>
<span class="n">add_templates</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span>
<span class="n">add_template_vars</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
<span class="n">root</span> <span class="o">=</span> <span class="n">yum</span><span class="o">.</span><span class="n">conf</span><span class="o">.</span><span class="n">installroot</span>
<span class="c"># use a copy of product so we can modify it locally</span>
<span class="n">product</span> <span class="o">=</span> <span class="n">product</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
<span class="n">product</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">product</span><span class="o">.</span><span class="n">name</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">vars</span> <span class="o">=</span> <span class="n">DataHolder</span><span class="p">(</span><span class="n">arch</span><span class="o">=</span><span class="n">arch</span><span class="p">,</span> <span class="n">product</span><span class="o">=</span><span class="n">product</span><span class="p">,</span> <span class="n">yum</span><span class="o">=</span><span class="n">yum</span><span class="p">,</span> <span class="n">root</span><span class="o">=</span><span class="n">root</span><span class="p">,</span>
<span class="n">basearch</span><span class="o">=</span><span class="n">arch</span><span class="o">.</span><span class="n">basearch</span><span class="p">,</span> <span class="n">libdir</span><span class="o">=</span><span class="n">arch</span><span class="o">.</span><span class="n">libdir</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">yum</span> <span class="o">=</span> <span class="n">yum</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_runner</span> <span class="o">=</span> <span class="n">LoraxTemplateRunner</span><span class="p">(</span><span class="n">inroot</span><span class="o">=</span><span class="n">root</span><span class="p">,</span> <span class="n">outroot</span><span class="o">=</span><span class="n">root</span><span class="p">,</span>
<span class="n">yum_obj</span><span class="o">=</span><span class="n">yum</span><span class="p">,</span> <span class="n">templatedir</span><span class="o">=</span><span class="n">templatedir</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">add_templates</span> <span class="o">=</span> <span class="n">add_templates</span> <span class="ow">or</span> <span class="p">[]</span>
<span class="bp">self</span><span class="o">.</span><span class="n">add_template_vars</span> <span class="o">=</span> <span class="n">add_template_vars</span> <span class="ow">or</span> <span class="p">{}</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_installpkgs</span> <span class="o">=</span> <span class="n">installpkgs</span> <span class="ow">or</span> <span class="p">[]</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_runner</span><span class="o">.</span><span class="n">defaults</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">vars</span>
<span class="k">def</span> <span class="nf">_install_branding</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="n">release</span> <span class="o">=</span> <span class="bp">None</span>
<span class="k">for</span> <span class="n">pkg</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">yum</span><span class="o">.</span><span class="n">whatProvides</span><span class="p">(</span><span class="s">&#39;/etc/system-release&#39;</span><span class="p">,</span> <span class="bp">None</span><span class="p">,</span> <span class="bp">None</span><span class="p">):</span>
<span class="k">if</span> <span class="n">pkg</span><span class="o">.</span><span class="n">name</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s">&#39;generic&#39;</span><span class="p">):</span>
<span class="k">continue</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">release</span> <span class="o">=</span> <span class="n">pkg</span><span class="o">.</span><span class="n">name</span>
<span class="k">break</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">release</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s">&#39;could not get the release&#39;</span><span class="p">)</span>
<span class="k">return</span>
<span class="c"># release</span>
<span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&#39;got release: </span><span class="si">%s</span><span class="s">&#39;</span><span class="p">,</span> <span class="n">release</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_runner</span><span class="o">.</span><span class="n">installpkg</span><span class="p">(</span><span class="n">release</span><span class="p">)</span>
<span class="c"># logos</span>
<span class="n">release</span><span class="p">,</span> <span class="n">_suffix</span> <span class="o">=</span> <span class="n">release</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">&#39;-&#39;</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">_runner</span><span class="o">.</span><span class="n">installpkg</span><span class="p">(</span><span class="s">&#39;</span><span class="si">%s</span><span class="s">-logos&#39;</span> <span class="o">%</span> <span class="n">release</span><span class="p">)</span>
<div class="viewcode-block" id="RuntimeBuilder.install"><a class="viewcode-back" href="../../pylorax.html#pylorax.treebuilder.RuntimeBuilder.install">[docs]</a> <span class="k">def</span> <span class="nf">install</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;Install packages and do initial setup with runtime-install.tmpl&#39;&#39;&#39;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_install_branding</span><span class="p">()</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_installpkgs</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_runner</span><span class="o">.</span><span class="n">installpkg</span><span class="p">(</span><span class="o">*</span><span class="bp">self</span><span class="o">.</span><span class="n">_installpkgs</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_runner</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="s">&quot;runtime-install.tmpl&quot;</span><span class="p">)</span>
<span class="k">for</span> <span class="n">tmpl</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">add_templates</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_runner</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="n">tmpl</span><span class="p">,</span> <span class="o">**</span><span class="bp">self</span><span class="o">.</span><span class="n">add_template_vars</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="RuntimeBuilder.writepkglists"><a class="viewcode-back" href="../../pylorax.html#pylorax.treebuilder.RuntimeBuilder.writepkglists">[docs]</a> <span class="k">def</span> <span class="nf">writepkglists</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">pkglistdir</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;debugging data: write out lists of package contents&#39;&#39;&#39;</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">isdir</span><span class="p">(</span><span class="n">pkglistdir</span><span class="p">):</span>
<span class="n">os</span><span class="o">.</span><span class="n">makedirs</span><span class="p">(</span><span class="n">pkglistdir</span><span class="p">)</span>
<span class="k">for</span> <span class="n">pkgobj</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">yum</span><span class="o">.</span><span class="n">doPackageLists</span><span class="p">(</span><span class="n">pkgnarrow</span><span class="o">=</span><span class="s">&#39;installed&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">installed</span><span class="p">:</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">pkglistdir</span><span class="p">,</span> <span class="n">pkgobj</span><span class="o">.</span><span class="n">name</span><span class="p">),</span> <span class="s">&quot;w&quot;</span><span class="p">)</span> <span class="k">as</span> <span class="n">fobj</span><span class="p">:</span>
<span class="k">for</span> <span class="n">fname</span> <span class="ow">in</span> <span class="n">pkgobj</span><span class="o">.</span><span class="n">filelist</span> <span class="o">+</span> <span class="n">pkgobj</span><span class="o">.</span><span class="n">dirlist</span><span class="p">:</span>
<span class="n">fobj</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">&quot;{0}</span><span class="se">\n</span><span class="s">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">fname</span><span class="p">))</span>
</div>
<div class="viewcode-block" id="RuntimeBuilder.postinstall"><a class="viewcode-back" href="../../pylorax.html#pylorax.treebuilder.RuntimeBuilder.postinstall">[docs]</a> <span class="k">def</span> <span class="nf">postinstall</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;Do some post-install setup work with runtime-postinstall.tmpl&#39;&#39;&#39;</span>
<span class="c"># copy configdir into runtime root beforehand</span>
<span class="n">configdir</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_runner</span><span class="o">.</span><span class="n">templatedir</span><span class="p">,</span><span class="s">&quot;config_files&quot;</span><span class="p">)</span>
<span class="n">configdir_path</span> <span class="o">=</span> <span class="s">&quot;tmp/config_files&quot;</span>
<span class="n">fullpath</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">vars</span><span class="o">.</span><span class="n">root</span><span class="p">,</span> <span class="n">configdir_path</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">exists</span><span class="p">(</span><span class="n">fullpath</span><span class="p">):</span>
<span class="n">remove</span><span class="p">(</span><span class="n">fullpath</span><span class="p">)</span>
<span class="n">copytree</span><span class="p">(</span><span class="n">configdir</span><span class="p">,</span> <span class="n">fullpath</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_runner</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="s">&quot;runtime-postinstall.tmpl&quot;</span><span class="p">,</span> <span class="n">configdir</span><span class="o">=</span><span class="n">configdir_path</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="RuntimeBuilder.cleanup"><a class="viewcode-back" href="../../pylorax.html#pylorax.treebuilder.RuntimeBuilder.cleanup">[docs]</a> <span class="k">def</span> <span class="nf">cleanup</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;Remove unneeded packages and files with runtime-cleanup.tmpl&#39;&#39;&#39;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_runner</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="s">&quot;runtime-cleanup.tmpl&quot;</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="RuntimeBuilder.writepkgsizes"><a class="viewcode-back" href="../../pylorax.html#pylorax.treebuilder.RuntimeBuilder.writepkgsizes">[docs]</a> <span class="k">def</span> <span class="nf">writepkgsizes</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">pkgsizefile</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;debugging data: write a big list of pkg sizes&#39;&#39;&#39;</span>
<span class="n">fobj</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">pkgsizefile</span><span class="p">,</span> <span class="s">&quot;w&quot;</span><span class="p">)</span>
<span class="n">getsize</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">f</span><span class="p">:</span> <span class="n">os</span><span class="o">.</span><span class="n">lstat</span><span class="p">(</span><span class="n">f</span><span class="p">)</span><span class="o">.</span><span class="n">st_size</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">exists</span><span class="p">(</span><span class="n">f</span><span class="p">)</span> <span class="k">else</span> <span class="mi">0</span>
<span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="nb">sorted</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">yum</span><span class="o">.</span><span class="n">doPackageLists</span><span class="p">(</span><span class="n">pkgnarrow</span><span class="o">=</span><span class="s">&#39;installed&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">installed</span><span class="p">):</span>
<span class="n">pkgsize</span> <span class="o">=</span> <span class="nb">sum</span><span class="p">(</span><span class="n">getsize</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">vars</span><span class="o">.</span><span class="n">root</span><span class="p">,</span><span class="n">f</span><span class="p">))</span> <span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">p</span><span class="o">.</span><span class="n">filelist</span><span class="p">)</span>
<span class="n">fobj</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">&quot;{0.name}.{0.arch}: {1}</span><span class="se">\n</span><span class="s">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">p</span><span class="p">,</span> <span class="n">pkgsize</span><span class="p">))</span>
</div>
<div class="viewcode-block" id="RuntimeBuilder.generate_module_data"><a class="viewcode-back" href="../../pylorax.html#pylorax.treebuilder.RuntimeBuilder.generate_module_data">[docs]</a> <span class="k">def</span> <span class="nf">generate_module_data</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="n">root</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">vars</span><span class="o">.</span><span class="n">root</span>
<span class="n">moddir</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">root</span><span class="p">,</span> <span class="s">&quot;lib/modules/&quot;</span><span class="p">)</span>
<span class="k">for</span> <span class="n">kver</span> <span class="ow">in</span> <span class="n">os</span><span class="o">.</span><span class="n">listdir</span><span class="p">(</span><span class="n">moddir</span><span class="p">):</span>
<span class="n">ksyms</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">root</span><span class="p">,</span> <span class="s">&quot;boot/System.map-</span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">kver</span><span class="p">)</span>
<span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;doing depmod and module-info for </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">kver</span><span class="p">)</span>
<span class="n">runcmd</span><span class="p">([</span><span class="s">&quot;depmod&quot;</span><span class="p">,</span> <span class="s">&quot;-a&quot;</span><span class="p">,</span> <span class="s">&quot;-F&quot;</span><span class="p">,</span> <span class="n">ksyms</span><span class="p">,</span> <span class="s">&quot;-b&quot;</span><span class="p">,</span> <span class="n">root</span><span class="p">,</span> <span class="n">kver</span><span class="p">])</span>
<span class="n">generate_module_info</span><span class="p">(</span><span class="n">moddir</span><span class="o">+</span><span class="n">kver</span><span class="p">,</span> <span class="n">outfile</span><span class="o">=</span><span class="n">moddir</span><span class="o">+</span><span class="s">&quot;module-info&quot;</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="RuntimeBuilder.create_runtime"><a class="viewcode-back" href="../../pylorax.html#pylorax.treebuilder.RuntimeBuilder.create_runtime">[docs]</a> <span class="k">def</span> <span class="nf">create_runtime</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">outfile</span><span class="o">=</span><span class="s">&quot;/var/tmp/squashfs.img&quot;</span><span class="p">,</span> <span class="n">compression</span><span class="o">=</span><span class="s">&quot;xz&quot;</span><span class="p">,</span> <span class="n">compressargs</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">size</span><span class="o">=</span><span class="mi">2</span><span class="p">):</span>
<span class="k">if</span> <span class="n">compressargs</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span>
<span class="n">compressargs</span> <span class="o">=</span> <span class="p">[]</span>
<span class="c"># make live rootfs image - must be named &quot;LiveOS/rootfs.img&quot; for dracut</span>
<span class="n">workdir</span> <span class="o">=</span> <span class="n">joinpaths</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">dirname</span><span class="p">(</span><span class="n">outfile</span><span class="p">),</span> <span class="s">&quot;runtime-workdir&quot;</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">makedirs</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">workdir</span><span class="p">,</span> <span class="s">&quot;LiveOS&quot;</span><span class="p">))</span>
<span class="n">imgutils</span><span class="o">.</span><span class="n">mkrootfsimg</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">vars</span><span class="o">.</span><span class="n">root</span><span class="p">,</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">workdir</span><span class="p">,</span> <span class="s">&quot;LiveOS/rootfs.img&quot;</span><span class="p">),</span>
<span class="s">&quot;Anaconda&quot;</span><span class="p">,</span> <span class="n">size</span><span class="o">=</span><span class="n">size</span><span class="p">)</span>
<span class="c"># squash the live rootfs and clean up workdir</span>
<span class="n">imgutils</span><span class="o">.</span><span class="n">mksquashfs</span><span class="p">(</span><span class="n">workdir</span><span class="p">,</span> <span class="n">outfile</span><span class="p">,</span> <span class="n">compression</span><span class="p">,</span> <span class="n">compressargs</span><span class="p">)</span>
<span class="n">remove</span><span class="p">(</span><span class="n">workdir</span><span class="p">)</span>
</div></div>
<div class="viewcode-block" id="TreeBuilder"><a class="viewcode-back" href="../../pylorax.html#pylorax.treebuilder.TreeBuilder">[docs]</a><span class="k">class</span> <span class="nc">TreeBuilder</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;Builds the arch-specific boot images.</span>
<span class="sd"> inroot should be the installtree root (the newly-built runtime dir)&#39;&#39;&#39;</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">product</span><span class="p">,</span> <span class="n">arch</span><span class="p">,</span> <span class="n">inroot</span><span class="p">,</span> <span class="n">outroot</span><span class="p">,</span> <span class="n">runtime</span><span class="p">,</span> <span class="n">isolabel</span><span class="p">,</span> <span class="n">domacboot</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">doupgrade</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span> <span class="n">templatedir</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">add_templates</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">add_template_vars</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">workdir</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
<span class="c"># NOTE: if you pass an arg named &quot;runtime&quot; to a mako template it&#39;ll</span>
<span class="c"># clobber some mako internal variables - hence &quot;runtime_img&quot;.</span>
<span class="bp">self</span><span class="o">.</span><span class="n">vars</span> <span class="o">=</span> <span class="n">DataHolder</span><span class="p">(</span><span class="n">arch</span><span class="o">=</span><span class="n">arch</span><span class="p">,</span> <span class="n">product</span><span class="o">=</span><span class="n">product</span><span class="p">,</span> <span class="n">runtime_img</span><span class="o">=</span><span class="n">runtime</span><span class="p">,</span>
<span class="n">runtime_base</span><span class="o">=</span><span class="n">basename</span><span class="p">(</span><span class="n">runtime</span><span class="p">),</span>
<span class="n">inroot</span><span class="o">=</span><span class="n">inroot</span><span class="p">,</span> <span class="n">outroot</span><span class="o">=</span><span class="n">outroot</span><span class="p">,</span>
<span class="n">basearch</span><span class="o">=</span><span class="n">arch</span><span class="o">.</span><span class="n">basearch</span><span class="p">,</span> <span class="n">libdir</span><span class="o">=</span><span class="n">arch</span><span class="o">.</span><span class="n">libdir</span><span class="p">,</span>
<span class="n">isolabel</span><span class="o">=</span><span class="n">isolabel</span><span class="p">,</span> <span class="n">udev</span><span class="o">=</span><span class="n">udev_escape</span><span class="p">,</span> <span class="n">domacboot</span><span class="o">=</span><span class="n">domacboot</span><span class="p">,</span> <span class="n">doupgrade</span><span class="o">=</span><span class="n">doupgrade</span><span class="p">,</span>
<span class="n">workdir</span><span class="o">=</span><span class="n">workdir</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_runner</span> <span class="o">=</span> <span class="n">LoraxTemplateRunner</span><span class="p">(</span><span class="n">inroot</span><span class="p">,</span> <span class="n">outroot</span><span class="p">,</span> <span class="n">templatedir</span><span class="o">=</span><span class="n">templatedir</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_runner</span><span class="o">.</span><span class="n">defaults</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">vars</span>
<span class="bp">self</span><span class="o">.</span><span class="n">add_templates</span> <span class="o">=</span> <span class="n">add_templates</span> <span class="ow">or</span> <span class="p">[]</span>
<span class="bp">self</span><span class="o">.</span><span class="n">add_template_vars</span> <span class="o">=</span> <span class="n">add_template_vars</span> <span class="ow">or</span> <span class="p">{}</span>
<span class="bp">self</span><span class="o">.</span><span class="n">templatedir</span> <span class="o">=</span> <span class="n">templatedir</span>
<span class="bp">self</span><span class="o">.</span><span class="n">treeinfo_data</span> <span class="o">=</span> <span class="bp">None</span>
<span class="nd">@property</span>
<div class="viewcode-block" id="TreeBuilder.kernels"><a class="viewcode-back" href="../../pylorax.html#pylorax.treebuilder.TreeBuilder.kernels">[docs]</a> <span class="k">def</span> <span class="nf">kernels</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="n">findkernels</span><span class="p">(</span><span class="n">root</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">vars</span><span class="o">.</span><span class="n">inroot</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="TreeBuilder.rebuild_initrds"><a class="viewcode-back" href="../../pylorax.html#pylorax.treebuilder.TreeBuilder.rebuild_initrds">[docs]</a> <span class="k">def</span> <span class="nf">rebuild_initrds</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">add_args</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">backup</span><span class="o">=</span><span class="s">&quot;&quot;</span><span class="p">,</span> <span class="n">prefix</span><span class="o">=</span><span class="s">&quot;&quot;</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;Rebuild all the initrds in the tree. If backup is specified, each</span>
<span class="sd"> initrd will be renamed with backup as a suffix before rebuilding.</span>
<span class="sd"> If backup is empty, the existing initrd files will be overwritten.</span>
<span class="sd"> If suffix is specified, the existing initrd is untouched and a new</span>
<span class="sd"> image is built with the filename &quot;${prefix}-${kernel.version}.img&quot;</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">if</span> <span class="n">add_args</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span>
<span class="n">add_args</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">dracut</span> <span class="o">=</span> <span class="p">[</span><span class="s">&quot;dracut&quot;</span><span class="p">,</span> <span class="s">&quot;--nomdadmconf&quot;</span><span class="p">,</span> <span class="s">&quot;--nolvmconf&quot;</span><span class="p">]</span> <span class="o">+</span> <span class="n">add_args</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">backup</span><span class="p">:</span>
<span class="n">dracut</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s">&quot;--force&quot;</span><span class="p">)</span>
<span class="n">kernels</span> <span class="o">=</span> <span class="p">[</span><span class="n">kernel</span> <span class="k">for</span> <span class="n">kernel</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">kernels</span> <span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">kernel</span><span class="p">,</span> <span class="s">&quot;initrd&quot;</span><span class="p">)]</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">kernels</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="s">&quot;No initrds found, cannot rebuild_initrds&quot;</span><span class="p">)</span>
<span class="c"># Hush some dracut warnings. TODO: bind-mount proc in place?</span>
<span class="nb">open</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">vars</span><span class="o">.</span><span class="n">inroot</span><span class="p">,</span><span class="s">&quot;/proc/modules&quot;</span><span class="p">),</span><span class="s">&quot;w&quot;</span><span class="p">)</span>
<span class="k">for</span> <span class="n">kernel</span> <span class="ow">in</span> <span class="n">kernels</span><span class="p">:</span>
<span class="k">if</span> <span class="n">prefix</span><span class="p">:</span>
<span class="n">idir</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">dirname</span><span class="p">(</span><span class="n">kernel</span><span class="o">.</span><span class="n">initrd</span><span class="o">.</span><span class="n">path</span><span class="p">)</span>
<span class="n">outfile</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">idir</span><span class="p">,</span> <span class="n">prefix</span><span class="o">+</span><span class="s">&#39;-&#39;</span><span class="o">+</span><span class="n">kernel</span><span class="o">.</span><span class="n">version</span><span class="o">+</span><span class="s">&#39;.img&#39;</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">outfile</span> <span class="o">=</span> <span class="n">kernel</span><span class="o">.</span><span class="n">initrd</span><span class="o">.</span><span class="n">path</span>
<span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;rebuilding </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">outfile</span><span class="p">)</span>
<span class="k">if</span> <span class="n">backup</span><span class="p">:</span>
<span class="n">initrd</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">vars</span><span class="o">.</span><span class="n">inroot</span><span class="p">,</span> <span class="n">outfile</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">rename</span><span class="p">(</span><span class="n">initrd</span><span class="p">,</span> <span class="n">initrd</span> <span class="o">+</span> <span class="n">backup</span><span class="p">)</span>
<span class="n">cmd</span> <span class="o">=</span> <span class="n">dracut</span> <span class="o">+</span> <span class="p">[</span><span class="n">outfile</span><span class="p">,</span> <span class="n">kernel</span><span class="o">.</span><span class="n">version</span><span class="p">]</span>
<span class="n">runcmd</span><span class="p">(</span><span class="n">cmd</span><span class="p">,</span> <span class="n">root</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">vars</span><span class="o">.</span><span class="n">inroot</span><span class="p">)</span>
<span class="c"># ppc64 cannot boot images &gt; 32MiB, check size and warn</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">vars</span><span class="o">.</span><span class="n">arch</span><span class="o">.</span><span class="n">basearch</span> <span class="ow">in</span> <span class="p">(</span><span class="s">&quot;ppc64&quot;</span><span class="p">,</span> <span class="s">&quot;ppc64le&quot;</span><span class="p">)</span> <span class="ow">and</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">outfile</span><span class="p">):</span>
<span class="n">st</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">stat</span><span class="p">(</span><span class="n">outfile</span><span class="p">)</span>
<span class="k">if</span> <span class="n">st</span><span class="o">.</span><span class="n">st_size</span> <span class="o">&gt;</span> <span class="mi">32</span> <span class="o">*</span> <span class="mi">1024</span> <span class="o">*</span> <span class="mi">1024</span><span class="p">:</span>
<span class="n">logging</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="s">&quot;ppc64 initrd </span><span class="si">%s</span><span class="s"> is &gt; 32MiB&quot;</span><span class="p">,</span> <span class="n">outfile</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">joinpaths</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">vars</span><span class="o">.</span><span class="n">inroot</span><span class="p">,</span><span class="s">&quot;/proc/modules&quot;</span><span class="p">))</span>
</div>
<div class="viewcode-block" id="TreeBuilder.build"><a class="viewcode-back" href="../../pylorax.html#pylorax.treebuilder.TreeBuilder.build">[docs]</a> <span class="k">def</span> <span class="nf">build</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="n">templatefile</span> <span class="o">=</span> <span class="n">templatemap</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">vars</span><span class="o">.</span><span class="n">arch</span><span class="o">.</span><span class="n">basearch</span><span class="p">]</span>
<span class="k">for</span> <span class="n">tmpl</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">add_templates</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_runner</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="n">tmpl</span><span class="p">,</span> <span class="o">**</span><span class="bp">self</span><span class="o">.</span><span class="n">add_template_vars</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_runner</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="n">templatefile</span><span class="p">,</span> <span class="n">kernels</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">kernels</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">treeinfo_data</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_runner</span><span class="o">.</span><span class="n">results</span><span class="o">.</span><span class="n">treeinfo</span>
<span class="bp">self</span><span class="o">.</span><span class="n">implantisomd5</span><span class="p">()</span>
</div>
<div class="viewcode-block" id="TreeBuilder.implantisomd5"><a class="viewcode-back" href="../../pylorax.html#pylorax.treebuilder.TreeBuilder.implantisomd5">[docs]</a> <span class="k">def</span> <span class="nf">implantisomd5</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">for</span> <span class="n">_section</span><span class="p">,</span> <span class="n">data</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">treeinfo_data</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
<span class="k">if</span> <span class="s">&#39;boot.iso&#39;</span> <span class="ow">in</span> <span class="n">data</span><span class="p">:</span>
<span class="n">iso</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">vars</span><span class="o">.</span><span class="n">outroot</span><span class="p">,</span> <span class="n">data</span><span class="p">[</span><span class="s">&#39;boot.iso&#39;</span><span class="p">])</span>
<span class="n">runcmd</span><span class="p">([</span><span class="s">&quot;implantisomd5&quot;</span><span class="p">,</span> <span class="n">iso</span><span class="p">])</span>
</div>
<span class="nd">@property</span>
<div class="viewcode-block" id="TreeBuilder.dracut_hooks_path"><a class="viewcode-back" href="../../pylorax.html#pylorax.treebuilder.TreeBuilder.dracut_hooks_path">[docs]</a> <span class="k">def</span> <span class="nf">dracut_hooks_path</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot; Return the path to the lorax dracut hooks scripts</span>
<span class="sd"> Use the configured share dir if it is setup,</span>
<span class="sd"> otherwise default to /usr/share/lorax/dracut_hooks</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">templatedir</span><span class="p">:</span>
<span class="k">return</span> <span class="n">joinpaths</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">templatedir</span><span class="p">,</span> <span class="s">&quot;dracut_hooks&quot;</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="s">&quot;/usr/share/lorax/dracut_hooks&quot;</span>
</div>
<div class="viewcode-block" id="TreeBuilder.copy_dracut_hooks"><a class="viewcode-back" href="../../pylorax.html#pylorax.treebuilder.TreeBuilder.copy_dracut_hooks">[docs]</a> <span class="k">def</span> <span class="nf">copy_dracut_hooks</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">hooks</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot; Copy the hook scripts in hooks into the installroot&#39;s /tmp/</span>
<span class="sd"> and return a list of commands to pass to dracut when creating the</span>
<span class="sd"> initramfs</span>
<span class="sd"> hooks is a list of tuples with the name of the hook script and the</span>
<span class="sd"> target dracut hook directory</span>
<span class="sd"> (eg. [(&quot;99anaconda-copy-ks.sh&quot;, &quot;/lib/dracut/hooks/pre-pivot&quot;)])</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">dracut_commands</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">hook_script</span><span class="p">,</span> <span class="n">dracut_path</span> <span class="ow">in</span> <span class="n">hooks</span><span class="p">:</span>
<span class="n">src</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">dracut_hooks_path</span><span class="p">,</span> <span class="n">hook_script</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">src</span><span class="p">):</span>
<span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s">&quot;Missing lorax dracut hook script </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">src</span><span class="p">)</span>
<span class="k">continue</span>
<span class="n">dst</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">vars</span><span class="o">.</span><span class="n">inroot</span><span class="p">,</span> <span class="s">&quot;/tmp/&quot;</span><span class="p">,</span> <span class="n">hook_script</span><span class="p">)</span>
<span class="n">copy2</span><span class="p">(</span><span class="n">src</span><span class="p">,</span> <span class="n">dst</span><span class="p">)</span>
<span class="n">dracut_commands</span> <span class="o">+=</span> <span class="p">[</span><span class="s">&quot;--include&quot;</span><span class="p">,</span> <span class="n">joinpaths</span><span class="p">(</span><span class="s">&quot;/tmp/&quot;</span><span class="p">,</span> <span class="n">hook_script</span><span class="p">),</span>
<span class="n">dracut_path</span><span class="p">]</span>
<span class="k">return</span> <span class="n">dracut_commands</span>
<span class="c">#### TreeBuilder helper functions</span>
</div></div>
<div class="viewcode-block" id="findkernels"><a class="viewcode-back" href="../../pylorax.html#pylorax.treebuilder.findkernels">[docs]</a><span class="k">def</span> <span class="nf">findkernels</span><span class="p">(</span><span class="n">root</span><span class="o">=</span><span class="s">&quot;/&quot;</span><span class="p">,</span> <span class="n">kdir</span><span class="o">=</span><span class="s">&quot;boot&quot;</span><span class="p">):</span>
<span class="c"># To find possible flavors, awk &#39;/BuildKernel/ { print $4 }&#39; kernel.spec</span>
<span class="n">flavors</span> <span class="o">=</span> <span class="p">(</span><span class="s">&#39;debug&#39;</span><span class="p">,</span> <span class="s">&#39;PAE&#39;</span><span class="p">,</span> <span class="s">&#39;PAEdebug&#39;</span><span class="p">,</span> <span class="s">&#39;smp&#39;</span><span class="p">,</span> <span class="s">&#39;xen&#39;</span><span class="p">,</span> <span class="s">&#39;lpae&#39;</span><span class="p">,</span> <span class="s">&#39;tegra&#39;</span><span class="p">)</span>
<span class="n">kre</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="s">r&quot;vmlinuz-(?P&lt;version&gt;.+?\.(?P&lt;arch&gt;[a-z0-9_]+)&quot;</span>
<span class="s">r&quot;(\.(?P&lt;flavor&gt;{0}))?)$&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="s">&quot;|&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">flavors</span><span class="p">)))</span>
<span class="n">kernels</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">bootfiles</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">listdir</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">root</span><span class="p">,</span> <span class="n">kdir</span><span class="p">))</span>
<span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">bootfiles</span><span class="p">:</span>
<span class="n">match</span> <span class="o">=</span> <span class="n">kre</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
<span class="k">if</span> <span class="n">match</span><span class="p">:</span>
<span class="n">kernel</span> <span class="o">=</span> <span class="n">DataHolder</span><span class="p">(</span><span class="n">path</span><span class="o">=</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">kdir</span><span class="p">,</span> <span class="n">f</span><span class="p">))</span>
<span class="n">kernel</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">match</span><span class="o">.</span><span class="n">groupdict</span><span class="p">())</span> <span class="c"># sets version, arch, flavor</span>
<span class="n">kernels</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">kernel</span><span class="p">)</span>
<span class="c"># look for associated initrd/initramfs/etc.</span>
<span class="k">for</span> <span class="n">kernel</span> <span class="ow">in</span> <span class="n">kernels</span><span class="p">:</span>
<span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">bootfiles</span><span class="p">:</span>
<span class="k">if</span> <span class="n">f</span><span class="o">.</span><span class="n">endswith</span><span class="p">(</span><span class="s">&#39;-&#39;</span><span class="o">+</span><span class="n">kernel</span><span class="o">.</span><span class="n">version</span><span class="o">+</span><span class="s">&#39;.img&#39;</span><span class="p">):</span>
<span class="n">imgtype</span><span class="p">,</span> <span class="n">_rest</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">&#39;-&#39;</span><span class="p">,</span><span class="mi">1</span><span class="p">)</span>
<span class="c"># special backwards-compat case</span>
<span class="k">if</span> <span class="n">imgtype</span> <span class="o">==</span> <span class="s">&#39;initramfs&#39;</span><span class="p">:</span>
<span class="n">imgtype</span> <span class="o">=</span> <span class="s">&#39;initrd&#39;</span>
<span class="n">kernel</span><span class="p">[</span><span class="n">imgtype</span><span class="p">]</span> <span class="o">=</span> <span class="n">DataHolder</span><span class="p">(</span><span class="n">path</span><span class="o">=</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">kdir</span><span class="p">,</span> <span class="n">f</span><span class="p">))</span>
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">&quot;kernels=</span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">kernels</span><span class="p">)</span>
<span class="k">return</span> <span class="n">kernels</span>
<span class="c"># udev whitelist: &#39;a-zA-Z0-9#+.:=@_-&#39; (see is_whitelisted in libudev-util.c)</span></div>
<span class="n">udev_blacklist</span><span class="o">=</span><span class="s">&#39; !&quot;$%&amp;</span><span class="se">\&#39;</span><span class="s">()*,/;&lt;&gt;?[</span><span class="se">\\</span><span class="s">]^`{|}~&#39;</span> <span class="c"># ASCII printable, minus whitelist</span>
<span class="n">udev_blacklist</span> <span class="o">+=</span> <span class="s">&#39;&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="nb">chr</span><span class="p">(</span><span class="n">i</span><span class="p">)</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">32</span><span class="p">))</span> <span class="c"># ASCII non-printable</span>
<div class="viewcode-block" id="udev_escape"><a class="viewcode-back" href="../../pylorax.html#pylorax.treebuilder.udev_escape">[docs]</a><span class="k">def</span> <span class="nf">udev_escape</span><span class="p">(</span><span class="n">label</span><span class="p">):</span>
<span class="n">out</span> <span class="o">=</span> <span class="s">u&#39;&#39;</span>
<span class="k">for</span> <span class="n">ch</span> <span class="ow">in</span> <span class="n">label</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s">&#39;utf8&#39;</span><span class="p">):</span>
<span class="n">out</span> <span class="o">+=</span> <span class="n">ch</span> <span class="k">if</span> <span class="n">ch</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">udev_blacklist</span> <span class="k">else</span> <span class="s">u&#39;</span><span class="se">\\</span><span class="s">x</span><span class="si">%02x</span><span class="s">&#39;</span> <span class="o">%</span> <span class="nb">ord</span><span class="p">(</span><span class="n">ch</span><span class="p">)</span>
<span class="k">return</span> <span class="n">out</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s">&#39;utf8&#39;</span><span class="p">)</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">Lorax 19.7.10 documentation</a> &raquo;</li>
<li><a href="../index.html" >Module code</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2017, Red Hat, Inc..
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>

View File

@ -0,0 +1,151 @@
<!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>pylorax.treeinfo &mdash; Lorax 19.7.10 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: '19.7.10',
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>
<link rel="top" title="Lorax 19.7.10 documentation" href="../../index.html" />
<link rel="up" title="Module code" href="../index.html" />
</head>
<body>
<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">Lorax 19.7.10 documentation</a> &raquo;</li>
<li><a href="../index.html" accesskey="U">Module code</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<h1>Source code for pylorax.treeinfo</h1><div class="highlight"><pre>
<span class="c">#</span>
<span class="c"># treeinfo.py</span>
<span class="c">#</span>
<span class="c"># Copyright (C) 2010 Red Hat, Inc.</span>
<span class="c">#</span>
<span class="c"># This program is free software; you can redistribute it and/or modify</span>
<span class="c"># it under the terms of the GNU General Public License as published by</span>
<span class="c"># the Free Software Foundation; either version 2 of the License, or</span>
<span class="c"># (at your option) any later version.</span>
<span class="c">#</span>
<span class="c"># This program is distributed in the hope that it will be useful,</span>
<span class="c"># but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<span class="c"># MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span>
<span class="c"># GNU General Public License for more details.</span>
<span class="c">#</span>
<span class="c"># You should have received a copy of the GNU General Public License</span>
<span class="c"># along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;.</span>
<span class="c">#</span>
<span class="c"># Red Hat Author(s): Martin Gracik &lt;mgracik@redhat.com&gt;</span>
<span class="c">#</span>
<span class="kn">import</span> <span class="nn">logging</span>
<span class="n">logger</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s">&quot;pylorax.treeinfo&quot;</span><span class="p">)</span>
<span class="kn">import</span> <span class="nn">ConfigParser</span>
<span class="kn">import</span> <span class="nn">time</span>
<div class="viewcode-block" id="TreeInfo"><a class="viewcode-back" href="../../pylorax.html#pylorax.treeinfo.TreeInfo">[docs]</a><span class="k">class</span> <span class="nc">TreeInfo</span><span class="p">(</span><span class="nb">object</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">product</span><span class="p">,</span> <span class="n">version</span><span class="p">,</span> <span class="n">variant</span><span class="p">,</span> <span class="n">basearch</span><span class="p">,</span>
<span class="n">packagedir</span><span class="o">=</span><span class="s">&quot;&quot;</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">c</span> <span class="o">=</span> <span class="n">ConfigParser</span><span class="o">.</span><span class="n">ConfigParser</span><span class="p">()</span>
<span class="n">section</span> <span class="o">=</span> <span class="s">&quot;general&quot;</span>
<span class="n">data</span> <span class="o">=</span> <span class="p">{</span><span class="s">&quot;timestamp&quot;</span><span class="p">:</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">(),</span>
<span class="s">&quot;family&quot;</span><span class="p">:</span> <span class="n">product</span><span class="p">,</span>
<span class="s">&quot;version&quot;</span><span class="p">:</span> <span class="n">version</span><span class="p">,</span>
<span class="s">&quot;name&quot;</span><span class="p">:</span> <span class="s">&quot;</span><span class="si">%s</span><span class="s">-</span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">product</span><span class="p">,</span> <span class="n">version</span><span class="p">),</span>
<span class="s">&quot;variant&quot;</span><span class="p">:</span> <span class="n">variant</span> <span class="ow">or</span> <span class="s">&quot;&quot;</span><span class="p">,</span>
<span class="s">&quot;arch&quot;</span><span class="p">:</span> <span class="n">basearch</span><span class="p">,</span>
<span class="s">&quot;packagedir&quot;</span><span class="p">:</span> <span class="n">packagedir</span><span class="p">}</span>
<span class="bp">self</span><span class="o">.</span><span class="n">c</span><span class="o">.</span><span class="n">add_section</span><span class="p">(</span><span class="n">section</span><span class="p">)</span>
<span class="nb">map</span><span class="p">(</span><span class="k">lambda</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="bp">self</span><span class="o">.</span><span class="n">c</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="n">section</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="n">data</span><span class="o">.</span><span class="n">items</span><span class="p">())</span>
<div class="viewcode-block" id="TreeInfo.add_section"><a class="viewcode-back" href="../../pylorax.html#pylorax.treeinfo.TreeInfo.add_section">[docs]</a> <span class="k">def</span> <span class="nf">add_section</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">section</span><span class="p">,</span> <span class="n">data</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">c</span><span class="o">.</span><span class="n">has_section</span><span class="p">(</span><span class="n">section</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">c</span><span class="o">.</span><span class="n">add_section</span><span class="p">(</span><span class="n">section</span><span class="p">)</span>
<span class="nb">map</span><span class="p">(</span><span class="k">lambda</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="bp">self</span><span class="o">.</span><span class="n">c</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="n">section</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="n">data</span><span class="o">.</span><span class="n">items</span><span class="p">())</span>
</div>
<div class="viewcode-block" id="TreeInfo.write"><a class="viewcode-back" href="../../pylorax.html#pylorax.treeinfo.TreeInfo.write">[docs]</a> <span class="k">def</span> <span class="nf">write</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">outfile</span><span class="p">):</span>
<span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;writing .treeinfo file&quot;</span><span class="p">)</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">outfile</span><span class="p">,</span> <span class="s">&quot;w&quot;</span><span class="p">)</span> <span class="k">as</span> <span class="n">fobj</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">c</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">fobj</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">Lorax 19.7.10 documentation</a> &raquo;</li>
<li><a href="../index.html" >Module code</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2017, Red Hat, Inc..
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>

View File

@ -0,0 +1,219 @@
<!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>pylorax.yumhelper &mdash; Lorax 19.7.10 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: '19.7.10',
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>
<link rel="top" title="Lorax 19.7.10 documentation" href="../../index.html" />
<link rel="up" title="Module code" href="../index.html" />
</head>
<body>
<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">Lorax 19.7.10 documentation</a> &raquo;</li>
<li><a href="../index.html" accesskey="U">Module code</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<h1>Source code for pylorax.yumhelper</h1><div class="highlight"><pre>
<span class="c">#</span>
<span class="c"># yumhelper.py</span>
<span class="c">#</span>
<span class="c"># Copyright (C) 2010 Red Hat, Inc.</span>
<span class="c">#</span>
<span class="c"># This program is free software; you can redistribute it and/or modify</span>
<span class="c"># it under the terms of the GNU General Public License as published by</span>
<span class="c"># the Free Software Foundation; either version 2 of the License, or</span>
<span class="c"># (at your option) any later version.</span>
<span class="c">#</span>
<span class="c"># This program is distributed in the hope that it will be useful,</span>
<span class="c"># but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<span class="c"># MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span>
<span class="c"># GNU General Public License for more details.</span>
<span class="c">#</span>
<span class="c"># You should have received a copy of the GNU General Public License</span>
<span class="c"># along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;.</span>
<span class="c">#</span>
<span class="c"># Red Hat Author(s): Martin Gracik &lt;mgracik@redhat.com&gt;</span>
<span class="c">#</span>
<span class="kn">import</span> <span class="nn">logging</span>
<span class="n">logger</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s">&quot;pylorax.yumhelper&quot;</span><span class="p">)</span>
<span class="kn">import</span> <span class="nn">re</span>
<span class="kn">import</span> <span class="nn">yum</span><span class="o">,</span> <span class="nn">yum.callbacks</span><span class="o">,</span> <span class="nn">yum.rpmtrans</span>
<span class="kn">import</span> <span class="nn">pylorax.output</span> <span class="kn">as</span> <span class="nn">output</span>
<span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span><span class="s">&#39;LoraxDownloadCallback&#39;</span><span class="p">,</span> <span class="s">&#39;LoraxTransactionCallback&#39;</span><span class="p">,</span>
<span class="s">&#39;LoraxRpmCallback&#39;</span><span class="p">]</span>
<div class="viewcode-block" id="LoraxDownloadCallback"><a class="viewcode-back" href="../../pylorax.html#pylorax.yumhelper.LoraxDownloadCallback">[docs]</a><span class="k">class</span> <span class="nc">LoraxDownloadCallback</span><span class="p">(</span><span class="n">yum</span><span class="o">.</span><span class="n">callbacks</span><span class="o">.</span><span class="n">DownloadBaseCallback</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">yum</span><span class="o">.</span><span class="n">callbacks</span><span class="o">.</span><span class="n">DownloadBaseCallback</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="bp">self</span><span class="o">.</span><span class="n">output</span> <span class="o">=</span> <span class="n">output</span><span class="o">.</span><span class="n">LoraxOutput</span><span class="p">()</span>
<span class="n">pattern</span> <span class="o">=</span> <span class="s">r&quot;\((?P&lt;pkgno&gt;\d+)/(?P&lt;total&gt;\d+)\):\s+(?P&lt;pkgname&gt;.*)&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">pattern</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="n">pattern</span><span class="p">)</span>
<div class="viewcode-block" id="LoraxDownloadCallback.updateProgress"><a class="viewcode-back" href="../../pylorax.html#pylorax.yumhelper.LoraxDownloadCallback.updateProgress">[docs]</a> <span class="k">def</span> <span class="nf">updateProgress</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">frac</span><span class="p">,</span> <span class="n">fread</span><span class="p">,</span> <span class="n">ftime</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Update the progress bar</span>
<span class="sd"> @param name: filename</span>
<span class="sd"> @param frac: progress fraction (0 -&gt; 1)</span>
<span class="sd"> @param fread: formated string containing BytesRead</span>
<span class="sd"> @param ftime: formated string containing remaining or elapsed time</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">match</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">pattern</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
<span class="n">pkgno</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">total</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">pkgname</span> <span class="o">=</span> <span class="n">name</span>
<span class="k">if</span> <span class="n">match</span><span class="p">:</span>
<span class="n">pkgno</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">match</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="s">&quot;pkgno&quot;</span><span class="p">))</span>
<span class="n">total</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">match</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="s">&quot;total&quot;</span><span class="p">))</span>
<span class="n">pkgname</span> <span class="o">=</span> <span class="n">match</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="s">&quot;pkgname&quot;</span><span class="p">)</span>
<span class="n">info</span> <span class="o">=</span> <span class="s">&quot;({0:3d}/{1:3d}) [{2:3.0f}%] downloading &quot;</span>
<span class="n">info</span> <span class="o">=</span> <span class="n">info</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">pkgno</span><span class="p">,</span> <span class="n">total</span><span class="p">,</span> <span class="n">frac</span> <span class="o">*</span> <span class="mi">100</span><span class="p">)</span>
<span class="n">infolen</span><span class="p">,</span> <span class="n">pkglen</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">info</span><span class="p">),</span> <span class="nb">len</span><span class="p">(</span><span class="n">pkgname</span><span class="p">)</span>
<span class="k">if</span> <span class="p">(</span><span class="n">infolen</span> <span class="o">+</span> <span class="n">pkglen</span><span class="p">)</span> <span class="o">&gt;</span> <span class="bp">self</span><span class="o">.</span><span class="n">output</span><span class="o">.</span><span class="n">width</span><span class="p">:</span>
<span class="n">pkgname</span> <span class="o">=</span> <span class="s">&quot;{0}...&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">pkgname</span><span class="p">[:</span><span class="bp">self</span><span class="o">.</span><span class="n">output</span><span class="o">.</span><span class="n">width</span><span class="o">-</span><span class="n">infolen</span><span class="o">-</span><span class="mi">3</span><span class="p">])</span>
<span class="n">msg</span> <span class="o">=</span> <span class="s">&quot;{0}&lt;b&gt;{1}&lt;/b&gt;</span><span class="se">\r</span><span class="s">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">info</span><span class="p">,</span> <span class="n">pkgname</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">output</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
<span class="k">if</span> <span class="n">frac</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">output</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">&quot;</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">)</span>
</div></div>
<div class="viewcode-block" id="LoraxTransactionCallback"><a class="viewcode-back" href="../../pylorax.html#pylorax.yumhelper.LoraxTransactionCallback">[docs]</a><span class="k">class</span> <span class="nc">LoraxTransactionCallback</span><span class="p">(</span><span class="nb">object</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="bp">self</span><span class="o">.</span><span class="n">output</span> <span class="o">=</span> <span class="n">output</span><span class="o">.</span><span class="n">LoraxOutput</span><span class="p">()</span>
<div class="viewcode-block" id="LoraxTransactionCallback.event"><a class="viewcode-back" href="../../pylorax.html#pylorax.yumhelper.LoraxTransactionCallback.event">[docs]</a> <span class="k">def</span> <span class="nf">event</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">state</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
<span class="k">if</span> <span class="n">state</span> <span class="o">==</span> <span class="n">yum</span><span class="o">.</span><span class="n">callbacks</span><span class="o">.</span><span class="n">PT_DOWNLOAD</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">output</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">&quot;downloading packages</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">state</span> <span class="o">==</span> <span class="n">yum</span><span class="o">.</span><span class="n">callbacks</span><span class="o">.</span><span class="n">PT_DOWNLOAD_PKGS</span><span class="p">:</span>
<span class="k">pass</span>
<span class="k">elif</span> <span class="n">state</span> <span class="o">==</span> <span class="n">yum</span><span class="o">.</span><span class="n">callbacks</span><span class="o">.</span><span class="n">PT_GPGCHECK</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">output</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">&quot;checking package signatures</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">state</span> <span class="o">==</span> <span class="n">yum</span><span class="o">.</span><span class="n">callbacks</span><span class="o">.</span><span class="n">PT_TEST_TRANS</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">output</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">&quot;running test transaction</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">state</span> <span class="o">==</span> <span class="n">yum</span><span class="o">.</span><span class="n">callbacks</span><span class="o">.</span><span class="n">PT_TRANSACTION</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">output</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">&quot;running transaction</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">)</span>
</div></div>
<div class="viewcode-block" id="LoraxRpmCallback"><a class="viewcode-back" href="../../pylorax.html#pylorax.yumhelper.LoraxRpmCallback">[docs]</a><span class="k">class</span> <span class="nc">LoraxRpmCallback</span><span class="p">(</span><span class="n">yum</span><span class="o">.</span><span class="n">rpmtrans</span><span class="o">.</span><span class="n">RPMBaseCallback</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">yum</span><span class="o">.</span><span class="n">rpmtrans</span><span class="o">.</span><span class="n">RPMBaseCallback</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="bp">self</span><span class="o">.</span><span class="n">output</span> <span class="o">=</span> <span class="n">output</span><span class="o">.</span><span class="n">LoraxOutput</span><span class="p">()</span>
<div class="viewcode-block" id="LoraxRpmCallback.event"><a class="viewcode-back" href="../../pylorax.html#pylorax.yumhelper.LoraxRpmCallback.event">[docs]</a> <span class="k">def</span> <span class="nf">event</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="n">action</span><span class="p">,</span> <span class="n">te_current</span><span class="p">,</span> <span class="n">te_total</span><span class="p">,</span>
<span class="n">ts_current</span><span class="p">,</span> <span class="n">ts_total</span><span class="p">):</span>
<span class="n">action_str</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">action</span><span class="p">[</span><span class="n">action</span><span class="p">]</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s">&quot;utf-8&quot;</span><span class="p">)</span>
<span class="n">info</span> <span class="o">=</span> <span class="s">&quot;({0:3d}/{1:3d}) [{2:3.0f}%] {3} &quot;</span>
<span class="n">info</span> <span class="o">=</span> <span class="n">info</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">ts_current</span><span class="p">,</span> <span class="n">ts_total</span><span class="p">,</span>
<span class="nb">float</span><span class="p">(</span><span class="n">te_current</span><span class="p">)</span> <span class="o">/</span> <span class="nb">float</span><span class="p">(</span><span class="n">te_total</span><span class="p">)</span> <span class="o">*</span> <span class="mi">100</span><span class="p">,</span>
<span class="n">action_str</span><span class="o">.</span><span class="n">lower</span><span class="p">())</span>
<span class="n">pkg</span> <span class="o">=</span> <span class="s">&quot;{0}&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">package</span><span class="p">)</span>
<span class="n">infolen</span><span class="p">,</span> <span class="n">pkglen</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">info</span><span class="p">),</span> <span class="nb">len</span><span class="p">(</span><span class="n">pkg</span><span class="p">)</span>
<span class="k">if</span> <span class="p">(</span><span class="n">infolen</span> <span class="o">+</span> <span class="n">pkglen</span><span class="p">)</span> <span class="o">&gt;</span> <span class="bp">self</span><span class="o">.</span><span class="n">output</span><span class="o">.</span><span class="n">width</span><span class="p">:</span>
<span class="n">pkg</span> <span class="o">=</span> <span class="s">&quot;{0}...&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">pkg</span><span class="p">[:</span><span class="bp">self</span><span class="o">.</span><span class="n">output</span><span class="o">.</span><span class="n">width</span><span class="o">-</span><span class="n">infolen</span><span class="o">-</span><span class="mi">3</span><span class="p">])</span>
<span class="n">msg</span> <span class="o">=</span> <span class="s">&quot;{0}&lt;b&gt;{1}&lt;/b&gt;</span><span class="se">\r</span><span class="s">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">info</span><span class="p">,</span> <span class="n">pkg</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">output</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
<span class="k">if</span> <span class="n">te_current</span> <span class="o">==</span> <span class="n">te_total</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">output</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">&quot;</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="LoraxRpmCallback.filelog"><a class="viewcode-back" href="../../pylorax.html#pylorax.yumhelper.LoraxRpmCallback.filelog">[docs]</a> <span class="k">def</span> <span class="nf">filelog</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="n">action</span><span class="p">):</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">fileaction</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">action</span><span class="p">)</span> <span class="o">==</span> <span class="s">&quot;Installed&quot;</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">&quot;</span><span class="si">%s</span><span class="s"> installed successfully&quot;</span><span class="p">,</span> <span class="n">package</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="LoraxRpmCallback.errorlog"><a class="viewcode-back" href="../../pylorax.html#pylorax.yumhelper.LoraxRpmCallback.errorlog">[docs]</a> <span class="k">def</span> <span class="nf">errorlog</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">msg</span><span class="p">):</span>
<span class="n">logger</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="s">&quot;RPM transaction error: </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">msg</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="LoraxRpmCallback.scriptout"><a class="viewcode-back" href="../../pylorax.html#pylorax.yumhelper.LoraxRpmCallback.scriptout">[docs]</a> <span class="k">def</span> <span class="nf">scriptout</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="n">msgs</span><span class="p">):</span>
<span class="k">if</span> <span class="n">msgs</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;</span><span class="si">%s</span><span class="s"> scriptlet output:</span><span class="se">\n</span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">package</span><span class="p">,</span> <span class="n">msgs</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">Lorax 19.7.10 documentation</a> &raquo;</li>
<li><a href="../index.html" >Module code</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2017, Red Hat, Inc..
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>

View File

@ -0,0 +1,28 @@
.. Lorax documentation master file, created by
sphinx-quickstart on Wed Apr 8 13:46:00 2015.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Welcome to Lorax's documentation!
=================================
Contents:
.. toctree::
:maxdepth: 1
intro
lorax
livemedia-creator
lorax-composer
product-images
modules
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

View File

@ -0,0 +1,28 @@
.. Lorax documentation master file, created by
sphinx-quickstart on Wed Apr 8 13:46:00 2015.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Welcome to Lorax's documentation!
=================================
Contents:
.. toctree::
:maxdepth: 1
intro
lorax
livemedia-creator
lorax-composer
product-images
modules
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

View File

@ -0,0 +1,67 @@
Introduction to Lorax
=====================
I am the Lorax. I speak for the trees [and images].
Lorax is used to build the Anaconda Installer boot.iso, it consists of a
library, pylorax, a set of templates, and the lorax script. Its operation
is driven by a customized set of Mako templates that lists the packages
to be installed, steps to execute to remove unneeded files, and creation
of the iso for all of the supported architectures.
Before Lorax
============
Tree building tools such as pungi and revisor rely on 'buildinstall' in
anaconda/scripts/ to produce the boot images and other such control files
in the final tree. The existing buildinstall scripts written in a mix of
bash and Python are unmaintainable. Lorax is an attempt to replace them
with something more flexible.
EXISTING WORKFLOW:
pungi and other tools call scripts/buildinstall, which in turn call other
scripts to do the image building and data generation. Here's how it
currently looks:
-> buildinstall
* process command line options
* write temporary yum.conf to point to correct repo
* find anaconda release RPM
* unpack RPM, pull in those versions of upd-instroot, mk-images,
maketreeinfo.py, makestamp.py, and buildinstall
-> call upd-instroot
-> call maketreeinfo.py
-> call mk-images (which figures out which mk-images.ARCH to call)
-> call makestamp.py
* clean up
PROBLEMS:
The existing workflow presents some problems with maintaining the scripts.
First, almost all knowledge of what goes in to the stage 1 and stage 2
images lives in upd-instroot. The mk-images* scripts copy things from the
root created by upd-instroot in order to build the stage 1 image, though
it's not completely clear from reading the scripts.
NEW IDEAS:
Create a new central driver with all information living in Python modules.
Configuration files will provide the knowledge previously contained in the
upd-instroot and mk-images* scripts.

View File

@ -0,0 +1,67 @@
Introduction to Lorax
=====================
I am the Lorax. I speak for the trees [and images].
Lorax is used to build the Anaconda Installer boot.iso, it consists of a
library, pylorax, a set of templates, and the lorax script. Its operation
is driven by a customized set of Mako templates that lists the packages
to be installed, steps to execute to remove unneeded files, and creation
of the iso for all of the supported architectures.
Before Lorax
============
Tree building tools such as pungi and revisor rely on 'buildinstall' in
anaconda/scripts/ to produce the boot images and other such control files
in the final tree. The existing buildinstall scripts written in a mix of
bash and Python are unmaintainable. Lorax is an attempt to replace them
with something more flexible.
EXISTING WORKFLOW:
pungi and other tools call scripts/buildinstall, which in turn call other
scripts to do the image building and data generation. Here's how it
currently looks:
-> buildinstall
* process command line options
* write temporary yum.conf to point to correct repo
* find anaconda release RPM
* unpack RPM, pull in those versions of upd-instroot, mk-images,
maketreeinfo.py, makestamp.py, and buildinstall
-> call upd-instroot
-> call maketreeinfo.py
-> call mk-images (which figures out which mk-images.ARCH to call)
-> call makestamp.py
* clean up
PROBLEMS:
The existing workflow presents some problems with maintaining the scripts.
First, almost all knowledge of what goes in to the stage 1 and stage 2
images lives in upd-instroot. The mk-images* scripts copy things from the
root created by upd-instroot in order to build the stage 1 image, though
it's not completely clear from reading the scripts.
NEW IDEAS:
Create a new central driver with all information living in Python modules.
Configuration files will provide the knowledge previously contained in the
upd-instroot and mk-images* scripts.

View File

@ -0,0 +1,104 @@
lorax-composer
==============
:Authors:
Brian C. Lane <bcl@redhat.com>
lorax-composer is an API server that is compatible with the Weldr project's
bdcs-api REST protocol. More information on Weldr can be found `on the Weldr
blog <http://www.weldr.io>`_.
The server runs as root, and communication with it is via a unix domain socket
(``/run/weldr/api.socket`` by default). The directory and socket are owned by
root:weldr so that any user in the weldr group can use the API to control
lorax-composer.
When starting the server it will check for the correct permissions and
ownership of a pre-existing directory, or it will create a new one if it
doesn't exist. The socket path and group owner's name can be changed from the
cmdline by passing it the ``--socket`` and ``--group`` arguments.
As of version 19.7.7 it will drop root privileges for the API thread. The queue
and compose thread still runs as root because it needs to be able to
mount/umount files and run Anaconda.
Logs
----
Logs are stored under ``/var/log/lorax-composer/`` and include all console
messages as well as extra debugging info and API requests.
Quickstart
----------
1. Create a ``weldr`` user and group by running ``useradd weldr``
2. Remove any pre-existing socket directory with ``rm -rf /run/weldr/``
A new directory with correct permissions will be created the first time the server runs.
3. Either start it via systemd with ``systemctl start lorax-composer`` or
run it directly with ``lorax-composer /path/to/recipes/``
The ``/path/to/recipes/`` is where the recipe's git repo will be created, and
all the recipes created with the ``/api/v0/recipes/new`` route will be stored.
If there are recipe ``.toml`` files in the top level of the directory they will
be imported into the recipe git storage.
Composing Images
----------------
As of version 19.7.7 lorax-composer can create ``tar`` output images. You can use curl to start
a compose like this::
curl --unix-socket /run/weldr/api.socket -X POST -H "Content-Type: application/json" -d '{"recipe_name": "http-server", "compose_type": "tar", "branch": "master"}' http:///api/v0/compose
And then monitor it by passing the returned build UUID to ``/compose/status/<uuid>``.
Version 19.7.10 adds support for ``live-iso`` and ``partitioned-disk``
Adding Output Types
-------------------
livemedia-creator supports a large number of output types, and only some of
these are currently available via lorax-composer. To add a new output type to
lorax-composer a kickstart file needs to be added to ``./share/composer/``. The
name of the kickstart is what will be used by the ``/compose/types`` route, and the
``compose_type`` field of the POST to start a compose. It also needs to have
code added to the :py:func:`pylorax.api.compose.compose_args` function. The
``_MAP`` entry in this function defines what lorax-composer will pass to
:py:func:`pylorax.installer.novirt_install` when it runs the compose. When the
compose is finished the output files need to be copied out of the build
directory (``/var/lib/lorax/composer/results/<UUID>/compose/``),
:py:func:`pylorax.api.compose.move_compose_results` handles this for each type.
You should move them instead of copying to save space.
If the new output type does not have support in livemedia-creator it should be
added there first. This will make the output available to the widest number of
users.
Example: Add partitioned disk support
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Partitioned disk support is something that livemedia-creator already supports
via the ``--make-disk`` cmdline argument. To add this to lorax-composer it
needs 3 things:
* A ``partitioned-disk.ks`` file in ``./share/composer/``
* A new entry in the _MAP in :py:func:`pylorax.api.compose.compose_args`
* Add a bit of code to :py:func:`pylorax.api.compose.move_compose_results` to move the disk image from
the compose directory to the results directory.
The ``partitioned-disk.ks`` is pretty similar to the example minimal kickstart
in ``./docs/rhel7-minimal.ks``. You should remove the ``url`` and ``repo``
commands, they will be added by the compose process. Make sure the bootloader
packages are included in the ``%packages`` section at the end of the kickstart,
and you will want to leave off the ``%end`` so that the compose can append the
list of packages from the recipe.
The new ``_MAP`` entry should be a copy of one of the existing entries, but with ``make_disk`` set
to ``True``. Make sure that none of the other ``make_*`` options are ``True``. The ``image_name`` is
what the name of the final image will be.
``move_compose_results()`` can be as simple as moving the output file into
the results directory, or it could do some post-processing on it. The end of
the function should always clean up the ``./compose/`` directory, removing any
unneeded extra files. This is especially true for the ``live-iso`` since it produces
the contents of the iso as well as the boot.iso itself.

View File

@ -0,0 +1,104 @@
lorax-composer
==============
:Authors:
Brian C. Lane <bcl@redhat.com>
lorax-composer is an API server that is compatible with the Weldr project's
bdcs-api REST protocol. More information on Weldr can be found `on the Weldr
blog <http://www.weldr.io>`_.
The server runs as root, and communication with it is via a unix domain socket
(``/run/weldr/api.socket`` by default). The directory and socket are owned by
root:weldr so that any user in the weldr group can use the API to control
lorax-composer.
When starting the server it will check for the correct permissions and
ownership of a pre-existing directory, or it will create a new one if it
doesn't exist. The socket path and group owner's name can be changed from the
cmdline by passing it the ``--socket`` and ``--group`` arguments.
As of version 19.7.7 it will drop root privileges for the API thread. The queue
and compose thread still runs as root because it needs to be able to
mount/umount files and run Anaconda.
Logs
----
Logs are stored under ``/var/log/lorax-composer/`` and include all console
messages as well as extra debugging info and API requests.
Quickstart
----------
1. Create a ``weldr`` user and group by running ``useradd weldr``
2. Remove any pre-existing socket directory with ``rm -rf /run/weldr/``
A new directory with correct permissions will be created the first time the server runs.
3. Either start it via systemd with ``systemctl start lorax-composer`` or
run it directly with ``lorax-composer /path/to/recipes/``
The ``/path/to/recipes/`` is where the recipe's git repo will be created, and
all the recipes created with the ``/api/v0/recipes/new`` route will be stored.
If there are recipe ``.toml`` files in the top level of the directory they will
be imported into the recipe git storage.
Composing Images
----------------
As of version 19.7.7 lorax-composer can create ``tar`` output images. You can use curl to start
a compose like this::
curl --unix-socket /run/weldr/api.socket -X POST -H "Content-Type: application/json" -d '{"recipe_name": "http-server", "compose_type": "tar", "branch": "master"}' http:///api/v0/compose
And then monitor it by passing the returned build UUID to ``/compose/status/<uuid>``.
Version 19.7.10 adds support for ``live-iso`` and ``partitioned-disk``
Adding Output Types
-------------------
livemedia-creator supports a large number of output types, and only some of
these are currently available via lorax-composer. To add a new output type to
lorax-composer a kickstart file needs to be added to ``./share/composer/``. The
name of the kickstart is what will be used by the ``/compose/types`` route, and the
``compose_type`` field of the POST to start a compose. It also needs to have
code added to the :py:func:`pylorax.api.compose.compose_args` function. The
``_MAP`` entry in this function defines what lorax-composer will pass to
:py:func:`pylorax.installer.novirt_install` when it runs the compose. When the
compose is finished the output files need to be copied out of the build
directory (``/var/lib/lorax/composer/results/<UUID>/compose/``),
:py:func:`pylorax.api.compose.move_compose_results` handles this for each type.
You should move them instead of copying to save space.
If the new output type does not have support in livemedia-creator it should be
added there first. This will make the output available to the widest number of
users.
Example: Add partitioned disk support
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Partitioned disk support is something that livemedia-creator already supports
via the ``--make-disk`` cmdline argument. To add this to lorax-composer it
needs 3 things:
* A ``partitioned-disk.ks`` file in ``./share/composer/``
* A new entry in the _MAP in :py:func:`pylorax.api.compose.compose_args`
* Add a bit of code to :py:func:`pylorax.api.compose.move_compose_results` to move the disk image from
the compose directory to the results directory.
The ``partitioned-disk.ks`` is pretty similar to the example minimal kickstart
in ``./docs/rhel7-minimal.ks``. You should remove the ``url`` and ``repo``
commands, they will be added by the compose process. Make sure the bootloader
packages are included in the ``%packages`` section at the end of the kickstart,
and you will want to leave off the ``%end`` so that the compose can append the
list of packages from the recipe.
The new ``_MAP`` entry should be a copy of one of the existing entries, but with ``make_disk`` set
to ``True``. Make sure that none of the other ``make_*`` options are ``True``. The ``image_name`` is
what the name of the final image will be.
``move_compose_results()`` can be as simple as moving the output file into
the results directory, or it could do some post-processing on it. The end of
the function should always clean up the ``./compose/`` directory, removing any
unneeded extra files. This is especially true for the ``live-iso`` since it produces
the contents of the iso as well as the boot.iso itself.

View File

@ -0,0 +1,7 @@
pylorax
=======
.. toctree::
:maxdepth: 4
pylorax

View File

@ -0,0 +1,7 @@
pylorax
=======
.. toctree::
:maxdepth: 4
pylorax

View File

@ -0,0 +1,94 @@
pylorax\.api package
====================
Submodules
----------
pylorax\.api\.compose module
----------------------------
.. automodule:: pylorax.api.compose
:members:
:undoc-members:
:show-inheritance:
pylorax\.api\.config module
---------------------------
.. automodule:: pylorax.api.config
:members:
:undoc-members:
:show-inheritance:
pylorax\.api\.crossdomain module
--------------------------------
.. automodule:: pylorax.api.crossdomain
:members:
:undoc-members:
:show-inheritance:
pylorax\.api\.projects module
-----------------------------
.. automodule:: pylorax.api.projects
:members:
:undoc-members:
:show-inheritance:
pylorax\.api\.queue module
--------------------------
.. automodule:: pylorax.api.queue
:members:
:undoc-members:
:show-inheritance:
pylorax\.api\.recipes module
----------------------------
.. automodule:: pylorax.api.recipes
:members:
:undoc-members:
:show-inheritance:
pylorax\.api\.server module
---------------------------
.. automodule:: pylorax.api.server
:members:
:undoc-members:
:show-inheritance:
pylorax\.api\.v0 module
-----------------------
.. automodule:: pylorax.api.v0
:members:
:undoc-members:
:show-inheritance:
pylorax\.api\.workspace module
------------------------------
.. automodule:: pylorax.api.workspace
:members:
:undoc-members:
:show-inheritance:
pylorax\.api\.yumbase module
----------------------------
.. automodule:: pylorax.api.yumbase
:members:
:undoc-members:
:show-inheritance:
Module contents
---------------
.. automodule:: pylorax.api
:members:
:undoc-members:
:show-inheritance:

View File

@ -0,0 +1,91 @@
api Package
===========
:mod:`api` Package
------------------
.. automodule:: pylorax.api
:members:
:undoc-members:
:show-inheritance:
:mod:`compose` Module
---------------------
.. automodule:: pylorax.api.compose
:members:
:undoc-members:
:show-inheritance:
:mod:`config` Module
--------------------
.. automodule:: pylorax.api.config
:members:
:undoc-members:
:show-inheritance:
:mod:`crossdomain` Module
-------------------------
.. automodule:: pylorax.api.crossdomain
:members:
:undoc-members:
:show-inheritance:
:mod:`projects` Module
----------------------
.. automodule:: pylorax.api.projects
:members:
:undoc-members:
:show-inheritance:
:mod:`queue` Module
-------------------
.. automodule:: pylorax.api.queue
:members:
:undoc-members:
:show-inheritance:
:mod:`recipes` Module
---------------------
.. automodule:: pylorax.api.recipes
:members:
:undoc-members:
:show-inheritance:
:mod:`server` Module
--------------------
.. automodule:: pylorax.api.server
:members:
:undoc-members:
:show-inheritance:
:mod:`v0` Module
----------------
.. automodule:: pylorax.api.v0
:members:
:undoc-members:
:show-inheritance:
:mod:`workspace` Module
-----------------------
.. automodule:: pylorax.api.workspace
:members:
:undoc-members:
:show-inheritance:
:mod:`yumbase` Module
---------------------
.. automodule:: pylorax.api.yumbase
:members:
:undoc-members:
:show-inheritance:

View File

@ -0,0 +1,141 @@
pylorax package
===============
Subpackages
-----------
.. toctree::
pylorax.api
Submodules
----------
pylorax\.base module
--------------------
.. automodule:: pylorax.base
:members:
:undoc-members:
:show-inheritance:
pylorax\.buildstamp module
--------------------------
.. automodule:: pylorax.buildstamp
:members:
:undoc-members:
:show-inheritance:
pylorax\.creator module
-----------------------
.. automodule:: pylorax.creator
:members:
:undoc-members:
:show-inheritance:
pylorax\.decorators module
--------------------------
.. automodule:: pylorax.decorators
:members:
:undoc-members:
:show-inheritance:
pylorax\.discinfo module
------------------------
.. automodule:: pylorax.discinfo
:members:
:undoc-members:
:show-inheritance:
pylorax\.executils module
-------------------------
.. automodule:: pylorax.executils
:members:
:undoc-members:
:show-inheritance:
pylorax\.imgutils module
------------------------
.. automodule:: pylorax.imgutils
:members:
:undoc-members:
:show-inheritance:
pylorax\.installer module
-------------------------
.. automodule:: pylorax.installer
:members:
:undoc-members:
:show-inheritance:
pylorax\.logmonitor module
--------------------------
.. automodule:: pylorax.logmonitor
:members:
:undoc-members:
:show-inheritance:
pylorax\.ltmpl module
---------------------
.. automodule:: pylorax.ltmpl
:members:
:undoc-members:
:show-inheritance:
pylorax\.output module
----------------------
.. automodule:: pylorax.output
:members:
:undoc-members:
:show-inheritance:
pylorax\.sysutils module
------------------------
.. automodule:: pylorax.sysutils
:members:
:undoc-members:
:show-inheritance:
pylorax\.treebuilder module
---------------------------
.. automodule:: pylorax.treebuilder
:members:
:undoc-members:
:show-inheritance:
pylorax\.treeinfo module
------------------------
.. automodule:: pylorax.treeinfo
:members:
:undoc-members:
:show-inheritance:
pylorax\.yumhelper module
-------------------------
.. automodule:: pylorax.yumhelper
:members:
:undoc-members:
:show-inheritance:
Module contents
---------------
.. automodule:: pylorax
:members:
:undoc-members:
:show-inheritance:

View File

@ -0,0 +1,138 @@
pylorax Package
===============
:mod:`pylorax` Package
----------------------
.. automodule:: pylorax.__init__
:members:
:undoc-members:
:show-inheritance:
:mod:`base` Module
------------------
.. automodule:: pylorax.base
:members:
:undoc-members:
:show-inheritance:
:mod:`buildstamp` Module
------------------------
.. automodule:: pylorax.buildstamp
:members:
:undoc-members:
:show-inheritance:
:mod:`creator` Module
---------------------
.. automodule:: pylorax.creator
:members:
:undoc-members:
:show-inheritance:
:mod:`decorators` Module
------------------------
.. automodule:: pylorax.decorators
:members:
:undoc-members:
:show-inheritance:
:mod:`discinfo` Module
----------------------
.. automodule:: pylorax.discinfo
:members:
:undoc-members:
:show-inheritance:
:mod:`executils` Module
-----------------------
.. automodule:: pylorax.executils
:members:
:undoc-members:
:show-inheritance:
:mod:`imgutils` Module
----------------------
.. automodule:: pylorax.imgutils
:members:
:undoc-members:
:show-inheritance:
:mod:`installer` Module
-----------------------
.. automodule:: pylorax.installer
:members:
:undoc-members:
:show-inheritance:
:mod:`logmonitor` Module
------------------------
.. automodule:: pylorax.logmonitor
:members:
:undoc-members:
:show-inheritance:
:mod:`ltmpl` Module
-------------------
.. automodule:: pylorax.ltmpl
:members:
:undoc-members:
:show-inheritance:
:mod:`output` Module
--------------------
.. automodule:: pylorax.output
:members:
:undoc-members:
:show-inheritance:
:mod:`sysutils` Module
----------------------
.. automodule:: pylorax.sysutils
:members:
:undoc-members:
:show-inheritance:
:mod:`treebuilder` Module
-------------------------
.. automodule:: pylorax.treebuilder
:members:
:undoc-members:
:show-inheritance:
:mod:`treeinfo` Module
----------------------
.. automodule:: pylorax.treeinfo
:members:
:undoc-members:
:show-inheritance:
:mod:`yumhelper` Module
-----------------------
.. automodule:: pylorax.yumhelper
:members:
:undoc-members:
:show-inheritance:
Subpackages
-----------
.. toctree::
pylorax.api

Binary file not shown.

After

Width:  |  Height:  |  Size: 673 B

View File

@ -0,0 +1,540 @@
/*
* basic.css
* ~~~~~~~~~
*
* Sphinx stylesheet -- basic theme.
*
* :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
/* -- main layout ----------------------------------------------------------- */
div.clearer {
clear: both;
}
/* -- relbar ---------------------------------------------------------------- */
div.related {
width: 100%;
font-size: 90%;
}
div.related h3 {
display: none;
}
div.related ul {
margin: 0;
padding: 0 0 0 10px;
list-style: none;
}
div.related li {
display: inline;
}
div.related li.right {
float: right;
margin-right: 5px;
}
/* -- sidebar --------------------------------------------------------------- */
div.sphinxsidebarwrapper {
padding: 10px 5px 0 10px;
}
div.sphinxsidebar {
float: left;
width: 230px;
margin-left: -100%;
font-size: 90%;
}
div.sphinxsidebar ul {
list-style: none;
}
div.sphinxsidebar ul ul,
div.sphinxsidebar ul.want-points {
margin-left: 20px;
list-style: square;
}
div.sphinxsidebar ul ul {
margin-top: 0;
margin-bottom: 0;
}
div.sphinxsidebar form {
margin-top: 10px;
}
div.sphinxsidebar input {
border: 1px solid #98dbcc;
font-family: sans-serif;
font-size: 1em;
}
div.sphinxsidebar #searchbox input[type="text"] {
width: 170px;
}
div.sphinxsidebar #searchbox input[type="submit"] {
width: 30px;
}
img {
border: 0;
}
/* -- search page ----------------------------------------------------------- */
ul.search {
margin: 10px 0 0 20px;
padding: 0;
}
ul.search li {
padding: 5px 0 5px 20px;
background-image: url(file.png);
background-repeat: no-repeat;
background-position: 0 7px;
}
ul.search li a {
font-weight: bold;
}
ul.search li div.context {
color: #888;
margin: 2px 0 0 30px;
text-align: left;
}
ul.keywordmatches li.goodmatch a {
font-weight: bold;
}
/* -- index page ------------------------------------------------------------ */
table.contentstable {
width: 90%;
}
table.contentstable p.biglink {
line-height: 150%;
}
a.biglink {
font-size: 1.3em;
}
span.linkdescr {
font-style: italic;
padding-top: 5px;
font-size: 90%;
}
/* -- general index --------------------------------------------------------- */
table.indextable {
width: 100%;
}
table.indextable td {
text-align: left;
vertical-align: top;
}
table.indextable dl, table.indextable dd {
margin-top: 0;
margin-bottom: 0;
}
table.indextable tr.pcap {
height: 10px;
}
table.indextable tr.cap {
margin-top: 10px;
background-color: #f2f2f2;
}
img.toggler {
margin-right: 3px;
margin-top: 3px;
cursor: pointer;
}
div.modindex-jumpbox {
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
margin: 1em 0 1em 0;
padding: 0.4em;
}
div.genindex-jumpbox {
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
margin: 1em 0 1em 0;
padding: 0.4em;
}
/* -- general body styles --------------------------------------------------- */
a.headerlink {
visibility: hidden;
}
h1:hover > a.headerlink,
h2:hover > a.headerlink,
h3:hover > a.headerlink,
h4:hover > a.headerlink,
h5:hover > a.headerlink,
h6:hover > a.headerlink,
dt:hover > a.headerlink {
visibility: visible;
}
div.body p.caption {
text-align: inherit;
}
div.body td {
text-align: left;
}
.field-list ul {
padding-left: 1em;
}
.first {
margin-top: 0 !important;
}
p.rubric {
margin-top: 30px;
font-weight: bold;
}
img.align-left, .figure.align-left, object.align-left {
clear: left;
float: left;
margin-right: 1em;
}
img.align-right, .figure.align-right, object.align-right {
clear: right;
float: right;
margin-left: 1em;
}
img.align-center, .figure.align-center, object.align-center {
display: block;
margin-left: auto;
margin-right: auto;
}
.align-left {
text-align: left;
}
.align-center {
text-align: center;
}
.align-right {
text-align: right;
}
/* -- sidebars -------------------------------------------------------------- */
div.sidebar {
margin: 0 0 0.5em 1em;
border: 1px solid #ddb;
padding: 7px 7px 0 7px;
background-color: #ffe;
width: 40%;
float: right;
}
p.sidebar-title {
font-weight: bold;
}
/* -- topics ---------------------------------------------------------------- */
div.topic {
border: 1px solid #ccc;
padding: 7px 7px 0 7px;
margin: 10px 0 10px 0;
}
p.topic-title {
font-size: 1.1em;
font-weight: bold;
margin-top: 10px;
}
/* -- admonitions ----------------------------------------------------------- */
div.admonition {
margin-top: 10px;
margin-bottom: 10px;
padding: 7px;
}
div.admonition dt {
font-weight: bold;
}
div.admonition dl {
margin-bottom: 0;
}
p.admonition-title {
margin: 0px 10px 5px 0px;
font-weight: bold;
}
div.body p.centered {
text-align: center;
margin-top: 25px;
}
/* -- tables ---------------------------------------------------------------- */
table.docutils {
border: 0;
border-collapse: collapse;
}
table.docutils td, table.docutils th {
padding: 1px 8px 1px 5px;
border-top: 0;
border-left: 0;
border-right: 0;
border-bottom: 1px solid #aaa;
}
table.field-list td, table.field-list th {
border: 0 !important;
}
table.footnote td, table.footnote th {
border: 0 !important;
}
th {
text-align: left;
padding-right: 5px;
}
table.citation {
border-left: solid 1px gray;
margin-left: 1px;
}
table.citation td {
border-bottom: none;
}
/* -- other body styles ----------------------------------------------------- */
ol.arabic {
list-style: decimal;
}
ol.loweralpha {
list-style: lower-alpha;
}
ol.upperalpha {
list-style: upper-alpha;
}
ol.lowerroman {
list-style: lower-roman;
}
ol.upperroman {
list-style: upper-roman;
}
dl {
margin-bottom: 15px;
}
dd p {
margin-top: 0px;
}
dd ul, dd table {
margin-bottom: 10px;
}
dd {
margin-top: 3px;
margin-bottom: 10px;
margin-left: 30px;
}
dt:target, .highlighted {
background-color: #fbe54e;
}
dl.glossary dt {
font-weight: bold;
font-size: 1.1em;
}
.field-list ul {
margin: 0;
padding-left: 1em;
}
.field-list p {
margin: 0;
}
.refcount {
color: #060;
}
.optional {
font-size: 1.3em;
}
.versionmodified {
font-style: italic;
}
.system-message {
background-color: #fda;
padding: 5px;
border: 3px solid red;
}
.footnote:target {
background-color: #ffa;
}
.line-block {
display: block;
margin-top: 1em;
margin-bottom: 1em;
}
.line-block .line-block {
margin-top: 0;
margin-bottom: 0;
margin-left: 1.5em;
}
.guilabel, .menuselection {
font-family: sans-serif;
}
.accelerator {
text-decoration: underline;
}
.classifier {
font-style: oblique;
}
abbr, acronym {
border-bottom: dotted 1px;
cursor: help;
}
/* -- code displays --------------------------------------------------------- */
pre {
overflow: auto;
overflow-y: hidden; /* fixes display issues on Chrome browsers */
}
td.linenos pre {
padding: 5px 0px;
border: 0;
background-color: transparent;
color: #aaa;
}
table.highlighttable {
margin-left: 0.5em;
}
table.highlighttable td {
padding: 0 0.5em 0 0.5em;
}
tt.descname {
background-color: transparent;
font-weight: bold;
font-size: 1.2em;
}
tt.descclassname {
background-color: transparent;
}
tt.xref, a tt {
background-color: transparent;
font-weight: bold;
}
h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
background-color: transparent;
}
.viewcode-link {
float: right;
}
.viewcode-back {
float: right;
font-family: sans-serif;
}
div.viewcode-block:target {
margin: -1px -10px;
padding: 0 10px;
}
/* -- math display ---------------------------------------------------------- */
img.math {
vertical-align: middle;
}
div.body div.math p {
text-align: center;
}
span.eqno {
float: right;
}
/* -- printout stylesheet --------------------------------------------------- */
@media print {
div.document,
div.documentwrapper,
div.bodywrapper {
margin: 0 !important;
width: 100%;
}
div.sphinxsidebar,
div.related,
div.footer,
#top-link {
display: none;
}
}

View File

@ -0,0 +1,261 @@
/*
* classic.css_t
* ~~~~~~~~~~~~~
*
* Sphinx stylesheet -- classic theme.
*
* :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
@import url("basic.css");
/* -- page layout ----------------------------------------------------------- */
body {
font-family: sans-serif;
font-size: 100%;
background-color: #11303d;
color: #000;
margin: 0;
padding: 0;
}
div.document {
background-color: #1c4e63;
}
div.documentwrapper {
float: left;
width: 100%;
}
div.bodywrapper {
margin: 0 0 0 230px;
}
div.body {
background-color: #ffffff;
color: #000000;
padding: 0 20px 30px 20px;
}
div.footer {
color: #ffffff;
width: 100%;
padding: 9px 0 9px 0;
text-align: center;
font-size: 75%;
}
div.footer a {
color: #ffffff;
text-decoration: underline;
}
div.related {
background-color: #133f52;
line-height: 30px;
color: #ffffff;
}
div.related a {
color: #ffffff;
}
div.sphinxsidebar {
}
div.sphinxsidebar h3 {
font-family: 'Trebuchet MS', sans-serif;
color: #ffffff;
font-size: 1.4em;
font-weight: normal;
margin: 0;
padding: 0;
}
div.sphinxsidebar h3 a {
color: #ffffff;
}
div.sphinxsidebar h4 {
font-family: 'Trebuchet MS', sans-serif;
color: #ffffff;
font-size: 1.3em;
font-weight: normal;
margin: 5px 0 0 0;
padding: 0;
}
div.sphinxsidebar p {
color: #ffffff;
}
div.sphinxsidebar p.topless {
margin: 5px 10px 10px 10px;
}
div.sphinxsidebar ul {
margin: 10px;
padding: 0;
color: #ffffff;
}
div.sphinxsidebar a {
color: #98dbcc;
}
div.sphinxsidebar input {
border: 1px solid #98dbcc;
font-family: sans-serif;
font-size: 1em;
}
/* -- hyperlink styles ------------------------------------------------------ */
a {
color: #355f7c;
text-decoration: none;
}
a:visited {
color: #355f7c;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
/* -- body styles ----------------------------------------------------------- */
div.body h1,
div.body h2,
div.body h3,
div.body h4,
div.body h5,
div.body h6 {
font-family: 'Trebuchet MS', sans-serif;
background-color: #f2f2f2;
font-weight: normal;
color: #20435c;
border-bottom: 1px solid #ccc;
margin: 20px -20px 10px -20px;
padding: 3px 0 3px 10px;
}
div.body h1 { margin-top: 0; font-size: 200%; }
div.body h2 { font-size: 160%; }
div.body h3 { font-size: 140%; }
div.body h4 { font-size: 120%; }
div.body h5 { font-size: 110%; }
div.body h6 { font-size: 100%; }
a.headerlink {
color: #c60f0f;
font-size: 0.8em;
padding: 0 4px 0 4px;
text-decoration: none;
}
a.headerlink:hover {
background-color: #c60f0f;
color: white;
}
div.body p, div.body dd, div.body li, div.body blockquote {
text-align: justify;
line-height: 130%;
}
div.admonition p.admonition-title + p {
display: inline;
}
div.admonition p {
margin-bottom: 5px;
}
div.admonition pre {
margin-bottom: 5px;
}
div.admonition ul, div.admonition ol {
margin-bottom: 5px;
}
div.note {
background-color: #eee;
border: 1px solid #ccc;
}
div.seealso {
background-color: #ffc;
border: 1px solid #ff6;
}
div.topic {
background-color: #eee;
}
div.warning {
background-color: #ffe4e4;
border: 1px solid #f66;
}
p.admonition-title {
display: inline;
}
p.admonition-title:after {
content: ":";
}
pre {
padding: 5px;
background-color: #eeffcc;
color: #333333;
line-height: 120%;
border: 1px solid #ac9;
border-left: none;
border-right: none;
}
code {
background-color: #ecf0f3;
padding: 0 1px 0 1px;
font-size: 0.95em;
}
th {
background-color: #ede;
}
.warning code {
background: #efc2c2;
}
.note code {
background: #d6d6d6;
}
.viewcode-back {
font-family: sans-serif;
}
div.viewcode-block:target {
background-color: #f4debf;
border-top: 1px solid #ac9;
border-bottom: 1px solid #ac9;
}
div.code-block-caption {
color: #efefef;
background-color: #1c4e63;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@ -0,0 +1,256 @@
/*
* default.css_t
* ~~~~~~~~~~~~~
*
* Sphinx stylesheet -- default theme.
*
* :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
@import url("basic.css");
/* -- page layout ----------------------------------------------------------- */
body {
font-family: sans-serif;
font-size: 100%;
background-color: #11303d;
color: #000;
margin: 0;
padding: 0;
}
div.document {
background-color: #1c4e63;
}
div.documentwrapper {
float: left;
width: 100%;
}
div.bodywrapper {
margin: 0 0 0 230px;
}
div.body {
background-color: #ffffff;
color: #000000;
padding: 0 20px 30px 20px;
}
div.footer {
color: #ffffff;
width: 100%;
padding: 9px 0 9px 0;
text-align: center;
font-size: 75%;
}
div.footer a {
color: #ffffff;
text-decoration: underline;
}
div.related {
background-color: #133f52;
line-height: 30px;
color: #ffffff;
}
div.related a {
color: #ffffff;
}
div.sphinxsidebar {
}
div.sphinxsidebar h3 {
font-family: 'Trebuchet MS', sans-serif;
color: #ffffff;
font-size: 1.4em;
font-weight: normal;
margin: 0;
padding: 0;
}
div.sphinxsidebar h3 a {
color: #ffffff;
}
div.sphinxsidebar h4 {
font-family: 'Trebuchet MS', sans-serif;
color: #ffffff;
font-size: 1.3em;
font-weight: normal;
margin: 5px 0 0 0;
padding: 0;
}
div.sphinxsidebar p {
color: #ffffff;
}
div.sphinxsidebar p.topless {
margin: 5px 10px 10px 10px;
}
div.sphinxsidebar ul {
margin: 10px;
padding: 0;
color: #ffffff;
}
div.sphinxsidebar a {
color: #98dbcc;
}
div.sphinxsidebar input {
border: 1px solid #98dbcc;
font-family: sans-serif;
font-size: 1em;
}
/* -- hyperlink styles ------------------------------------------------------ */
a {
color: #355f7c;
text-decoration: none;
}
a:visited {
color: #355f7c;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
/* -- body styles ----------------------------------------------------------- */
div.body h1,
div.body h2,
div.body h3,
div.body h4,
div.body h5,
div.body h6 {
font-family: 'Trebuchet MS', sans-serif;
background-color: #f2f2f2;
font-weight: normal;
color: #20435c;
border-bottom: 1px solid #ccc;
margin: 20px -20px 10px -20px;
padding: 3px 0 3px 10px;
}
div.body h1 { margin-top: 0; font-size: 200%; }
div.body h2 { font-size: 160%; }
div.body h3 { font-size: 140%; }
div.body h4 { font-size: 120%; }
div.body h5 { font-size: 110%; }
div.body h6 { font-size: 100%; }
a.headerlink {
color: #c60f0f;
font-size: 0.8em;
padding: 0 4px 0 4px;
text-decoration: none;
}
a.headerlink:hover {
background-color: #c60f0f;
color: white;
}
div.body p, div.body dd, div.body li {
text-align: justify;
line-height: 130%;
}
div.admonition p.admonition-title + p {
display: inline;
}
div.admonition p {
margin-bottom: 5px;
}
div.admonition pre {
margin-bottom: 5px;
}
div.admonition ul, div.admonition ol {
margin-bottom: 5px;
}
div.note {
background-color: #eee;
border: 1px solid #ccc;
}
div.seealso {
background-color: #ffc;
border: 1px solid #ff6;
}
div.topic {
background-color: #eee;
}
div.warning {
background-color: #ffe4e4;
border: 1px solid #f66;
}
p.admonition-title {
display: inline;
}
p.admonition-title:after {
content: ":";
}
pre {
padding: 5px;
background-color: #eeffcc;
color: #333333;
line-height: 120%;
border: 1px solid #ac9;
border-left: none;
border-right: none;
}
tt {
background-color: #ecf0f3;
padding: 0 1px 0 1px;
font-size: 0.95em;
}
th {
background-color: #ede;
}
.warning tt {
background: #efc2c2;
}
.note tt {
background: #d6d6d6;
}
.viewcode-back {
font-family: sans-serif;
}
div.viewcode-block:target {
background-color: #f4debf;
border-top: 1px solid #ac9;
border-bottom: 1px solid #ac9;
}

View File

@ -0,0 +1,247 @@
/*
* doctools.js
* ~~~~~~~~~~~
*
* Sphinx JavaScript utilities for all documentation.
*
* :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
/**
* select a different prefix for underscore
*/
$u = _.noConflict();
/**
* make the code below compatible with browsers without
* an installed firebug like debugger
if (!window.console || !console.firebug) {
var names = ["log", "debug", "info", "warn", "error", "assert", "dir",
"dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace",
"profile", "profileEnd"];
window.console = {};
for (var i = 0; i < names.length; ++i)
window.console[names[i]] = function() {};
}
*/
/**
* small helper function to urldecode strings
*/
jQuery.urldecode = function(x) {
return decodeURIComponent(x).replace(/\+/g, ' ');
}
/**
* small helper function to urlencode strings
*/
jQuery.urlencode = encodeURIComponent;
/**
* This function returns the parsed url parameters of the
* current request. Multiple values per key are supported,
* it will always return arrays of strings for the value parts.
*/
jQuery.getQueryParameters = function(s) {
if (typeof s == 'undefined')
s = document.location.search;
var parts = s.substr(s.indexOf('?') + 1).split('&');
var result = {};
for (var i = 0; i < parts.length; i++) {
var tmp = parts[i].split('=', 2);
var key = jQuery.urldecode(tmp[0]);
var value = jQuery.urldecode(tmp[1]);
if (key in result)
result[key].push(value);
else
result[key] = [value];
}
return result;
};
/**
* small function to check if an array contains
* a given item.
*/
jQuery.contains = function(arr, item) {
for (var i = 0; i < arr.length; i++) {
if (arr[i] == item)
return true;
}
return false;
};
/**
* highlight a given string on a jquery object by wrapping it in
* span elements with the given class name.
*/
jQuery.fn.highlightText = function(text, className) {
function highlight(node) {
if (node.nodeType == 3) {
var val = node.nodeValue;
var pos = val.toLowerCase().indexOf(text);
if (pos >= 0 && !jQuery(node.parentNode).hasClass(className)) {
var span = document.createElement("span");
span.className = className;
span.appendChild(document.createTextNode(val.substr(pos, text.length)));
node.parentNode.insertBefore(span, node.parentNode.insertBefore(
document.createTextNode(val.substr(pos + text.length)),
node.nextSibling));
node.nodeValue = val.substr(0, pos);
}
}
else if (!jQuery(node).is("button, select, textarea")) {
jQuery.each(node.childNodes, function() {
highlight(this);
});
}
}
return this.each(function() {
highlight(this);
});
};
/**
* Small JavaScript module for the documentation.
*/
var Documentation = {
init : function() {
this.fixFirefoxAnchorBug();
this.highlightSearchWords();
this.initIndexTable();
},
/**
* i18n support
*/
TRANSLATIONS : {},
PLURAL_EXPR : function(n) { return n == 1 ? 0 : 1; },
LOCALE : 'unknown',
// gettext and ngettext don't access this so that the functions
// can safely bound to a different name (_ = Documentation.gettext)
gettext : function(string) {
var translated = Documentation.TRANSLATIONS[string];
if (typeof translated == 'undefined')
return string;
return (typeof translated == 'string') ? translated : translated[0];
},
ngettext : function(singular, plural, n) {
var translated = Documentation.TRANSLATIONS[singular];
if (typeof translated == 'undefined')
return (n == 1) ? singular : plural;
return translated[Documentation.PLURALEXPR(n)];
},
addTranslations : function(catalog) {
for (var key in catalog.messages)
this.TRANSLATIONS[key] = catalog.messages[key];
this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')');
this.LOCALE = catalog.locale;
},
/**
* add context elements like header anchor links
*/
addContextElements : function() {
$('div[id] > :header:first').each(function() {
$('<a class="headerlink">\u00B6</a>').
attr('href', '#' + this.id).
attr('title', _('Permalink to this headline')).
appendTo(this);
});
$('dt[id]').each(function() {
$('<a class="headerlink">\u00B6</a>').
attr('href', '#' + this.id).
attr('title', _('Permalink to this definition')).
appendTo(this);
});
},
/**
* workaround a firefox stupidity
*/
fixFirefoxAnchorBug : function() {
if (document.location.hash && $.browser.mozilla)
window.setTimeout(function() {
document.location.href += '';
}, 10);
},
/**
* highlight the search words provided in the url in the text
*/
highlightSearchWords : function() {
var params = $.getQueryParameters();
var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : [];
if (terms.length) {
var body = $('div.body');
window.setTimeout(function() {
$.each(terms, function() {
body.highlightText(this.toLowerCase(), 'highlighted');
});
}, 10);
$('<p class="highlight-link"><a href="javascript:Documentation.' +
'hideSearchWords()">' + _('Hide Search Matches') + '</a></p>')
.appendTo($('#searchbox'));
}
},
/**
* init the domain index toggle buttons
*/
initIndexTable : function() {
var togglers = $('img.toggler').click(function() {
var src = $(this).attr('src');
var idnum = $(this).attr('id').substr(7);
$('tr.cg-' + idnum).toggle();
if (src.substr(-9) == 'minus.png')
$(this).attr('src', src.substr(0, src.length-9) + 'plus.png');
else
$(this).attr('src', src.substr(0, src.length-8) + 'minus.png');
}).css('display', '');
if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) {
togglers.click();
}
},
/**
* helper function to hide the search marks again
*/
hideSearchWords : function() {
$('#searchbox .highlight-link').fadeOut(300);
$('span.highlighted').removeClass('highlighted');
},
/**
* make the url absolute
*/
makeURL : function(relativeURL) {
return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL;
},
/**
* get the current relative url
*/
getCurrentURL : function() {
var path = document.location.pathname;
var parts = path.split(/\//);
$.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() {
if (this == '..')
parts.pop();
});
var url = parts.join('/');
return path.substring(url.lastIndexOf('/') + 1, path.length - 1);
}
};
// quick alias for translations
_ = Documentation.gettext;
$(document).ready(function() {
Documentation.init();
});

Binary file not shown.

After

Width:  |  Height:  |  Size: 368 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 363 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 392 B

10074
lorax-composer/_static/jquery-3.1.0.js vendored Normal file

File diff suppressed because it is too large Load Diff

154
lorax-composer/_static/jquery.js vendored Normal file
View File

@ -0,0 +1,154 @@
/*!
* jQuery JavaScript Library v1.4.2
* http://jquery.com/
*
* Copyright 2010, John Resig
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* Includes Sizzle.js
* http://sizzlejs.com/
* Copyright 2010, The Dojo Foundation
* Released under the MIT, BSD, and GPL Licenses.
*
* Date: Sat Feb 13 22:33:48 2010 -0500
*/
(function(A,w){function ma(){if(!c.isReady){try{s.documentElement.doScroll("left")}catch(a){setTimeout(ma,1);return}c.ready()}}function Qa(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function X(a,b,d,f,e,j){var i=a.length;if(typeof b==="object"){for(var o in b)X(a,o,b[o],f,e,d);return a}if(d!==w){f=!j&&f&&c.isFunction(d);for(o=0;o<i;o++)e(a[o],b,f?d.call(a[o],o,e(a[o],b)):d,j);return a}return i?
e(a[0],b):w}function J(){return(new Date).getTime()}function Y(){return false}function Z(){return true}function na(a,b,d){d[0].type=a;return c.event.handle.apply(b,d)}function oa(a){var b,d=[],f=[],e=arguments,j,i,o,k,n,r;i=c.data(this,"events");if(!(a.liveFired===this||!i||!i.live||a.button&&a.type==="click")){a.liveFired=this;var u=i.live.slice(0);for(k=0;k<u.length;k++){i=u[k];i.origType.replace(O,"")===a.type?f.push(i.selector):u.splice(k--,1)}j=c(a.target).closest(f,a.currentTarget);n=0;for(r=
j.length;n<r;n++)for(k=0;k<u.length;k++){i=u[k];if(j[n].selector===i.selector){o=j[n].elem;f=null;if(i.preType==="mouseenter"||i.preType==="mouseleave")f=c(a.relatedTarget).closest(i.selector)[0];if(!f||f!==o)d.push({elem:o,handleObj:i})}}n=0;for(r=d.length;n<r;n++){j=d[n];a.currentTarget=j.elem;a.data=j.handleObj.data;a.handleObj=j.handleObj;if(j.handleObj.origHandler.apply(j.elem,e)===false){b=false;break}}return b}}function pa(a,b){return"live."+(a&&a!=="*"?a+".":"")+b.replace(/\./g,"`").replace(/ /g,
"&")}function qa(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function ra(a,b){var d=0;b.each(function(){if(this.nodeName===(a[d]&&a[d].nodeName)){var f=c.data(a[d++]),e=c.data(this,f);if(f=f&&f.events){delete e.handle;e.events={};for(var j in f)for(var i in f[j])c.event.add(this,j,f[j][i],f[j][i].data)}}})}function sa(a,b,d){var f,e,j;b=b&&b[0]?b[0].ownerDocument||b[0]:s;if(a.length===1&&typeof a[0]==="string"&&a[0].length<512&&b===s&&!ta.test(a[0])&&(c.support.checkClone||!ua.test(a[0]))){e=
true;if(j=c.fragments[a[0]])if(j!==1)f=j}if(!f){f=b.createDocumentFragment();c.clean(a,b,f,d)}if(e)c.fragments[a[0]]=j?f:1;return{fragment:f,cacheable:e}}function K(a,b){var d={};c.each(va.concat.apply([],va.slice(0,b)),function(){d[this]=a});return d}function wa(a){return"scrollTo"in a&&a.document?a:a.nodeType===9?a.defaultView||a.parentWindow:false}var c=function(a,b){return new c.fn.init(a,b)},Ra=A.jQuery,Sa=A.$,s=A.document,T,Ta=/^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,Ua=/^.[^:#\[\.,]*$/,Va=/\S/,
Wa=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,Xa=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,P=navigator.userAgent,xa=false,Q=[],L,$=Object.prototype.toString,aa=Object.prototype.hasOwnProperty,ba=Array.prototype.push,R=Array.prototype.slice,ya=Array.prototype.indexOf;c.fn=c.prototype={init:function(a,b){var d,f;if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1;return this}if(a==="body"&&!b){this.context=s;this[0]=s.body;this.selector="body";this.length=1;return this}if(typeof a==="string")if((d=Ta.exec(a))&&
(d[1]||!b))if(d[1]){f=b?b.ownerDocument||b:s;if(a=Xa.exec(a))if(c.isPlainObject(b)){a=[s.createElement(a[1])];c.fn.attr.call(a,b,true)}else a=[f.createElement(a[1])];else{a=sa([d[1]],[f]);a=(a.cacheable?a.fragment.cloneNode(true):a.fragment).childNodes}return c.merge(this,a)}else{if(b=s.getElementById(d[2])){if(b.id!==d[2])return T.find(a);this.length=1;this[0]=b}this.context=s;this.selector=a;return this}else if(!b&&/^\w+$/.test(a)){this.selector=a;this.context=s;a=s.getElementsByTagName(a);return c.merge(this,
a)}else return!b||b.jquery?(b||T).find(a):c(b).find(a);else if(c.isFunction(a))return T.ready(a);if(a.selector!==w){this.selector=a.selector;this.context=a.context}return c.makeArray(a,this)},selector:"",jquery:"1.4.2",length:0,size:function(){return this.length},toArray:function(){return R.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this.slice(a)[0]:this[a]},pushStack:function(a,b,d){var f=c();c.isArray(a)?ba.apply(f,a):c.merge(f,a);f.prevObject=this;f.context=this.context;if(b===
"find")f.selector=this.selector+(this.selector?" ":"")+d;else if(b)f.selector=this.selector+"."+b+"("+d+")";return f},each:function(a,b){return c.each(this,a,b)},ready:function(a){c.bindReady();if(c.isReady)a.call(s,c);else Q&&Q.push(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(R.apply(this,arguments),"slice",R.call(arguments).join(","))},map:function(a){return this.pushStack(c.map(this,
function(b,d){return a.call(b,d,b)}))},end:function(){return this.prevObject||c(null)},push:ba,sort:[].sort,splice:[].splice};c.fn.init.prototype=c.fn;c.extend=c.fn.extend=function(){var a=arguments[0]||{},b=1,d=arguments.length,f=false,e,j,i,o;if(typeof a==="boolean"){f=a;a=arguments[1]||{};b=2}if(typeof a!=="object"&&!c.isFunction(a))a={};if(d===b){a=this;--b}for(;b<d;b++)if((e=arguments[b])!=null)for(j in e){i=a[j];o=e[j];if(a!==o)if(f&&o&&(c.isPlainObject(o)||c.isArray(o))){i=i&&(c.isPlainObject(i)||
c.isArray(i))?i:c.isArray(o)?[]:{};a[j]=c.extend(f,i,o)}else if(o!==w)a[j]=o}return a};c.extend({noConflict:function(a){A.$=Sa;if(a)A.jQuery=Ra;return c},isReady:false,ready:function(){if(!c.isReady){if(!s.body)return setTimeout(c.ready,13);c.isReady=true;if(Q){for(var a,b=0;a=Q[b++];)a.call(s,c);Q=null}c.fn.triggerHandler&&c(s).triggerHandler("ready")}},bindReady:function(){if(!xa){xa=true;if(s.readyState==="complete")return c.ready();if(s.addEventListener){s.addEventListener("DOMContentLoaded",
L,false);A.addEventListener("load",c.ready,false)}else if(s.attachEvent){s.attachEvent("onreadystatechange",L);A.attachEvent("onload",c.ready);var a=false;try{a=A.frameElement==null}catch(b){}s.documentElement.doScroll&&a&&ma()}}},isFunction:function(a){return $.call(a)==="[object Function]"},isArray:function(a){return $.call(a)==="[object Array]"},isPlainObject:function(a){if(!a||$.call(a)!=="[object Object]"||a.nodeType||a.setInterval)return false;if(a.constructor&&!aa.call(a,"constructor")&&!aa.call(a.constructor.prototype,
"isPrototypeOf"))return false;var b;for(b in a);return b===w||aa.call(a,b)},isEmptyObject:function(a){for(var b in a)return false;return true},error:function(a){throw a;},parseJSON:function(a){if(typeof a!=="string"||!a)return null;a=c.trim(a);if(/^[\],:{}\s]*$/.test(a.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return A.JSON&&A.JSON.parse?A.JSON.parse(a):(new Function("return "+
a))();else c.error("Invalid JSON: "+a)},noop:function(){},globalEval:function(a){if(a&&Va.test(a)){var b=s.getElementsByTagName("head")[0]||s.documentElement,d=s.createElement("script");d.type="text/javascript";if(c.support.scriptEval)d.appendChild(s.createTextNode(a));else d.text=a;b.insertBefore(d,b.firstChild);b.removeChild(d)}},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,b,d){var f,e=0,j=a.length,i=j===w||c.isFunction(a);if(d)if(i)for(f in a){if(b.apply(a[f],
d)===false)break}else for(;e<j;){if(b.apply(a[e++],d)===false)break}else if(i)for(f in a){if(b.call(a[f],f,a[f])===false)break}else for(d=a[0];e<j&&b.call(d,e,d)!==false;d=a[++e]);return a},trim:function(a){return(a||"").replace(Wa,"")},makeArray:function(a,b){b=b||[];if(a!=null)a.length==null||typeof a==="string"||c.isFunction(a)||typeof a!=="function"&&a.setInterval?ba.call(b,a):c.merge(b,a);return b},inArray:function(a,b){if(b.indexOf)return b.indexOf(a);for(var d=0,f=b.length;d<f;d++)if(b[d]===
a)return d;return-1},merge:function(a,b){var d=a.length,f=0;if(typeof b.length==="number")for(var e=b.length;f<e;f++)a[d++]=b[f];else for(;b[f]!==w;)a[d++]=b[f++];a.length=d;return a},grep:function(a,b,d){for(var f=[],e=0,j=a.length;e<j;e++)!d!==!b(a[e],e)&&f.push(a[e]);return f},map:function(a,b,d){for(var f=[],e,j=0,i=a.length;j<i;j++){e=b(a[j],j,d);if(e!=null)f[f.length]=e}return f.concat.apply([],f)},guid:1,proxy:function(a,b,d){if(arguments.length===2)if(typeof b==="string"){d=a;a=d[b];b=w}else if(b&&
!c.isFunction(b)){d=b;b=w}if(!b&&a)b=function(){return a.apply(d||this,arguments)};if(a)b.guid=a.guid=a.guid||b.guid||c.guid++;return b},uaMatch:function(a){a=a.toLowerCase();a=/(webkit)[ \/]([\w.]+)/.exec(a)||/(opera)(?:.*version)?[ \/]([\w.]+)/.exec(a)||/(msie) ([\w.]+)/.exec(a)||!/compatible/.test(a)&&/(mozilla)(?:.*? rv:([\w.]+))?/.exec(a)||[];return{browser:a[1]||"",version:a[2]||"0"}},browser:{}});P=c.uaMatch(P);if(P.browser){c.browser[P.browser]=true;c.browser.version=P.version}if(c.browser.webkit)c.browser.safari=
true;if(ya)c.inArray=function(a,b){return ya.call(b,a)};T=c(s);if(s.addEventListener)L=function(){s.removeEventListener("DOMContentLoaded",L,false);c.ready()};else if(s.attachEvent)L=function(){if(s.readyState==="complete"){s.detachEvent("onreadystatechange",L);c.ready()}};(function(){c.support={};var a=s.documentElement,b=s.createElement("script"),d=s.createElement("div"),f="script"+J();d.style.display="none";d.innerHTML=" <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
var e=d.getElementsByTagName("*"),j=d.getElementsByTagName("a")[0];if(!(!e||!e.length||!j)){c.support={leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(j.getAttribute("style")),hrefNormalized:j.getAttribute("href")==="/a",opacity:/^0.55$/.test(j.style.opacity),cssFloat:!!j.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:s.createElement("select").appendChild(s.createElement("option")).selected,
parentNode:d.removeChild(d.appendChild(s.createElement("div"))).parentNode===null,deleteExpando:true,checkClone:false,scriptEval:false,noCloneEvent:true,boxModel:null};b.type="text/javascript";try{b.appendChild(s.createTextNode("window."+f+"=1;"))}catch(i){}a.insertBefore(b,a.firstChild);if(A[f]){c.support.scriptEval=true;delete A[f]}try{delete b.test}catch(o){c.support.deleteExpando=false}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function k(){c.support.noCloneEvent=
false;d.detachEvent("onclick",k)});d.cloneNode(true).fireEvent("onclick")}d=s.createElement("div");d.innerHTML="<input type='radio' name='radiotest' checked='checked'/>";a=s.createDocumentFragment();a.appendChild(d.firstChild);c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var k=s.createElement("div");k.style.width=k.style.paddingLeft="1px";s.body.appendChild(k);c.boxModel=c.support.boxModel=k.offsetWidth===2;s.body.removeChild(k).style.display="none"});a=function(k){var n=
s.createElement("div");k="on"+k;var r=k in n;if(!r){n.setAttribute(k,"return;");r=typeof n[k]==="function"}return r};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=e=j=null}})();c.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var G="jQuery"+J(),Ya=0,za={};c.extend({cache:{},expando:G,noData:{embed:true,object:true,
applet:true},data:function(a,b,d){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var f=a[G],e=c.cache;if(!f&&typeof b==="string"&&d===w)return null;f||(f=++Ya);if(typeof b==="object"){a[G]=f;e[f]=c.extend(true,{},b)}else if(!e[f]){a[G]=f;e[f]={}}a=e[f];if(d!==w)a[b]=d;return typeof b==="string"?a[b]:a}},removeData:function(a,b){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var d=a[G],f=c.cache,e=f[d];if(b){if(e){delete e[b];c.isEmptyObject(e)&&c.removeData(a)}}else{if(c.support.deleteExpando)delete a[c.expando];
else a.removeAttribute&&a.removeAttribute(c.expando);delete f[d]}}}});c.fn.extend({data:function(a,b){if(typeof a==="undefined"&&this.length)return c.data(this[0]);else if(typeof a==="object")return this.each(function(){c.data(this,a)});var d=a.split(".");d[1]=d[1]?"."+d[1]:"";if(b===w){var f=this.triggerHandler("getData"+d[1]+"!",[d[0]]);if(f===w&&this.length)f=c.data(this[0],a);return f===w&&d[1]?this.data(d[0]):f}else return this.trigger("setData"+d[1]+"!",[d[0],b]).each(function(){c.data(this,
a,b)})},removeData:function(a){return this.each(function(){c.removeData(this,a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var f=c.data(a,b);if(!d)return f||[];if(!f||c.isArray(d))f=c.data(a,b,c.makeArray(d));else f.push(d);return f}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),f=d.shift();if(f==="inprogress")f=d.shift();if(f){b==="fx"&&d.unshift("inprogress");f.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b===
w)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var Aa=/[\n\t]/g,ca=/\s+/,Za=/\r/g,$a=/href|src|style/,ab=/(button|input)/i,bb=/(button|input|object|select|textarea)/i,
cb=/^(a|area)$/i,Ba=/radio|checkbox/;c.fn.extend({attr:function(a,b){return X(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(n){var r=c(this);r.addClass(a.call(this,n,r.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1)if(e.className){for(var j=" "+e.className+" ",
i=e.className,o=0,k=b.length;o<k;o++)if(j.indexOf(" "+b[o]+" ")<0)i+=" "+b[o];e.className=c.trim(i)}else e.className=a}return this},removeClass:function(a){if(c.isFunction(a))return this.each(function(k){var n=c(this);n.removeClass(a.call(this,k,n.attr("class")))});if(a&&typeof a==="string"||a===w)for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1&&e.className)if(a){for(var j=(" "+e.className+" ").replace(Aa," "),i=0,o=b.length;i<o;i++)j=j.replace(" "+b[i]+" ",
" ");e.className=c.trim(j)}else e.className=""}return this},toggleClass:function(a,b){var d=typeof a,f=typeof b==="boolean";if(c.isFunction(a))return this.each(function(e){var j=c(this);j.toggleClass(a.call(this,e,j.attr("class"),b),b)});return this.each(function(){if(d==="string")for(var e,j=0,i=c(this),o=b,k=a.split(ca);e=k[j++];){o=f?o:!i.hasClass(e);i[o?"addClass":"removeClass"](e)}else if(d==="undefined"||d==="boolean"){this.className&&c.data(this,"__className__",this.className);this.className=
this.className||a===false?"":c.data(this,"__className__")||""}})},hasClass:function(a){a=" "+a+" ";for(var b=0,d=this.length;b<d;b++)if((" "+this[b].className+" ").replace(Aa," ").indexOf(a)>-1)return true;return false},val:function(a){if(a===w){var b=this[0];if(b){if(c.nodeName(b,"option"))return(b.attributes.value||{}).specified?b.value:b.text;if(c.nodeName(b,"select")){var d=b.selectedIndex,f=[],e=b.options;b=b.type==="select-one";if(d<0)return null;var j=b?d:0;for(d=b?d+1:e.length;j<d;j++){var i=
e[j];if(i.selected){a=c(i).val();if(b)return a;f.push(a)}}return f}if(Ba.test(b.type)&&!c.support.checkOn)return b.getAttribute("value")===null?"on":b.value;return(b.value||"").replace(Za,"")}return w}var o=c.isFunction(a);return this.each(function(k){var n=c(this),r=a;if(this.nodeType===1){if(o)r=a.call(this,k,n.val());if(typeof r==="number")r+="";if(c.isArray(r)&&Ba.test(this.type))this.checked=c.inArray(n.val(),r)>=0;else if(c.nodeName(this,"select")){var u=c.makeArray(r);c("option",this).each(function(){this.selected=
c.inArray(c(this).val(),u)>=0});if(!u.length)this.selectedIndex=-1}else this.value=r}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,d,f){if(!a||a.nodeType===3||a.nodeType===8)return w;if(f&&b in c.attrFn)return c(a)[b](d);f=a.nodeType!==1||!c.isXMLDoc(a);var e=d!==w;b=f&&c.props[b]||b;if(a.nodeType===1){var j=$a.test(b);if(b in a&&f&&!j){if(e){b==="type"&&ab.test(a.nodeName)&&a.parentNode&&c.error("type property can't be changed");
a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&b.specified?b.value:bb.test(a.nodeName)||cb.test(a.nodeName)&&a.href?0:w;return a[b]}if(!c.support.style&&f&&b==="style"){if(e)a.style.cssText=""+d;return a.style.cssText}e&&a.setAttribute(b,""+d);a=!c.support.hrefNormalized&&f&&j?a.getAttribute(b,2):a.getAttribute(b);return a===null?w:a}return c.style(a,b,d)}});var O=/\.(.*)$/,db=function(a){return a.replace(/[^\w\s\.\|`]/g,
function(b){return"\\"+b})};c.event={add:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){if(a.setInterval&&a!==A&&!a.frameElement)a=A;var e,j;if(d.handler){e=d;d=e.handler}if(!d.guid)d.guid=c.guid++;if(j=c.data(a)){var i=j.events=j.events||{},o=j.handle;if(!o)j.handle=o=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(o.elem,arguments):w};o.elem=a;b=b.split(" ");for(var k,n=0,r;k=b[n++];){j=e?c.extend({},e):{handler:d,data:f};if(k.indexOf(".")>-1){r=k.split(".");
k=r.shift();j.namespace=r.slice(0).sort().join(".")}else{r=[];j.namespace=""}j.type=k;j.guid=d.guid;var u=i[k],z=c.event.special[k]||{};if(!u){u=i[k]=[];if(!z.setup||z.setup.call(a,f,r,o)===false)if(a.addEventListener)a.addEventListener(k,o,false);else a.attachEvent&&a.attachEvent("on"+k,o)}if(z.add){z.add.call(a,j);if(!j.handler.guid)j.handler.guid=d.guid}u.push(j);c.event.global[k]=true}a=null}}},global:{},remove:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){var e,j=0,i,o,k,n,r,u,z=c.data(a),
C=z&&z.events;if(z&&C){if(b&&b.type){d=b.handler;b=b.type}if(!b||typeof b==="string"&&b.charAt(0)==="."){b=b||"";for(e in C)c.event.remove(a,e+b)}else{for(b=b.split(" ");e=b[j++];){n=e;i=e.indexOf(".")<0;o=[];if(!i){o=e.split(".");e=o.shift();k=new RegExp("(^|\\.)"+c.map(o.slice(0).sort(),db).join("\\.(?:.*\\.)?")+"(\\.|$)")}if(r=C[e])if(d){n=c.event.special[e]||{};for(B=f||0;B<r.length;B++){u=r[B];if(d.guid===u.guid){if(i||k.test(u.namespace)){f==null&&r.splice(B--,1);n.remove&&n.remove.call(a,u)}if(f!=
null)break}}if(r.length===0||f!=null&&r.length===1){if(!n.teardown||n.teardown.call(a,o)===false)Ca(a,e,z.handle);delete C[e]}}else for(var B=0;B<r.length;B++){u=r[B];if(i||k.test(u.namespace)){c.event.remove(a,n,u.handler,B);r.splice(B--,1)}}}if(c.isEmptyObject(C)){if(b=z.handle)b.elem=null;delete z.events;delete z.handle;c.isEmptyObject(z)&&c.removeData(a)}}}}},trigger:function(a,b,d,f){var e=a.type||a;if(!f){a=typeof a==="object"?a[G]?a:c.extend(c.Event(e),a):c.Event(e);if(e.indexOf("!")>=0){a.type=
e=e.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();c.event.global[e]&&c.each(c.cache,function(){this.events&&this.events[e]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===8)return w;a.result=w;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(f=c.data(d,"handle"))&&f.apply(d,b);f=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+e]&&d["on"+e].apply(d,b)===false)a.result=false}catch(j){}if(!a.isPropagationStopped()&&
f)c.event.trigger(a,b,f,true);else if(!a.isDefaultPrevented()){f=a.target;var i,o=c.nodeName(f,"a")&&e==="click",k=c.event.special[e]||{};if((!k._default||k._default.call(d,a)===false)&&!o&&!(f&&f.nodeName&&c.noData[f.nodeName.toLowerCase()])){try{if(f[e]){if(i=f["on"+e])f["on"+e]=null;c.event.triggered=true;f[e]()}}catch(n){}if(i)f["on"+e]=i;c.event.triggered=false}}},handle:function(a){var b,d,f,e;a=arguments[0]=c.event.fix(a||A.event);a.currentTarget=this;b=a.type.indexOf(".")<0&&!a.exclusive;
if(!b){d=a.type.split(".");a.type=d.shift();f=new RegExp("(^|\\.)"+d.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)")}e=c.data(this,"events");d=e[a.type];if(e&&d){d=d.slice(0);e=0;for(var j=d.length;e<j;e++){var i=d[e];if(b||f.test(i.namespace)){a.handler=i.handler;a.data=i.data;a.handleObj=i;i=i.handler.apply(this,arguments);if(i!==w){a.result=i;if(i===false){a.preventDefault();a.stopPropagation()}}if(a.isImmediatePropagationStopped())break}}}return a.result},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
fix:function(a){if(a[G])return a;var b=a;a=c.Event(b);for(var d=this.props.length,f;d;){f=this.props[--d];a[f]=b[f]}if(!a.target)a.target=a.srcElement||s;if(a.target.nodeType===3)a.target=a.target.parentNode;if(!a.relatedTarget&&a.fromElement)a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement;if(a.pageX==null&&a.clientX!=null){b=s.documentElement;d=s.body;a.pageX=a.clientX+(b&&b.scrollLeft||d&&d.scrollLeft||0)-(b&&b.clientLeft||d&&d.clientLeft||0);a.pageY=a.clientY+(b&&b.scrollTop||
d&&d.scrollTop||0)-(b&&b.clientTop||d&&d.clientTop||0)}if(!a.which&&(a.charCode||a.charCode===0?a.charCode:a.keyCode))a.which=a.charCode||a.keyCode;if(!a.metaKey&&a.ctrlKey)a.metaKey=a.ctrlKey;if(!a.which&&a.button!==w)a.which=a.button&1?1:a.button&2?3:a.button&4?2:0;return a},guid:1E8,proxy:c.proxy,special:{ready:{setup:c.bindReady,teardown:c.noop},live:{add:function(a){c.event.add(this,a.origType,c.extend({},a,{handler:oa}))},remove:function(a){var b=true,d=a.origType.replace(O,"");c.each(c.data(this,
"events").live||[],function(){if(d===this.origType.replace(O,""))return b=false});b&&c.event.remove(this,a.origType,oa)}},beforeunload:{setup:function(a,b,d){if(this.setInterval)this.onbeforeunload=d;return false},teardown:function(a,b){if(this.onbeforeunload===b)this.onbeforeunload=null}}}};var Ca=s.removeEventListener?function(a,b,d){a.removeEventListener(b,d,false)}:function(a,b,d){a.detachEvent("on"+b,d)};c.Event=function(a){if(!this.preventDefault)return new c.Event(a);if(a&&a.type){this.originalEvent=
a;this.type=a.type}else this.type=a;this.timeStamp=J();this[G]=true};c.Event.prototype={preventDefault:function(){this.isDefaultPrevented=Z;var a=this.originalEvent;if(a){a.preventDefault&&a.preventDefault();a.returnValue=false}},stopPropagation:function(){this.isPropagationStopped=Z;var a=this.originalEvent;if(a){a.stopPropagation&&a.stopPropagation();a.cancelBubble=true}},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=Z;this.stopPropagation()},isDefaultPrevented:Y,isPropagationStopped:Y,
isImmediatePropagationStopped:Y};var Da=function(a){var b=a.relatedTarget;try{for(;b&&b!==this;)b=b.parentNode;if(b!==this){a.type=a.data;c.event.handle.apply(this,arguments)}}catch(d){}},Ea=function(a){a.type=a.data;c.event.handle.apply(this,arguments)};c.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){c.event.special[a]={setup:function(d){c.event.add(this,b,d&&d.selector?Ea:Da,a)},teardown:function(d){c.event.remove(this,b,d&&d.selector?Ea:Da)}}});if(!c.support.submitBubbles)c.event.special.submit=
{setup:function(){if(this.nodeName.toLowerCase()!=="form"){c.event.add(this,"click.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="submit"||d==="image")&&c(b).closest("form").length)return na("submit",this,arguments)});c.event.add(this,"keypress.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="text"||d==="password")&&c(b).closest("form").length&&a.keyCode===13)return na("submit",this,arguments)})}else return false},teardown:function(){c.event.remove(this,".specialSubmit")}};
if(!c.support.changeBubbles){var da=/textarea|input|select/i,ea,Fa=function(a){var b=a.type,d=a.value;if(b==="radio"||b==="checkbox")d=a.checked;else if(b==="select-multiple")d=a.selectedIndex>-1?c.map(a.options,function(f){return f.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d},fa=function(a,b){var d=a.target,f,e;if(!(!da.test(d.nodeName)||d.readOnly)){f=c.data(d,"_change_data");e=Fa(d);if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_change_data",
e);if(!(f===w||e===f))if(f!=null||e){a.type="change";return c.event.trigger(a,b,d)}}};c.event.special.change={filters:{focusout:fa,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return fa.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return fa.call(this,a)},beforeactivate:function(a){a=a.target;c.data(a,
"_change_data",Fa(a))}},setup:function(){if(this.type==="file")return false;for(var a in ea)c.event.add(this,a+".specialChange",ea[a]);return da.test(this.nodeName)},teardown:function(){c.event.remove(this,".specialChange");return da.test(this.nodeName)}};ea=c.event.special.change.filters}s.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(f){f=c.event.fix(f);f.type=b;return c.event.handle.call(this,f)}c.event.special[b]={setup:function(){this.addEventListener(a,
d,true)},teardown:function(){this.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,f,e){if(typeof d==="object"){for(var j in d)this[b](j,f,d[j],e);return this}if(c.isFunction(f)){e=f;f=w}var i=b==="one"?c.proxy(e,function(k){c(this).unbind(k,i);return e.apply(this,arguments)}):e;if(d==="unload"&&b!=="one")this.one(d,f,e);else{j=0;for(var o=this.length;j<o;j++)c.event.add(this[j],d,i,f)}return this}});c.fn.extend({unbind:function(a,b){if(typeof a==="object"&&
!a.preventDefault)for(var d in a)this.unbind(d,a[d]);else{d=0;for(var f=this.length;d<f;d++)c.event.remove(this[d],a,b)}return this},delegate:function(a,b,d,f){return this.live(b,d,f,a)},undelegate:function(a,b,d){return arguments.length===0?this.unbind("live"):this.die(b,null,d,a)},trigger:function(a,b){return this.each(function(){c.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0]){a=c.Event(a);a.preventDefault();a.stopPropagation();c.event.trigger(a,b,this[0]);return a.result}},
toggle:function(a){for(var b=arguments,d=1;d<b.length;)c.proxy(a,b[d++]);return this.click(c.proxy(a,function(f){var e=(c.data(this,"lastToggle"+a.guid)||0)%d;c.data(this,"lastToggle"+a.guid,e+1);f.preventDefault();return b[e].apply(this,arguments)||false}))},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});var Ga={focus:"focusin",blur:"focusout",mouseenter:"mouseover",mouseleave:"mouseout"};c.each(["live","die"],function(a,b){c.fn[b]=function(d,f,e,j){var i,o=0,k,n,r=j||this.selector,
u=j?this:c(this.context);if(c.isFunction(f)){e=f;f=w}for(d=(d||"").split(" ");(i=d[o++])!=null;){j=O.exec(i);k="";if(j){k=j[0];i=i.replace(O,"")}if(i==="hover")d.push("mouseenter"+k,"mouseleave"+k);else{n=i;if(i==="focus"||i==="blur"){d.push(Ga[i]+k);i+=k}else i=(Ga[i]||i)+k;b==="live"?u.each(function(){c.event.add(this,pa(i,r),{data:f,selector:r,handler:e,origType:i,origHandler:e,preType:n})}):u.unbind(pa(i,r),e)}}return this}});c.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error".split(" "),
function(a,b){c.fn[b]=function(d){return d?this.bind(b,d):this.trigger(b)};if(c.attrFn)c.attrFn[b]=true});A.attachEvent&&!A.addEventListener&&A.attachEvent("onunload",function(){for(var a in c.cache)if(c.cache[a].handle)try{c.event.remove(c.cache[a].handle.elem)}catch(b){}});(function(){function a(g){for(var h="",l,m=0;g[m];m++){l=g[m];if(l.nodeType===3||l.nodeType===4)h+=l.nodeValue;else if(l.nodeType!==8)h+=a(l.childNodes)}return h}function b(g,h,l,m,q,p){q=0;for(var v=m.length;q<v;q++){var t=m[q];
if(t){t=t[g];for(var y=false;t;){if(t.sizcache===l){y=m[t.sizset];break}if(t.nodeType===1&&!p){t.sizcache=l;t.sizset=q}if(t.nodeName.toLowerCase()===h){y=t;break}t=t[g]}m[q]=y}}}function d(g,h,l,m,q,p){q=0;for(var v=m.length;q<v;q++){var t=m[q];if(t){t=t[g];for(var y=false;t;){if(t.sizcache===l){y=m[t.sizset];break}if(t.nodeType===1){if(!p){t.sizcache=l;t.sizset=q}if(typeof h!=="string"){if(t===h){y=true;break}}else if(k.filter(h,[t]).length>0){y=t;break}}t=t[g]}m[q]=y}}}var f=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
e=0,j=Object.prototype.toString,i=false,o=true;[0,0].sort(function(){o=false;return 0});var k=function(g,h,l,m){l=l||[];var q=h=h||s;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!g||typeof g!=="string")return l;for(var p=[],v,t,y,S,H=true,M=x(h),I=g;(f.exec(""),v=f.exec(I))!==null;){I=v[3];p.push(v[1]);if(v[2]){S=v[3];break}}if(p.length>1&&r.exec(g))if(p.length===2&&n.relative[p[0]])t=ga(p[0]+p[1],h);else for(t=n.relative[p[0]]?[h]:k(p.shift(),h);p.length;){g=p.shift();if(n.relative[g])g+=p.shift();
t=ga(g,t)}else{if(!m&&p.length>1&&h.nodeType===9&&!M&&n.match.ID.test(p[0])&&!n.match.ID.test(p[p.length-1])){v=k.find(p.shift(),h,M);h=v.expr?k.filter(v.expr,v.set)[0]:v.set[0]}if(h){v=m?{expr:p.pop(),set:z(m)}:k.find(p.pop(),p.length===1&&(p[0]==="~"||p[0]==="+")&&h.parentNode?h.parentNode:h,M);t=v.expr?k.filter(v.expr,v.set):v.set;if(p.length>0)y=z(t);else H=false;for(;p.length;){var D=p.pop();v=D;if(n.relative[D])v=p.pop();else D="";if(v==null)v=h;n.relative[D](y,v,M)}}else y=[]}y||(y=t);y||k.error(D||
g);if(j.call(y)==="[object Array]")if(H)if(h&&h.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&E(h,y[g])))l.push(t[g])}else for(g=0;y[g]!=null;g++)y[g]&&y[g].nodeType===1&&l.push(t[g]);else l.push.apply(l,y);else z(y,l);if(S){k(S,q,l,m);k.uniqueSort(l)}return l};k.uniqueSort=function(g){if(B){i=o;g.sort(B);if(i)for(var h=1;h<g.length;h++)g[h]===g[h-1]&&g.splice(h--,1)}return g};k.matches=function(g,h){return k(g,null,null,h)};k.find=function(g,h,l){var m,q;if(!g)return[];
for(var p=0,v=n.order.length;p<v;p++){var t=n.order[p];if(q=n.leftMatch[t].exec(g)){var y=q[1];q.splice(1,1);if(y.substr(y.length-1)!=="\\"){q[1]=(q[1]||"").replace(/\\/g,"");m=n.find[t](q,h,l);if(m!=null){g=g.replace(n.match[t],"");break}}}}m||(m=h.getElementsByTagName("*"));return{set:m,expr:g}};k.filter=function(g,h,l,m){for(var q=g,p=[],v=h,t,y,S=h&&h[0]&&x(h[0]);g&&h.length;){for(var H in n.filter)if((t=n.leftMatch[H].exec(g))!=null&&t[2]){var M=n.filter[H],I,D;D=t[1];y=false;t.splice(1,1);if(D.substr(D.length-
1)!=="\\"){if(v===p)p=[];if(n.preFilter[H])if(t=n.preFilter[H](t,v,l,p,m,S)){if(t===true)continue}else y=I=true;if(t)for(var U=0;(D=v[U])!=null;U++)if(D){I=M(D,t,U,v);var Ha=m^!!I;if(l&&I!=null)if(Ha)y=true;else v[U]=false;else if(Ha){p.push(D);y=true}}if(I!==w){l||(v=p);g=g.replace(n.match[H],"");if(!y)return[];break}}}if(g===q)if(y==null)k.error(g);else break;q=g}return v};k.error=function(g){throw"Syntax error, unrecognized expression: "+g;};var n=k.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
CLASS:/\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(g){return g.getAttribute("href")}},
relative:{"+":function(g,h){var l=typeof h==="string",m=l&&!/\W/.test(h);l=l&&!m;if(m)h=h.toLowerCase();m=0;for(var q=g.length,p;m<q;m++)if(p=g[m]){for(;(p=p.previousSibling)&&p.nodeType!==1;);g[m]=l||p&&p.nodeName.toLowerCase()===h?p||false:p===h}l&&k.filter(h,g,true)},">":function(g,h){var l=typeof h==="string";if(l&&!/\W/.test(h)){h=h.toLowerCase();for(var m=0,q=g.length;m<q;m++){var p=g[m];if(p){l=p.parentNode;g[m]=l.nodeName.toLowerCase()===h?l:false}}}else{m=0;for(q=g.length;m<q;m++)if(p=g[m])g[m]=
l?p.parentNode:p.parentNode===h;l&&k.filter(h,g,true)}},"":function(g,h,l){var m=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("parentNode",h,m,g,p,l)},"~":function(g,h,l){var m=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("previousSibling",h,m,g,p,l)}},find:{ID:function(g,h,l){if(typeof h.getElementById!=="undefined"&&!l)return(g=h.getElementById(g[1]))?[g]:[]},NAME:function(g,h){if(typeof h.getElementsByName!=="undefined"){var l=[];
h=h.getElementsByName(g[1]);for(var m=0,q=h.length;m<q;m++)h[m].getAttribute("name")===g[1]&&l.push(h[m]);return l.length===0?null:l}},TAG:function(g,h){return h.getElementsByTagName(g[1])}},preFilter:{CLASS:function(g,h,l,m,q,p){g=" "+g[1].replace(/\\/g,"")+" ";if(p)return g;p=0;for(var v;(v=h[p])!=null;p++)if(v)if(q^(v.className&&(" "+v.className+" ").replace(/[\t\n]/g," ").indexOf(g)>=0))l||m.push(v);else if(l)h[p]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()},
CHILD:function(g){if(g[1]==="nth"){var h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=h[1]+(h[2]||1)-0;g[3]=h[3]-0}g[0]=e++;return g},ATTR:function(g,h,l,m,q,p){h=g[1].replace(/\\/g,"");if(!p&&n.attrMap[h])g[1]=n.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,l,m,q){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=k(g[3],null,null,h);else{g=k.filter(g[3],h,l,true^q);l||m.push.apply(m,
g);return false}else if(n.match.POS.test(g[0])||n.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,h,l){return!!k(l[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)},
text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}},
setFilters:{first:function(g,h){return h===0},last:function(g,h,l,m){return h===m.length-1},even:function(g,h){return h%2===0},odd:function(g,h){return h%2===1},lt:function(g,h,l){return h<l[3]-0},gt:function(g,h,l){return h>l[3]-0},nth:function(g,h,l){return l[3]-0===h},eq:function(g,h,l){return l[3]-0===h}},filter:{PSEUDO:function(g,h,l,m){var q=h[1],p=n.filters[q];if(p)return p(g,l,h,m);else if(q==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(q==="not"){h=
h[3];l=0;for(m=h.length;l<m;l++)if(h[l]===g)return false;return true}else k.error("Syntax error, unrecognized expression: "+q)},CHILD:function(g,h){var l=h[1],m=g;switch(l){case "only":case "first":for(;m=m.previousSibling;)if(m.nodeType===1)return false;if(l==="first")return true;m=g;case "last":for(;m=m.nextSibling;)if(m.nodeType===1)return false;return true;case "nth":l=h[2];var q=h[3];if(l===1&&q===0)return true;h=h[0];var p=g.parentNode;if(p&&(p.sizcache!==h||!g.nodeIndex)){var v=0;for(m=p.firstChild;m;m=
m.nextSibling)if(m.nodeType===1)m.nodeIndex=++v;p.sizcache=h}g=g.nodeIndex-q;return l===0?g===0:g%l===0&&g/l>=0}},ID:function(g,h){return g.nodeType===1&&g.getAttribute("id")===h},TAG:function(g,h){return h==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===h},CLASS:function(g,h){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(g,h){var l=h[1];g=n.attrHandle[l]?n.attrHandle[l](g):g[l]!=null?g[l]:g.getAttribute(l);l=g+"";var m=h[2];h=h[4];return g==null?m==="!=":m===
"="?l===h:m==="*="?l.indexOf(h)>=0:m==="~="?(" "+l+" ").indexOf(h)>=0:!h?l&&g!==false:m==="!="?l!==h:m==="^="?l.indexOf(h)===0:m==="$="?l.substr(l.length-h.length)===h:m==="|="?l===h||l.substr(0,h.length+1)===h+"-":false},POS:function(g,h,l,m){var q=n.setFilters[h[2]];if(q)return q(g,l,h,m)}}},r=n.match.POS;for(var u in n.match){n.match[u]=new RegExp(n.match[u].source+/(?![^\[]*\])(?![^\(]*\))/.source);n.leftMatch[u]=new RegExp(/(^(?:.|\r|\n)*?)/.source+n.match[u].source.replace(/\\(\d+)/g,function(g,
h){return"\\"+(h-0+1)}))}var z=function(g,h){g=Array.prototype.slice.call(g,0);if(h){h.push.apply(h,g);return h}return g};try{Array.prototype.slice.call(s.documentElement.childNodes,0)}catch(C){z=function(g,h){h=h||[];if(j.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var l=0,m=g.length;l<m;l++)h.push(g[l]);else for(l=0;g[l];l++)h.push(g[l]);return h}}var B;if(s.documentElement.compareDocumentPosition)B=function(g,h){if(!g.compareDocumentPosition||
!h.compareDocumentPosition){if(g==h)i=true;return g.compareDocumentPosition?-1:1}g=g.compareDocumentPosition(h)&4?-1:g===h?0:1;if(g===0)i=true;return g};else if("sourceIndex"in s.documentElement)B=function(g,h){if(!g.sourceIndex||!h.sourceIndex){if(g==h)i=true;return g.sourceIndex?-1:1}g=g.sourceIndex-h.sourceIndex;if(g===0)i=true;return g};else if(s.createRange)B=function(g,h){if(!g.ownerDocument||!h.ownerDocument){if(g==h)i=true;return g.ownerDocument?-1:1}var l=g.ownerDocument.createRange(),m=
h.ownerDocument.createRange();l.setStart(g,0);l.setEnd(g,0);m.setStart(h,0);m.setEnd(h,0);g=l.compareBoundaryPoints(Range.START_TO_END,m);if(g===0)i=true;return g};(function(){var g=s.createElement("div"),h="script"+(new Date).getTime();g.innerHTML="<a name='"+h+"'/>";var l=s.documentElement;l.insertBefore(g,l.firstChild);if(s.getElementById(h)){n.find.ID=function(m,q,p){if(typeof q.getElementById!=="undefined"&&!p)return(q=q.getElementById(m[1]))?q.id===m[1]||typeof q.getAttributeNode!=="undefined"&&
q.getAttributeNode("id").nodeValue===m[1]?[q]:w:[]};n.filter.ID=function(m,q){var p=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&p&&p.nodeValue===q}}l.removeChild(g);l=g=null})();(function(){var g=s.createElement("div");g.appendChild(s.createComment(""));if(g.getElementsByTagName("*").length>0)n.find.TAG=function(h,l){l=l.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var m=0;l[m];m++)l[m].nodeType===1&&h.push(l[m]);l=h}return l};g.innerHTML="<a href='#'></a>";
if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")n.attrHandle.href=function(h){return h.getAttribute("href",2)};g=null})();s.querySelectorAll&&function(){var g=k,h=s.createElement("div");h.innerHTML="<p class='TEST'></p>";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){k=function(m,q,p,v){q=q||s;if(!v&&q.nodeType===9&&!x(q))try{return z(q.querySelectorAll(m),p)}catch(t){}return g(m,q,p,v)};for(var l in g)k[l]=g[l];h=null}}();
(function(){var g=s.createElement("div");g.innerHTML="<div class='test e'></div><div class='test'></div>";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){n.order.splice(1,0,"CLASS");n.find.CLASS=function(h,l,m){if(typeof l.getElementsByClassName!=="undefined"&&!m)return l.getElementsByClassName(h[1])};g=null}}})();var E=s.compareDocumentPosition?function(g,h){return!!(g.compareDocumentPosition(h)&16)}:
function(g,h){return g!==h&&(g.contains?g.contains(h):true)},x=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false},ga=function(g,h){var l=[],m="",q;for(h=h.nodeType?[h]:h;q=n.match.PSEUDO.exec(g);){m+=q[0];g=g.replace(n.match.PSEUDO,"")}g=n.relative[g]?g+"*":g;q=0;for(var p=h.length;q<p;q++)k(g,h[q],l);return k.filter(m,l)};c.find=k;c.expr=k.selectors;c.expr[":"]=c.expr.filters;c.unique=k.uniqueSort;c.text=a;c.isXMLDoc=x;c.contains=E})();var eb=/Until$/,fb=/^(?:parents|prevUntil|prevAll)/,
gb=/,/;R=Array.prototype.slice;var Ia=function(a,b,d){if(c.isFunction(b))return c.grep(a,function(e,j){return!!b.call(e,j,e)===d});else if(b.nodeType)return c.grep(a,function(e){return e===b===d});else if(typeof b==="string"){var f=c.grep(a,function(e){return e.nodeType===1});if(Ua.test(b))return c.filter(b,f,!d);else b=c.filter(b,f)}return c.grep(a,function(e){return c.inArray(e,b)>=0===d})};c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,f=0,e=this.length;f<e;f++){d=b.length;
c.find(a,this[f],b);if(f>0)for(var j=d;j<b.length;j++)for(var i=0;i<d;i++)if(b[i]===b[j]){b.splice(j--,1);break}}return b},has:function(a){var b=c(a);return this.filter(function(){for(var d=0,f=b.length;d<f;d++)if(c.contains(this,b[d]))return true})},not:function(a){return this.pushStack(Ia(this,a,false),"not",a)},filter:function(a){return this.pushStack(Ia(this,a,true),"filter",a)},is:function(a){return!!a&&c.filter(a,this).length>0},closest:function(a,b){if(c.isArray(a)){var d=[],f=this[0],e,j=
{},i;if(f&&a.length){e=0;for(var o=a.length;e<o;e++){i=a[e];j[i]||(j[i]=c.expr.match.POS.test(i)?c(i,b||this.context):i)}for(;f&&f.ownerDocument&&f!==b;){for(i in j){e=j[i];if(e.jquery?e.index(f)>-1:c(f).is(e)){d.push({selector:i,elem:f});delete j[i]}}f=f.parentNode}}return d}var k=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(n,r){for(;r&&r.ownerDocument&&r!==b;){if(k?k.index(r)>-1:c(r).is(a))return r;r=r.parentNode}return null})},index:function(a){if(!a||typeof a===
"string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){a=typeof a==="string"?c(a,b||this.context):c.makeArray(a);b=c.merge(this.get(),a);return this.pushStack(qa(a[0])||qa(b[0])?b:c.unique(b))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode",
d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")?
a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,f){var e=c.map(this,b,d);eb.test(a)||(f=d);if(f&&typeof f==="string")e=c.filter(f,e);e=this.length>1?c.unique(e):e;if((this.length>1||gb.test(f))&&fb.test(a))e=e.reverse();return this.pushStack(e,a,R.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return c.find.matches(a,b)},dir:function(a,b,d){var f=[];for(a=a[b];a&&a.nodeType!==9&&(d===w||a.nodeType!==1||!c(a).is(d));){a.nodeType===
1&&f.push(a);a=a[b]}return f},nth:function(a,b,d){b=b||1;for(var f=0;a;a=a[d])if(a.nodeType===1&&++f===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var Ja=/ jQuery\d+="(?:\d+|null)"/g,V=/^\s+/,Ka=/(<([\w:]+)[^>]*?)\/>/g,hb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,La=/<([\w:]+)/,ib=/<tbody/i,jb=/<|&#?\w+;/,ta=/<script|<object|<embed|<option|<style/i,ua=/checked\s*(?:[^=]|=\s*.checked.)/i,Ma=function(a,b,d){return hb.test(d)?
a:b+"></"+d+">"},F={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};F.optgroup=F.option;F.tbody=F.tfoot=F.colgroup=F.caption=F.thead;F.th=F.td;if(!c.support.htmlSerialize)F._default=[1,"div<div>","</div>"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d=
c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==w)return this.empty().append((this[0]&&this[0].ownerDocument||s).createTextNode(a));return c.text(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this},
wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})},
prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,
this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},remove:function(a,b){for(var d=0,f;(f=this[d])!=null;d++)if(!a||c.filter(a,[f]).length){if(!b&&f.nodeType===1){c.cleanData(f.getElementsByTagName("*"));c.cleanData([f])}f.parentNode&&f.parentNode.removeChild(f)}return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++)for(b.nodeType===1&&c.cleanData(b.getElementsByTagName("*"));b.firstChild;)b.removeChild(b.firstChild);
return this},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,f=this.ownerDocument;if(!d){d=f.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(Ja,"").replace(/=([^="'>\s]+\/)>/g,'="$1">').replace(V,"")],f)[0]}else return this.cloneNode(true)});if(a===true){ra(this,b);ra(this.find("*"),b.find("*"))}return b},html:function(a){if(a===w)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Ja,
""):null;else if(typeof a==="string"&&!ta.test(a)&&(c.support.leadingWhitespace||!V.test(a))&&!F[(La.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Ka,Ma);try{for(var b=0,d=this.length;b<d;b++)if(this[b].nodeType===1){c.cleanData(this[b].getElementsByTagName("*"));this[b].innerHTML=a}}catch(f){this.empty().append(a)}}else c.isFunction(a)?this.each(function(e){var j=c(this),i=j.html();j.empty().append(function(){return a.call(this,e,i)})}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&
this[0].parentNode){if(c.isFunction(a))return this.each(function(b){var d=c(this),f=d.html();d.replaceWith(a.call(this,b,f))});if(typeof a!=="string")a=c(a).detach();return this.each(function(){var b=this.nextSibling,d=this.parentNode;c(this).remove();b?c(b).before(a):c(d).append(a)})}else return this.pushStack(c(c.isFunction(a)?a():a),"replaceWith",a)},detach:function(a){return this.remove(a,true)},domManip:function(a,b,d){function f(u){return c.nodeName(u,"table")?u.getElementsByTagName("tbody")[0]||
u.appendChild(u.ownerDocument.createElement("tbody")):u}var e,j,i=a[0],o=[],k;if(!c.support.checkClone&&arguments.length===3&&typeof i==="string"&&ua.test(i))return this.each(function(){c(this).domManip(a,b,d,true)});if(c.isFunction(i))return this.each(function(u){var z=c(this);a[0]=i.call(this,u,b?z.html():w);z.domManip(a,b,d)});if(this[0]){e=i&&i.parentNode;e=c.support.parentNode&&e&&e.nodeType===11&&e.childNodes.length===this.length?{fragment:e}:sa(a,this,o);k=e.fragment;if(j=k.childNodes.length===
1?(k=k.firstChild):k.firstChild){b=b&&c.nodeName(j,"tr");for(var n=0,r=this.length;n<r;n++)d.call(b?f(this[n],j):this[n],n>0||e.cacheable||this.length>1?k.cloneNode(true):k)}o.length&&c.each(o,Qa)}return this}});c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var f=[];d=c(d);var e=this.length===1&&this[0].parentNode;if(e&&e.nodeType===11&&e.childNodes.length===1&&d.length===1){d[b](this[0]);
return this}else{e=0;for(var j=d.length;e<j;e++){var i=(e>0?this.clone(true):this).get();c.fn[b].apply(c(d[e]),i);f=f.concat(i)}return this.pushStack(f,a,d.selector)}}});c.extend({clean:function(a,b,d,f){b=b||s;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||s;for(var e=[],j=0,i;(i=a[j])!=null;j++){if(typeof i==="number")i+="";if(i){if(typeof i==="string"&&!jb.test(i))i=b.createTextNode(i);else if(typeof i==="string"){i=i.replace(Ka,Ma);var o=(La.exec(i)||["",
""])[1].toLowerCase(),k=F[o]||F._default,n=k[0],r=b.createElement("div");for(r.innerHTML=k[1]+i+k[2];n--;)r=r.lastChild;if(!c.support.tbody){n=ib.test(i);o=o==="table"&&!n?r.firstChild&&r.firstChild.childNodes:k[1]==="<table>"&&!n?r.childNodes:[];for(k=o.length-1;k>=0;--k)c.nodeName(o[k],"tbody")&&!o[k].childNodes.length&&o[k].parentNode.removeChild(o[k])}!c.support.leadingWhitespace&&V.test(i)&&r.insertBefore(b.createTextNode(V.exec(i)[0]),r.firstChild);i=r.childNodes}if(i.nodeType)e.push(i);else e=
c.merge(e,i)}}if(d)for(j=0;e[j];j++)if(f&&c.nodeName(e[j],"script")&&(!e[j].type||e[j].type.toLowerCase()==="text/javascript"))f.push(e[j].parentNode?e[j].parentNode.removeChild(e[j]):e[j]);else{e[j].nodeType===1&&e.splice.apply(e,[j+1,0].concat(c.makeArray(e[j].getElementsByTagName("script"))));d.appendChild(e[j])}return e},cleanData:function(a){for(var b,d,f=c.cache,e=c.event.special,j=c.support.deleteExpando,i=0,o;(o=a[i])!=null;i++)if(d=o[c.expando]){b=f[d];if(b.events)for(var k in b.events)e[k]?
c.event.remove(o,k):Ca(o,k,b.handle);if(j)delete o[c.expando];else o.removeAttribute&&o.removeAttribute(c.expando);delete f[d]}}});var kb=/z-?index|font-?weight|opacity|zoom|line-?height/i,Na=/alpha\([^)]*\)/,Oa=/opacity=([^)]*)/,ha=/float/i,ia=/-([a-z])/ig,lb=/([A-Z])/g,mb=/^-?\d+(?:px)?$/i,nb=/^-?\d/,ob={position:"absolute",visibility:"hidden",display:"block"},pb=["Left","Right"],qb=["Top","Bottom"],rb=s.defaultView&&s.defaultView.getComputedStyle,Pa=c.support.cssFloat?"cssFloat":"styleFloat",ja=
function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){return X(this,a,b,true,function(d,f,e){if(e===w)return c.curCSS(d,f);if(typeof e==="number"&&!kb.test(f))e+="px";c.style(d,f,e)})};c.extend({style:function(a,b,d){if(!a||a.nodeType===3||a.nodeType===8)return w;if((b==="width"||b==="height")&&parseFloat(d)<0)d=w;var f=a.style||a,e=d!==w;if(!c.support.opacity&&b==="opacity"){if(e){f.zoom=1;b=parseInt(d,10)+""==="NaN"?"":"alpha(opacity="+d*100+")";a=f.filter||c.curCSS(a,"filter")||"";f.filter=
Na.test(a)?a.replace(Na,b):b}return f.filter&&f.filter.indexOf("opacity=")>=0?parseFloat(Oa.exec(f.filter)[1])/100+"":""}if(ha.test(b))b=Pa;b=b.replace(ia,ja);if(e)f[b]=d;return f[b]},css:function(a,b,d,f){if(b==="width"||b==="height"){var e,j=b==="width"?pb:qb;function i(){e=b==="width"?a.offsetWidth:a.offsetHeight;f!=="border"&&c.each(j,function(){f||(e-=parseFloat(c.curCSS(a,"padding"+this,true))||0);if(f==="margin")e+=parseFloat(c.curCSS(a,"margin"+this,true))||0;else e-=parseFloat(c.curCSS(a,
"border"+this+"Width",true))||0})}a.offsetWidth!==0?i():c.swap(a,ob,i);return Math.max(0,Math.round(e))}return c.curCSS(a,b,d)},curCSS:function(a,b,d){var f,e=a.style;if(!c.support.opacity&&b==="opacity"&&a.currentStyle){f=Oa.test(a.currentStyle.filter||"")?parseFloat(RegExp.$1)/100+"":"";return f===""?"1":f}if(ha.test(b))b=Pa;if(!d&&e&&e[b])f=e[b];else if(rb){if(ha.test(b))b="float";b=b.replace(lb,"-$1").toLowerCase();e=a.ownerDocument.defaultView;if(!e)return null;if(a=e.getComputedStyle(a,null))f=
a.getPropertyValue(b);if(b==="opacity"&&f==="")f="1"}else if(a.currentStyle){d=b.replace(ia,ja);f=a.currentStyle[b]||a.currentStyle[d];if(!mb.test(f)&&nb.test(f)){b=e.left;var j=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;e.left=d==="fontSize"?"1em":f||0;f=e.pixelLeft+"px";e.left=b;a.runtimeStyle.left=j}}return f},swap:function(a,b,d){var f={};for(var e in b){f[e]=a.style[e];a.style[e]=b[e]}d.call(a);for(e in b)a.style[e]=f[e]}});if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b=
a.offsetWidth,d=a.offsetHeight,f=a.nodeName.toLowerCase()==="tr";return b===0&&d===0&&!f?true:b>0&&d>0&&!f?false:c.curCSS(a,"display")==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var sb=J(),tb=/<script(.|\s)*?\/script>/gi,ub=/select|textarea/i,vb=/color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,N=/=\?(&|$)/,ka=/\?/,wb=/(\?|&)_=.*?(&|$)/,xb=/^(\w+:)?\/\/([^\/?#]+)/,yb=/%20/g,zb=c.fn.load;c.fn.extend({load:function(a,b,d){if(typeof a!==
"string")return zb.call(this,a);else if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var e=a.slice(f,a.length);a=a.slice(0,f)}f="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b==="object"){b=c.param(b,c.ajaxSettings.traditional);f="POST"}var j=this;c.ajax({url:a,type:f,dataType:"html",data:b,complete:function(i,o){if(o==="success"||o==="notmodified")j.html(e?c("<div />").append(i.responseText.replace(tb,"")).find(e):i.responseText);d&&j.each(d,[i.responseText,o,i])}});return this},
serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||ub.test(this.nodeName)||vb.test(this.type))}).map(function(a,b){a=c(this).val();return a==null?null:c.isArray(a)?c.map(a,function(d){return{name:b.name,value:d}}):{name:b.name,value:a}}).get()}});c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),
function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:f})},getScript:function(a,b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:f})},ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href,
global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:A.XMLHttpRequest&&(A.location.protocol!=="file:"||!A.ActiveXObject)?function(){return new A.XMLHttpRequest}:function(){try{return new A.ActiveXObject("Microsoft.XMLHTTP")}catch(a){}},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},etag:{},ajax:function(a){function b(){e.success&&
e.success.call(k,o,i,x);e.global&&f("ajaxSuccess",[x,e])}function d(){e.complete&&e.complete.call(k,x,i);e.global&&f("ajaxComplete",[x,e]);e.global&&!--c.active&&c.event.trigger("ajaxStop")}function f(q,p){(e.context?c(e.context):c.event).trigger(q,p)}var e=c.extend(true,{},c.ajaxSettings,a),j,i,o,k=a&&a.context||e,n=e.type.toUpperCase();if(e.data&&e.processData&&typeof e.data!=="string")e.data=c.param(e.data,e.traditional);if(e.dataType==="jsonp"){if(n==="GET")N.test(e.url)||(e.url+=(ka.test(e.url)?
"&":"?")+(e.jsonp||"callback")+"=?");else if(!e.data||!N.test(e.data))e.data=(e.data?e.data+"&":"")+(e.jsonp||"callback")+"=?";e.dataType="json"}if(e.dataType==="json"&&(e.data&&N.test(e.data)||N.test(e.url))){j=e.jsonpCallback||"jsonp"+sb++;if(e.data)e.data=(e.data+"").replace(N,"="+j+"$1");e.url=e.url.replace(N,"="+j+"$1");e.dataType="script";A[j]=A[j]||function(q){o=q;b();d();A[j]=w;try{delete A[j]}catch(p){}z&&z.removeChild(C)}}if(e.dataType==="script"&&e.cache===null)e.cache=false;if(e.cache===
false&&n==="GET"){var r=J(),u=e.url.replace(wb,"$1_="+r+"$2");e.url=u+(u===e.url?(ka.test(e.url)?"&":"?")+"_="+r:"")}if(e.data&&n==="GET")e.url+=(ka.test(e.url)?"&":"?")+e.data;e.global&&!c.active++&&c.event.trigger("ajaxStart");r=(r=xb.exec(e.url))&&(r[1]&&r[1]!==location.protocol||r[2]!==location.host);if(e.dataType==="script"&&n==="GET"&&r){var z=s.getElementsByTagName("head")[0]||s.documentElement,C=s.createElement("script");C.src=e.url;if(e.scriptCharset)C.charset=e.scriptCharset;if(!j){var B=
false;C.onload=C.onreadystatechange=function(){if(!B&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){B=true;b();d();C.onload=C.onreadystatechange=null;z&&C.parentNode&&z.removeChild(C)}}}z.insertBefore(C,z.firstChild);return w}var E=false,x=e.xhr();if(x){e.username?x.open(n,e.url,e.async,e.username,e.password):x.open(n,e.url,e.async);try{if(e.data||a&&a.contentType)x.setRequestHeader("Content-Type",e.contentType);if(e.ifModified){c.lastModified[e.url]&&x.setRequestHeader("If-Modified-Since",
c.lastModified[e.url]);c.etag[e.url]&&x.setRequestHeader("If-None-Match",c.etag[e.url])}r||x.setRequestHeader("X-Requested-With","XMLHttpRequest");x.setRequestHeader("Accept",e.dataType&&e.accepts[e.dataType]?e.accepts[e.dataType]+", */*":e.accepts._default)}catch(ga){}if(e.beforeSend&&e.beforeSend.call(k,x,e)===false){e.global&&!--c.active&&c.event.trigger("ajaxStop");x.abort();return false}e.global&&f("ajaxSend",[x,e]);var g=x.onreadystatechange=function(q){if(!x||x.readyState===0||q==="abort"){E||
d();E=true;if(x)x.onreadystatechange=c.noop}else if(!E&&x&&(x.readyState===4||q==="timeout")){E=true;x.onreadystatechange=c.noop;i=q==="timeout"?"timeout":!c.httpSuccess(x)?"error":e.ifModified&&c.httpNotModified(x,e.url)?"notmodified":"success";var p;if(i==="success")try{o=c.httpData(x,e.dataType,e)}catch(v){i="parsererror";p=v}if(i==="success"||i==="notmodified")j||b();else c.handleError(e,x,i,p);d();q==="timeout"&&x.abort();if(e.async)x=null}};try{var h=x.abort;x.abort=function(){x&&h.call(x);
g("abort")}}catch(l){}e.async&&e.timeout>0&&setTimeout(function(){x&&!E&&g("timeout")},e.timeout);try{x.send(n==="POST"||n==="PUT"||n==="DELETE"?e.data:null)}catch(m){c.handleError(e,x,null,m);d()}e.async||g();return x}},handleError:function(a,b,d,f){if(a.error)a.error.call(a.context||a,b,d,f);if(a.global)(a.context?c(a.context):c.event).trigger("ajaxError",[b,a,f])},active:0,httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status===304||a.status===
1223||a.status===0}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),f=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(f)c.etag[b]=f;return a.status===304||a.status===0},httpData:function(a,b,d){var f=a.getResponseHeader("content-type")||"",e=b==="xml"||!b&&f.indexOf("xml")>=0;a=e?a.responseXML:a.responseText;e&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b===
"json"||!b&&f.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&f.indexOf("javascript")>=0)c.globalEval(a);return a},param:function(a,b){function d(i,o){if(c.isArray(o))c.each(o,function(k,n){b||/\[\]$/.test(i)?f(i,n):d(i+"["+(typeof n==="object"||c.isArray(n)?k:"")+"]",n)});else!b&&o!=null&&typeof o==="object"?c.each(o,function(k,n){d(i+"["+k+"]",n)}):f(i,o)}function f(i,o){o=c.isFunction(o)?o():o;e[e.length]=encodeURIComponent(i)+"="+encodeURIComponent(o)}var e=[];if(b===w)b=c.ajaxSettings.traditional;
if(c.isArray(a)||a.jquery)c.each(a,function(){f(this.name,this.value)});else for(var j in a)d(j,a[j]);return e.join("&").replace(yb,"+")}});var la={},Ab=/toggle|show|hide/,Bb=/^([+-]=)?([\d+-.]+)(.*)$/,W,va=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b){if(a||a===0)return this.animate(K("show",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");
this[a].style.display=d||"";if(c.css(this[a],"display")==="none"){d=this[a].nodeName;var f;if(la[d])f=la[d];else{var e=c("<"+d+" />").appendTo("body");f=e.css("display");if(f==="none")f="block";e.remove();la[d]=f}c.data(this[a],"olddisplay",f)}}a=0;for(b=this.length;a<b;a++)this[a].style.display=c.data(this[a],"olddisplay")||"";return this}},hide:function(a,b){if(a||a===0)return this.animate(K("hide",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");!d&&d!=="none"&&c.data(this[a],
"olddisplay",c.css(this[a],"display"))}a=0;for(b=this.length;a<b;a++)this[a].style.display="none";return this}},_toggle:c.fn.toggle,toggle:function(a,b){var d=typeof a==="boolean";if(c.isFunction(a)&&c.isFunction(b))this._toggle.apply(this,arguments);else a==null||d?this.each(function(){var f=d?a:c(this).is(":hidden");c(this)[f?"show":"hide"]()}):this.animate(K("toggle",3),a,b);return this},fadeTo:function(a,b,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,d)},
animate:function(a,b,d,f){var e=c.speed(b,d,f);if(c.isEmptyObject(a))return this.each(e.complete);return this[e.queue===false?"each":"queue"](function(){var j=c.extend({},e),i,o=this.nodeType===1&&c(this).is(":hidden"),k=this;for(i in a){var n=i.replace(ia,ja);if(i!==n){a[n]=a[i];delete a[i];i=n}if(a[i]==="hide"&&o||a[i]==="show"&&!o)return j.complete.call(this);if((i==="height"||i==="width")&&this.style){j.display=c.css(this,"display");j.overflow=this.style.overflow}if(c.isArray(a[i])){(j.specialEasing=
j.specialEasing||{})[i]=a[i][1];a[i]=a[i][0]}}if(j.overflow!=null)this.style.overflow="hidden";j.curAnim=c.extend({},a);c.each(a,function(r,u){var z=new c.fx(k,j,r);if(Ab.test(u))z[u==="toggle"?o?"show":"hide":u](a);else{var C=Bb.exec(u),B=z.cur(true)||0;if(C){u=parseFloat(C[2]);var E=C[3]||"px";if(E!=="px"){k.style[r]=(u||1)+E;B=(u||1)/z.cur(true)*B;k.style[r]=B+E}if(C[1])u=(C[1]==="-="?-1:1)*u+B;z.custom(B,u,E)}else z.custom(B,u,"")}});return true})},stop:function(a,b){var d=c.timers;a&&this.queue([]);
this.each(function(){for(var f=d.length-1;f>=0;f--)if(d[f].elem===this){b&&d[f](true);d.splice(f,1)}});b||this.dequeue();return this}});c.each({slideDown:K("show",1),slideUp:K("hide",1),slideToggle:K("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(a,b){c.fn[a]=function(d,f){return this.animate(b,d,f)}});c.extend({speed:function(a,b,d){var f=a&&typeof a==="object"?a:{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};f.duration=c.fx.off?0:typeof f.duration===
"number"?f.duration:c.fx.speeds[f.duration]||c.fx.speeds._default;f.old=f.complete;f.complete=function(){f.queue!==false&&c(this).dequeue();c.isFunction(f.old)&&f.old.call(this)};return f},easing:{linear:function(a,b,d,f){return d+f*a},swing:function(a,b,d,f){return(-Math.cos(a*Math.PI)/2+0.5)*f+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]||
c.fx.step._default)(this);if((this.prop==="height"||this.prop==="width")&&this.elem.style)this.elem.style.display="block"},cur:function(a){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];return(a=parseFloat(c.css(this.elem,this.prop,a)))&&a>-10000?a:parseFloat(c.curCSS(this.elem,this.prop))||0},custom:function(a,b,d){function f(j){return e.step(j)}this.startTime=J();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start;
this.pos=this.state=0;var e=this;f.elem=this.elem;if(f()&&c.timers.push(f)&&!W)W=setInterval(c.fx.tick,13)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(a){var b=J(),d=true;if(a||b>=this.options.duration+this.startTime){this.now=
this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var f in this.options.curAnim)if(this.options.curAnim[f]!==true)d=false;if(d){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;a=c.data(this.elem,"olddisplay");this.elem.style.display=a?a:this.options.display;if(c.css(this.elem,"display")==="none")this.elem.style.display="block"}this.options.hide&&c(this.elem).hide();if(this.options.hide||this.options.show)for(var e in this.options.curAnim)c.style(this.elem,
e,this.options.orig[e]);this.options.complete.call(this.elem)}return false}else{e=b-this.startTime;this.state=e/this.options.duration;a=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||a](this.state,e,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a=c.timers,b=0;b<a.length;b++)a[b]()||a.splice(b--,1);a.length||
c.fx.stop()},stop:function(){clearInterval(W);W=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){c.style(a.elem,"opacity",a.now)},_default:function(a){if(a.elem.style&&a.elem.style[a.prop]!=null)a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit;else a.elem[a.prop]=a.now}}});if(c.expr&&c.expr.filters)c.expr.filters.animated=function(a){return c.grep(c.timers,function(b){return a===b.elem}).length};c.fn.offset="getBoundingClientRect"in s.documentElement?
function(a){var b=this[0];if(a)return this.each(function(e){c.offset.setOffset(this,a,e)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);var d=b.getBoundingClientRect(),f=b.ownerDocument;b=f.body;f=f.documentElement;return{top:d.top+(self.pageYOffset||c.support.boxModel&&f.scrollTop||b.scrollTop)-(f.clientTop||b.clientTop||0),left:d.left+(self.pageXOffset||c.support.boxModel&&f.scrollLeft||b.scrollLeft)-(f.clientLeft||b.clientLeft||0)}}:function(a){var b=
this[0];if(a)return this.each(function(r){c.offset.setOffset(this,a,r)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);c.offset.initialize();var d=b.offsetParent,f=b,e=b.ownerDocument,j,i=e.documentElement,o=e.body;f=(e=e.defaultView)?e.getComputedStyle(b,null):b.currentStyle;for(var k=b.offsetTop,n=b.offsetLeft;(b=b.parentNode)&&b!==o&&b!==i;){if(c.offset.supportsFixedPosition&&f.position==="fixed")break;j=e?e.getComputedStyle(b,null):b.currentStyle;
k-=b.scrollTop;n-=b.scrollLeft;if(b===d){k+=b.offsetTop;n+=b.offsetLeft;if(c.offset.doesNotAddBorder&&!(c.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(b.nodeName))){k+=parseFloat(j.borderTopWidth)||0;n+=parseFloat(j.borderLeftWidth)||0}f=d;d=b.offsetParent}if(c.offset.subtractsBorderForOverflowNotVisible&&j.overflow!=="visible"){k+=parseFloat(j.borderTopWidth)||0;n+=parseFloat(j.borderLeftWidth)||0}f=j}if(f.position==="relative"||f.position==="static"){k+=o.offsetTop;n+=o.offsetLeft}if(c.offset.supportsFixedPosition&&
f.position==="fixed"){k+=Math.max(i.scrollTop,o.scrollTop);n+=Math.max(i.scrollLeft,o.scrollLeft)}return{top:k,left:n}};c.offset={initialize:function(){var a=s.body,b=s.createElement("div"),d,f,e,j=parseFloat(c.curCSS(a,"marginTop",true))||0;c.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"});b.innerHTML="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";
a.insertBefore(b,a.firstChild);d=b.firstChild;f=d.firstChild;e=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=f.offsetTop!==5;this.doesAddBorderForTableAndCells=e.offsetTop===5;f.style.position="fixed";f.style.top="20px";this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15;f.style.position=f.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==j;a.removeChild(b);
c.offset.initialize=c.noop},bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.curCSS(a,"marginTop",true))||0;d+=parseFloat(c.curCSS(a,"marginLeft",true))||0}return{top:b,left:d}},setOffset:function(a,b,d){if(/static/.test(c.curCSS(a,"position")))a.style.position="relative";var f=c(a),e=f.offset(),j=parseInt(c.curCSS(a,"top",true),10)||0,i=parseInt(c.curCSS(a,"left",true),10)||0;if(c.isFunction(b))b=b.call(a,
d,e);d={top:b.top-e.top+j,left:b.left-e.left+i};"using"in b?b.using.call(a,d):f.css(d)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),f=/^body|html$/i.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.curCSS(a,"marginTop",true))||0;d.left-=parseFloat(c.curCSS(a,"marginLeft",true))||0;f.top+=parseFloat(c.curCSS(b[0],"borderTopWidth",true))||0;f.left+=parseFloat(c.curCSS(b[0],"borderLeftWidth",true))||0;return{top:d.top-
f.top,left:d.left-f.left}},offsetParent:function(){return this.map(function(){for(var a=this.offsetParent||s.body;a&&!/^body|html$/i.test(a.nodeName)&&c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(f){var e=this[0],j;if(!e)return null;if(f!==w)return this.each(function(){if(j=wa(this))j.scrollTo(!a?f:c(j).scrollLeft(),a?f:c(j).scrollTop());else this[d]=f});else return(j=wa(e))?"pageXOffset"in j?j[a?"pageYOffset":
"pageXOffset"]:c.support.boxModel&&j.document.documentElement[d]||j.document.body[d]:e[d]}});c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();c.fn["inner"+b]=function(){return this[0]?c.css(this[0],d,false,"padding"):null};c.fn["outer"+b]=function(f){return this[0]?c.css(this[0],d,false,f?"margin":"border"):null};c.fn[d]=function(f){var e=this[0];if(!e)return f==null?null:this;if(c.isFunction(f))return this.each(function(j){var i=c(this);i[d](f.call(this,j,i[d]()))});return"scrollTo"in
e&&e.document?e.document.compatMode==="CSS1Compat"&&e.document.documentElement["client"+b]||e.document.body["client"+b]:e.nodeType===9?Math.max(e.documentElement["client"+b],e.body["scroll"+b],e.documentElement["scroll"+b],e.body["offset"+b],e.documentElement["offset"+b]):f===w?c.css(e,d):this.css(d,typeof f==="string"?f:f+"px")}});A.jQuery=A.$=c})(window);

Binary file not shown.

After

Width:  |  Height:  |  Size: 199 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 199 B

View File

@ -0,0 +1,62 @@
.highlight .hll { background-color: #ffffcc }
.highlight { background: #eeffcc; }
.highlight .c { color: #408090; font-style: italic } /* Comment */
.highlight .err { border: 1px solid #FF0000 } /* Error */
.highlight .k { color: #007020; font-weight: bold } /* Keyword */
.highlight .o { color: #666666 } /* Operator */
.highlight .cm { color: #408090; font-style: italic } /* Comment.Multiline */
.highlight .cp { color: #007020 } /* Comment.Preproc */
.highlight .c1 { color: #408090; font-style: italic } /* Comment.Single */
.highlight .cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #A00000 } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gr { color: #FF0000 } /* Generic.Error */
.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
.highlight .gi { color: #00A000 } /* Generic.Inserted */
.highlight .go { color: #303030 } /* Generic.Output */
.highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
.highlight .gt { color: #0040D0 } /* Generic.Traceback */
.highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #007020 } /* Keyword.Pseudo */
.highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #902000 } /* Keyword.Type */
.highlight .m { color: #208050 } /* Literal.Number */
.highlight .s { color: #4070a0 } /* Literal.String */
.highlight .na { color: #4070a0 } /* Name.Attribute */
.highlight .nb { color: #007020 } /* Name.Builtin */
.highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */
.highlight .no { color: #60add5 } /* Name.Constant */
.highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */
.highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */
.highlight .ne { color: #007020 } /* Name.Exception */
.highlight .nf { color: #06287e } /* Name.Function */
.highlight .nl { color: #002070; font-weight: bold } /* Name.Label */
.highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */
.highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #bb60d5 } /* Name.Variable */
.highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mf { color: #208050 } /* Literal.Number.Float */
.highlight .mh { color: #208050 } /* Literal.Number.Hex */
.highlight .mi { color: #208050 } /* Literal.Number.Integer */
.highlight .mo { color: #208050 } /* Literal.Number.Oct */
.highlight .sb { color: #4070a0 } /* Literal.String.Backtick */
.highlight .sc { color: #4070a0 } /* Literal.String.Char */
.highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */
.highlight .s2 { color: #4070a0 } /* Literal.String.Double */
.highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */
.highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */
.highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */
.highlight .sx { color: #c65d09 } /* Literal.String.Other */
.highlight .sr { color: #235388 } /* Literal.String.Regex */
.highlight .s1 { color: #4070a0 } /* Literal.String.Single */
.highlight .ss { color: #517918 } /* Literal.String.Symbol */
.highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */
.highlight .vc { color: #bb60d5 } /* Name.Variable.Class */
.highlight .vg { color: #bb60d5 } /* Name.Variable.Global */
.highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */
.highlight .il { color: #208050 } /* Literal.Number.Integer.Long */

View File

@ -0,0 +1,560 @@
/*
* searchtools.js_t
* ~~~~~~~~~~~~~~~~
*
* Sphinx JavaScript utilties for the full-text search.
*
* :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
/**
* helper function to return a node containing the
* search summary for a given text. keywords is a list
* of stemmed words, hlwords is the list of normal, unstemmed
* words. the first one is used to find the occurance, the
* latter for highlighting it.
*/
jQuery.makeSearchSummary = function(text, keywords, hlwords) {
var textLower = text.toLowerCase();
var start = 0;
$.each(keywords, function() {
var i = textLower.indexOf(this.toLowerCase());
if (i > -1)
start = i;
});
start = Math.max(start - 120, 0);
var excerpt = ((start > 0) ? '...' : '') +
$.trim(text.substr(start, 240)) +
((start + 240 - text.length) ? '...' : '');
var rv = $('<div class="context"></div>').text(excerpt);
$.each(hlwords, function() {
rv = rv.highlightText(this, 'highlighted');
});
return rv;
}
/**
* Porter Stemmer
*/
var Stemmer = function() {
var step2list = {
ational: 'ate',
tional: 'tion',
enci: 'ence',
anci: 'ance',
izer: 'ize',
bli: 'ble',
alli: 'al',
entli: 'ent',
eli: 'e',
ousli: 'ous',
ization: 'ize',
ation: 'ate',
ator: 'ate',
alism: 'al',
iveness: 'ive',
fulness: 'ful',
ousness: 'ous',
aliti: 'al',
iviti: 'ive',
biliti: 'ble',
logi: 'log'
};
var step3list = {
icate: 'ic',
ative: '',
alize: 'al',
iciti: 'ic',
ical: 'ic',
ful: '',
ness: ''
};
var c = "[^aeiou]"; // consonant
var v = "[aeiouy]"; // vowel
var C = c + "[^aeiouy]*"; // consonant sequence
var V = v + "[aeiou]*"; // vowel sequence
var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0
var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1
var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1
var s_v = "^(" + C + ")?" + v; // vowel in stem
this.stemWord = function (w) {
var stem;
var suffix;
var firstch;
var origword = w;
if (w.length < 3)
return w;
var re;
var re2;
var re3;
var re4;
firstch = w.substr(0,1);
if (firstch == "y")
w = firstch.toUpperCase() + w.substr(1);
// Step 1a
re = /^(.+?)(ss|i)es$/;
re2 = /^(.+?)([^s])s$/;
if (re.test(w))
w = w.replace(re,"$1$2");
else if (re2.test(w))
w = w.replace(re2,"$1$2");
// Step 1b
re = /^(.+?)eed$/;
re2 = /^(.+?)(ed|ing)$/;
if (re.test(w)) {
var fp = re.exec(w);
re = new RegExp(mgr0);
if (re.test(fp[1])) {
re = /.$/;
w = w.replace(re,"");
}
}
else if (re2.test(w)) {
var fp = re2.exec(w);
stem = fp[1];
re2 = new RegExp(s_v);
if (re2.test(stem)) {
w = stem;
re2 = /(at|bl|iz)$/;
re3 = new RegExp("([^aeiouylsz])\\1$");
re4 = new RegExp("^" + C + v + "[^aeiouwxy]$");
if (re2.test(w))
w = w + "e";
else if (re3.test(w)) {
re = /.$/;
w = w.replace(re,"");
}
else if (re4.test(w))
w = w + "e";
}
}
// Step 1c
re = /^(.+?)y$/;
if (re.test(w)) {
var fp = re.exec(w);
stem = fp[1];
re = new RegExp(s_v);
if (re.test(stem))
w = stem + "i";
}
// Step 2
re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/;
if (re.test(w)) {
var fp = re.exec(w);
stem = fp[1];
suffix = fp[2];
re = new RegExp(mgr0);
if (re.test(stem))
w = stem + step2list[suffix];
}
// Step 3
re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/;
if (re.test(w)) {
var fp = re.exec(w);
stem = fp[1];
suffix = fp[2];
re = new RegExp(mgr0);
if (re.test(stem))
w = stem + step3list[suffix];
}
// Step 4
re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/;
re2 = /^(.+?)(s|t)(ion)$/;
if (re.test(w)) {
var fp = re.exec(w);
stem = fp[1];
re = new RegExp(mgr1);
if (re.test(stem))
w = stem;
}
else if (re2.test(w)) {
var fp = re2.exec(w);
stem = fp[1] + fp[2];
re2 = new RegExp(mgr1);
if (re2.test(stem))
w = stem;
}
// Step 5
re = /^(.+?)e$/;
if (re.test(w)) {
var fp = re.exec(w);
stem = fp[1];
re = new RegExp(mgr1);
re2 = new RegExp(meq1);
re3 = new RegExp("^" + C + v + "[^aeiouwxy]$");
if (re.test(stem) || (re2.test(stem) && !(re3.test(stem))))
w = stem;
}
re = /ll$/;
re2 = new RegExp(mgr1);
if (re.test(w) && re2.test(w)) {
re = /.$/;
w = w.replace(re,"");
}
// and turn initial Y back to y
if (firstch == "y")
w = firstch.toLowerCase() + w.substr(1);
return w;
}
}
/**
* Search Module
*/
var Search = {
_index : null,
_queued_query : null,
_pulse_status : -1,
init : function() {
var params = $.getQueryParameters();
if (params.q) {
var query = params.q[0];
$('input[name="q"]')[0].value = query;
this.performSearch(query);
}
},
loadIndex : function(url) {
$.ajax({type: "GET", url: url, data: null, success: null,
dataType: "script", cache: true});
},
setIndex : function(index) {
var q;
this._index = index;
if ((q = this._queued_query) !== null) {
this._queued_query = null;
Search.query(q);
}
},
hasIndex : function() {
return this._index !== null;
},
deferQuery : function(query) {
this._queued_query = query;
},
stopPulse : function() {
this._pulse_status = 0;
},
startPulse : function() {
if (this._pulse_status >= 0)
return;
function pulse() {
Search._pulse_status = (Search._pulse_status + 1) % 4;
var dotString = '';
for (var i = 0; i < Search._pulse_status; i++)
dotString += '.';
Search.dots.text(dotString);
if (Search._pulse_status > -1)
window.setTimeout(pulse, 500);
};
pulse();
},
/**
* perform a search for something
*/
performSearch : function(query) {
// create the required interface elements
this.out = $('#search-results');
this.title = $('<h2>' + _('Searching') + '</h2>').appendTo(this.out);
this.dots = $('<span></span>').appendTo(this.title);
this.status = $('<p style="display: none"></p>').appendTo(this.out);
this.output = $('<ul class="search"/>').appendTo(this.out);
$('#search-progress').text(_('Preparing search...'));
this.startPulse();
// index already loaded, the browser was quick!
if (this.hasIndex())
this.query(query);
else
this.deferQuery(query);
},
query : function(query) {
var stopwords = ["and","then","into","it","as","are","in","if","for","no","there","their","was","is","be","to","that","but","they","not","such","with","by","a","on","these","of","will","this","near","the","or","at"];
// Stem the searchterms and add them to the correct list
var stemmer = new Stemmer();
var searchterms = [];
var excluded = [];
var hlterms = [];
var tmp = query.split(/\s+/);
var objectterms = [];
for (var i = 0; i < tmp.length; i++) {
if (tmp[i] != "") {
objectterms.push(tmp[i].toLowerCase());
}
if ($u.indexOf(stopwords, tmp[i]) != -1 || tmp[i].match(/^\d+$/) ||
tmp[i] == "") {
// skip this "word"
continue;
}
// stem the word
var word = stemmer.stemWord(tmp[i]).toLowerCase();
// select the correct list
if (word[0] == '-') {
var toAppend = excluded;
word = word.substr(1);
}
else {
var toAppend = searchterms;
hlterms.push(tmp[i].toLowerCase());
}
// only add if not already in the list
if (!$.contains(toAppend, word))
toAppend.push(word);
};
var highlightstring = '?highlight=' + $.urlencode(hlterms.join(" "));
// console.debug('SEARCH: searching for:');
// console.info('required: ', searchterms);
// console.info('excluded: ', excluded);
// prepare search
var filenames = this._index.filenames;
var titles = this._index.titles;
var terms = this._index.terms;
var fileMap = {};
var files = null;
// different result priorities
var importantResults = [];
var objectResults = [];
var regularResults = [];
var unimportantResults = [];
$('#search-progress').empty();
// lookup as object
for (var i = 0; i < objectterms.length; i++) {
var others = [].concat(objectterms.slice(0,i),
objectterms.slice(i+1, objectterms.length))
var results = this.performObjectSearch(objectterms[i], others);
// Assume first word is most likely to be the object,
// other words more likely to be in description.
// Therefore put matches for earlier words first.
// (Results are eventually used in reverse order).
objectResults = results[0].concat(objectResults);
importantResults = results[1].concat(importantResults);
unimportantResults = results[2].concat(unimportantResults);
}
// perform the search on the required terms
for (var i = 0; i < searchterms.length; i++) {
var word = searchterms[i];
// no match but word was a required one
if ((files = terms[word]) == null)
break;
if (files.length == undefined) {
files = [files];
}
// create the mapping
for (var j = 0; j < files.length; j++) {
var file = files[j];
if (file in fileMap)
fileMap[file].push(word);
else
fileMap[file] = [word];
}
}
// now check if the files don't contain excluded terms
for (var file in fileMap) {
var valid = true;
// check if all requirements are matched
if (fileMap[file].length != searchterms.length)
continue;
// ensure that none of the excluded terms is in the
// search result.
for (var i = 0; i < excluded.length; i++) {
if (terms[excluded[i]] == file ||
$.contains(terms[excluded[i]] || [], file)) {
valid = false;
break;
}
}
// if we have still a valid result we can add it
// to the result list
if (valid)
regularResults.push([filenames[file], titles[file], '', null]);
}
// delete unused variables in order to not waste
// memory until list is retrieved completely
delete filenames, titles, terms;
// now sort the regular results descending by title
regularResults.sort(function(a, b) {
var left = a[1].toLowerCase();
var right = b[1].toLowerCase();
return (left > right) ? -1 : ((left < right) ? 1 : 0);
});
// combine all results
var results = unimportantResults.concat(regularResults)
.concat(objectResults).concat(importantResults);
// print the results
var resultCount = results.length;
function displayNextItem() {
// results left, load the summary and display it
if (results.length) {
var item = results.pop();
var listItem = $('<li style="display:none"></li>');
if (DOCUMENTATION_OPTIONS.FILE_SUFFIX == '') {
// dirhtml builder
var dirname = item[0] + '/';
if (dirname.match(/\/index\/$/)) {
dirname = dirname.substring(0, dirname.length-6);
} else if (dirname == 'index/') {
dirname = '';
}
listItem.append($('<a/>').attr('href',
DOCUMENTATION_OPTIONS.URL_ROOT + dirname +
highlightstring + item[2]).html(item[1]));
} else {
// normal html builders
listItem.append($('<a/>').attr('href',
item[0] + DOCUMENTATION_OPTIONS.FILE_SUFFIX +
highlightstring + item[2]).html(item[1]));
}
if (item[3]) {
listItem.append($('<span> (' + item[3] + ')</span>'));
Search.output.append(listItem);
listItem.slideDown(5, function() {
displayNextItem();
});
} else if (DOCUMENTATION_OPTIONS.HAS_SOURCE) {
$.get(DOCUMENTATION_OPTIONS.URL_ROOT + '_sources/' +
item[0] + '.txt', function(data) {
if (data != '') {
listItem.append($.makeSearchSummary(data, searchterms, hlterms));
Search.output.append(listItem);
}
listItem.slideDown(5, function() {
displayNextItem();
});
}, "text");
} else {
// no source available, just display title
Search.output.append(listItem);
listItem.slideDown(5, function() {
displayNextItem();
});
}
}
// search finished, update title and status message
else {
Search.stopPulse();
Search.title.text(_('Search Results'));
if (!resultCount)
Search.status.text(_('Your search did not match any documents. Please make sure that all words are spelled correctly and that you\'ve selected enough categories.'));
else
Search.status.text(_('Search finished, found %s page(s) matching the search query.').replace('%s', resultCount));
Search.status.fadeIn(500);
}
}
displayNextItem();
},
performObjectSearch : function(object, otherterms) {
var filenames = this._index.filenames;
var objects = this._index.objects;
var objnames = this._index.objnames;
var titles = this._index.titles;
var importantResults = [];
var objectResults = [];
var unimportantResults = [];
for (var prefix in objects) {
for (var name in objects[prefix]) {
var fullname = (prefix ? prefix + '.' : '') + name;
if (fullname.toLowerCase().indexOf(object) > -1) {
var match = objects[prefix][name];
var objname = objnames[match[1]][2];
var title = titles[match[0]];
// If more than one term searched for, we require other words to be
// found in the name/title/description
if (otherterms.length > 0) {
var haystack = (prefix + ' ' + name + ' ' +
objname + ' ' + title).toLowerCase();
var allfound = true;
for (var i = 0; i < otherterms.length; i++) {
if (haystack.indexOf(otherterms[i]) == -1) {
allfound = false;
break;
}
}
if (!allfound) {
continue;
}
}
var descr = objname + _(', in ') + title;
anchor = match[3];
if (anchor == '')
anchor = fullname;
else if (anchor == '-')
anchor = objnames[match[1]][1] + '-' + fullname;
result = [filenames[match[0]], fullname, '#'+anchor, descr];
switch (match[2]) {
case 1: objectResults.push(result); break;
case 0: importantResults.push(result); break;
case 2: unimportantResults.push(result); break;
}
}
}
}
// sort results descending
objectResults.sort(function(a, b) {
return (a[1] > b[1]) ? -1 : ((a[1] < b[1]) ? 1 : 0);
});
importantResults.sort(function(a, b) {
return (a[1] > b[1]) ? -1 : ((a[1] < b[1]) ? 1 : 0);
});
unimportantResults.sort(function(a, b) {
return (a[1] > b[1]) ? -1 : ((a[1] < b[1]) ? 1 : 0);
});
return [importantResults, objectResults, unimportantResults]
}
}
$(document).ready(function() {
Search.init();
});

View File

@ -0,0 +1,151 @@
/*
* sidebar.js
* ~~~~~~~~~~
*
* This script makes the Sphinx sidebar collapsible.
*
* .sphinxsidebar contains .sphinxsidebarwrapper. This script adds
* in .sphixsidebar, after .sphinxsidebarwrapper, the #sidebarbutton
* used to collapse and expand the sidebar.
*
* When the sidebar is collapsed the .sphinxsidebarwrapper is hidden
* and the width of the sidebar and the margin-left of the document
* are decreased. When the sidebar is expanded the opposite happens.
* This script saves a per-browser/per-session cookie used to
* remember the position of the sidebar among the pages.
* Once the browser is closed the cookie is deleted and the position
* reset to the default (expanded).
*
* :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
$(function() {
// global elements used by the functions.
// the 'sidebarbutton' element is defined as global after its
// creation, in the add_sidebar_button function
var bodywrapper = $('.bodywrapper');
var sidebar = $('.sphinxsidebar');
var sidebarwrapper = $('.sphinxsidebarwrapper');
// for some reason, the document has no sidebar; do not run into errors
if (!sidebar.length) return;
// original margin-left of the bodywrapper and width of the sidebar
// with the sidebar expanded
var bw_margin_expanded = bodywrapper.css('margin-left');
var ssb_width_expanded = sidebar.width();
// margin-left of the bodywrapper and width of the sidebar
// with the sidebar collapsed
var bw_margin_collapsed = '.8em';
var ssb_width_collapsed = '.8em';
// colors used by the current theme
var dark_color = $('.related').css('background-color');
var light_color = $('.document').css('background-color');
function sidebar_is_collapsed() {
return sidebarwrapper.is(':not(:visible)');
}
function toggle_sidebar() {
if (sidebar_is_collapsed())
expand_sidebar();
else
collapse_sidebar();
}
function collapse_sidebar() {
sidebarwrapper.hide();
sidebar.css('width', ssb_width_collapsed);
bodywrapper.css('margin-left', bw_margin_collapsed);
sidebarbutton.css({
'margin-left': '0',
'height': bodywrapper.height()
});
sidebarbutton.find('span').text('»');
sidebarbutton.attr('title', _('Expand sidebar'));
document.cookie = 'sidebar=collapsed';
}
function expand_sidebar() {
bodywrapper.css('margin-left', bw_margin_expanded);
sidebar.css('width', ssb_width_expanded);
sidebarwrapper.show();
sidebarbutton.css({
'margin-left': ssb_width_expanded-12,
'height': bodywrapper.height()
});
sidebarbutton.find('span').text('«');
sidebarbutton.attr('title', _('Collapse sidebar'));
document.cookie = 'sidebar=expanded';
}
function add_sidebar_button() {
sidebarwrapper.css({
'float': 'left',
'margin-right': '0',
'width': ssb_width_expanded - 28
});
// create the button
sidebar.append(
'<div id="sidebarbutton"><span>&laquo;</span></div>'
);
var sidebarbutton = $('#sidebarbutton');
light_color = sidebarbutton.css('background-color');
// find the height of the viewport to center the '<<' in the page
var viewport_height;
if (window.innerHeight)
viewport_height = window.innerHeight;
else
viewport_height = $(window).height();
sidebarbutton.find('span').css({
'display': 'block',
'margin-top': (viewport_height - sidebar.position().top - 20) / 2
});
sidebarbutton.click(toggle_sidebar);
sidebarbutton.attr('title', _('Collapse sidebar'));
sidebarbutton.css({
'color': '#FFFFFF',
'border-left': '1px solid ' + dark_color,
'font-size': '1.2em',
'cursor': 'pointer',
'height': bodywrapper.height(),
'padding-top': '1px',
'margin-left': ssb_width_expanded - 12
});
sidebarbutton.hover(
function () {
$(this).css('background-color', dark_color);
},
function () {
$(this).css('background-color', light_color);
}
);
}
function set_position_from_cookie() {
if (!document.cookie)
return;
var items = document.cookie.split(';');
for(var k=0; k<items.length; k++) {
var key_val = items[k].split('=');
var key = key_val[0];
if (key == 'sidebar') {
var value = key_val[1];
if ((value == 'collapsed') && (!sidebar_is_collapsed()))
collapse_sidebar();
else if ((value == 'expanded') && (sidebar_is_collapsed()))
expand_sidebar();
}
}
}
add_sidebar_button();
var sidebarbutton = $('#sidebarbutton');
set_position_from_cookie();
});

View File

@ -0,0 +1,999 @@
// Underscore.js 1.3.1
// (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.
// Underscore is freely distributable under the MIT license.
// Portions of Underscore are inspired or borrowed from Prototype,
// Oliver Steele's Functional, and John Resig's Micro-Templating.
// For all details and documentation:
// http://documentcloud.github.com/underscore
(function() {
// Baseline setup
// --------------
// Establish the root object, `window` in the browser, or `global` on the server.
var root = this;
// Save the previous value of the `_` variable.
var previousUnderscore = root._;
// Establish the object that gets returned to break out of a loop iteration.
var breaker = {};
// Save bytes in the minified (but not gzipped) version:
var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
// Create quick reference variables for speed access to core prototypes.
var slice = ArrayProto.slice,
unshift = ArrayProto.unshift,
toString = ObjProto.toString,
hasOwnProperty = ObjProto.hasOwnProperty;
// All **ECMAScript 5** native function implementations that we hope to use
// are declared here.
var
nativeForEach = ArrayProto.forEach,
nativeMap = ArrayProto.map,
nativeReduce = ArrayProto.reduce,
nativeReduceRight = ArrayProto.reduceRight,
nativeFilter = ArrayProto.filter,
nativeEvery = ArrayProto.every,
nativeSome = ArrayProto.some,
nativeIndexOf = ArrayProto.indexOf,
nativeLastIndexOf = ArrayProto.lastIndexOf,
nativeIsArray = Array.isArray,
nativeKeys = Object.keys,
nativeBind = FuncProto.bind;
// Create a safe reference to the Underscore object for use below.
var _ = function(obj) { return new wrapper(obj); };
// Export the Underscore object for **Node.js**, with
// backwards-compatibility for the old `require()` API. If we're in
// the browser, add `_` as a global object via a string identifier,
// for Closure Compiler "advanced" mode.
if (typeof exports !== 'undefined') {
if (typeof module !== 'undefined' && module.exports) {
exports = module.exports = _;
}
exports._ = _;
} else {
root['_'] = _;
}
// Current version.
_.VERSION = '1.3.1';
// Collection Functions
// --------------------
// The cornerstone, an `each` implementation, aka `forEach`.
// Handles objects with the built-in `forEach`, arrays, and raw objects.
// Delegates to **ECMAScript 5**'s native `forEach` if available.
var each = _.each = _.forEach = function(obj, iterator, context) {
if (obj == null) return;
if (nativeForEach && obj.forEach === nativeForEach) {
obj.forEach(iterator, context);
} else if (obj.length === +obj.length) {
for (var i = 0, l = obj.length; i < l; i++) {
if (i in obj && iterator.call(context, obj[i], i, obj) === breaker) return;
}
} else {
for (var key in obj) {
if (_.has(obj, key)) {
if (iterator.call(context, obj[key], key, obj) === breaker) return;
}
}
}
};
// Return the results of applying the iterator to each element.
// Delegates to **ECMAScript 5**'s native `map` if available.
_.map = _.collect = function(obj, iterator, context) {
var results = [];
if (obj == null) return results;
if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);
each(obj, function(value, index, list) {
results[results.length] = iterator.call(context, value, index, list);
});
if (obj.length === +obj.length) results.length = obj.length;
return results;
};
// **Reduce** builds up a single result from a list of values, aka `inject`,
// or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.
_.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {
var initial = arguments.length > 2;
if (obj == null) obj = [];
if (nativeReduce && obj.reduce === nativeReduce) {
if (context) iterator = _.bind(iterator, context);
return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);
}
each(obj, function(value, index, list) {
if (!initial) {
memo = value;
initial = true;
} else {
memo = iterator.call(context, memo, value, index, list);
}
});
if (!initial) throw new TypeError('Reduce of empty array with no initial value');
return memo;
};
// The right-associative version of reduce, also known as `foldr`.
// Delegates to **ECMAScript 5**'s native `reduceRight` if available.
_.reduceRight = _.foldr = function(obj, iterator, memo, context) {
var initial = arguments.length > 2;
if (obj == null) obj = [];
if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {
if (context) iterator = _.bind(iterator, context);
return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
}
var reversed = _.toArray(obj).reverse();
if (context && !initial) iterator = _.bind(iterator, context);
return initial ? _.reduce(reversed, iterator, memo, context) : _.reduce(reversed, iterator);
};
// Return the first value which passes a truth test. Aliased as `detect`.
_.find = _.detect = function(obj, iterator, context) {
var result;
any(obj, function(value, index, list) {
if (iterator.call(context, value, index, list)) {
result = value;
return true;
}
});
return result;
};
// Return all the elements that pass a truth test.
// Delegates to **ECMAScript 5**'s native `filter` if available.
// Aliased as `select`.
_.filter = _.select = function(obj, iterator, context) {
var results = [];
if (obj == null) return results;
if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);
each(obj, function(value, index, list) {
if (iterator.call(context, value, index, list)) results[results.length] = value;
});
return results;
};
// Return all the elements for which a truth test fails.
_.reject = function(obj, iterator, context) {
var results = [];
if (obj == null) return results;
each(obj, function(value, index, list) {
if (!iterator.call(context, value, index, list)) results[results.length] = value;
});
return results;
};
// Determine whether all of the elements match a truth test.
// Delegates to **ECMAScript 5**'s native `every` if available.
// Aliased as `all`.
_.every = _.all = function(obj, iterator, context) {
var result = true;
if (obj == null) return result;
if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);
each(obj, function(value, index, list) {
if (!(result = result && iterator.call(context, value, index, list))) return breaker;
});
return result;
};
// Determine if at least one element in the object matches a truth test.
// Delegates to **ECMAScript 5**'s native `some` if available.
// Aliased as `any`.
var any = _.some = _.any = function(obj, iterator, context) {
iterator || (iterator = _.identity);
var result = false;
if (obj == null) return result;
if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);
each(obj, function(value, index, list) {
if (result || (result = iterator.call(context, value, index, list))) return breaker;
});
return !!result;
};
// Determine if a given value is included in the array or object using `===`.
// Aliased as `contains`.
_.include = _.contains = function(obj, target) {
var found = false;
if (obj == null) return found;
if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
found = any(obj, function(value) {
return value === target;
});
return found;
};
// Invoke a method (with arguments) on every item in a collection.
_.invoke = function(obj, method) {
var args = slice.call(arguments, 2);
return _.map(obj, function(value) {
return (_.isFunction(method) ? method || value : value[method]).apply(value, args);
});
};
// Convenience version of a common use case of `map`: fetching a property.
_.pluck = function(obj, key) {
return _.map(obj, function(value){ return value[key]; });
};
// Return the maximum element or (element-based computation).
_.max = function(obj, iterator, context) {
if (!iterator && _.isArray(obj)) return Math.max.apply(Math, obj);
if (!iterator && _.isEmpty(obj)) return -Infinity;
var result = {computed : -Infinity};
each(obj, function(value, index, list) {
var computed = iterator ? iterator.call(context, value, index, list) : value;
computed >= result.computed && (result = {value : value, computed : computed});
});
return result.value;
};
// Return the minimum element (or element-based computation).
_.min = function(obj, iterator, context) {
if (!iterator && _.isArray(obj)) return Math.min.apply(Math, obj);
if (!iterator && _.isEmpty(obj)) return Infinity;
var result = {computed : Infinity};
each(obj, function(value, index, list) {
var computed = iterator ? iterator.call(context, value, index, list) : value;
computed < result.computed && (result = {value : value, computed : computed});
});
return result.value;
};
// Shuffle an array.
_.shuffle = function(obj) {
var shuffled = [], rand;
each(obj, function(value, index, list) {
if (index == 0) {
shuffled[0] = value;
} else {
rand = Math.floor(Math.random() * (index + 1));
shuffled[index] = shuffled[rand];
shuffled[rand] = value;
}
});
return shuffled;
};
// Sort the object's values by a criterion produced by an iterator.
_.sortBy = function(obj, iterator, context) {
return _.pluck(_.map(obj, function(value, index, list) {
return {
value : value,
criteria : iterator.call(context, value, index, list)
};
}).sort(function(left, right) {
var a = left.criteria, b = right.criteria;
return a < b ? -1 : a > b ? 1 : 0;
}), 'value');
};
// Groups the object's values by a criterion. Pass either a string attribute
// to group by, or a function that returns the criterion.
_.groupBy = function(obj, val) {
var result = {};
var iterator = _.isFunction(val) ? val : function(obj) { return obj[val]; };
each(obj, function(value, index) {
var key = iterator(value, index);
(result[key] || (result[key] = [])).push(value);
});
return result;
};
// Use a comparator function to figure out at what index an object should
// be inserted so as to maintain order. Uses binary search.
_.sortedIndex = function(array, obj, iterator) {
iterator || (iterator = _.identity);
var low = 0, high = array.length;
while (low < high) {
var mid = (low + high) >> 1;
iterator(array[mid]) < iterator(obj) ? low = mid + 1 : high = mid;
}
return low;
};
// Safely convert anything iterable into a real, live array.
_.toArray = function(iterable) {
if (!iterable) return [];
if (iterable.toArray) return iterable.toArray();
if (_.isArray(iterable)) return slice.call(iterable);
if (_.isArguments(iterable)) return slice.call(iterable);
return _.values(iterable);
};
// Return the number of elements in an object.
_.size = function(obj) {
return _.toArray(obj).length;
};
// Array Functions
// ---------------
// Get the first element of an array. Passing **n** will return the first N
// values in the array. Aliased as `head`. The **guard** check allows it to work
// with `_.map`.
_.first = _.head = function(array, n, guard) {
return (n != null) && !guard ? slice.call(array, 0, n) : array[0];
};
// Returns everything but the last entry of the array. Especcialy useful on
// the arguments object. Passing **n** will return all the values in
// the array, excluding the last N. The **guard** check allows it to work with
// `_.map`.
_.initial = function(array, n, guard) {
return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n));
};
// Get the last element of an array. Passing **n** will return the last N
// values in the array. The **guard** check allows it to work with `_.map`.
_.last = function(array, n, guard) {
if ((n != null) && !guard) {
return slice.call(array, Math.max(array.length - n, 0));
} else {
return array[array.length - 1];
}
};
// Returns everything but the first entry of the array. Aliased as `tail`.
// Especially useful on the arguments object. Passing an **index** will return
// the rest of the values in the array from that index onward. The **guard**
// check allows it to work with `_.map`.
_.rest = _.tail = function(array, index, guard) {
return slice.call(array, (index == null) || guard ? 1 : index);
};
// Trim out all falsy values from an array.
_.compact = function(array) {
return _.filter(array, function(value){ return !!value; });
};
// Return a completely flattened version of an array.
_.flatten = function(array, shallow) {
return _.reduce(array, function(memo, value) {
if (_.isArray(value)) return memo.concat(shallow ? value : _.flatten(value));
memo[memo.length] = value;
return memo;
}, []);
};
// Return a version of the array that does not contain the specified value(s).
_.without = function(array) {
return _.difference(array, slice.call(arguments, 1));
};
// Produce a duplicate-free version of the array. If the array has already
// been sorted, you have the option of using a faster algorithm.
// Aliased as `unique`.
_.uniq = _.unique = function(array, isSorted, iterator) {
var initial = iterator ? _.map(array, iterator) : array;
var result = [];
_.reduce(initial, function(memo, el, i) {
if (0 == i || (isSorted === true ? _.last(memo) != el : !_.include(memo, el))) {
memo[memo.length] = el;
result[result.length] = array[i];
}
return memo;
}, []);
return result;
};
// Produce an array that contains the union: each distinct element from all of
// the passed-in arrays.
_.union = function() {
return _.uniq(_.flatten(arguments, true));
};
// Produce an array that contains every item shared between all the
// passed-in arrays. (Aliased as "intersect" for back-compat.)
_.intersection = _.intersect = function(array) {
var rest = slice.call(arguments, 1);
return _.filter(_.uniq(array), function(item) {
return _.every(rest, function(other) {
return _.indexOf(other, item) >= 0;
});
});
};
// Take the difference between one array and a number of other arrays.
// Only the elements present in just the first array will remain.
_.difference = function(array) {
var rest = _.flatten(slice.call(arguments, 1));
return _.filter(array, function(value){ return !_.include(rest, value); });
};
// Zip together multiple lists into a single array -- elements that share
// an index go together.
_.zip = function() {
var args = slice.call(arguments);
var length = _.max(_.pluck(args, 'length'));
var results = new Array(length);
for (var i = 0; i < length; i++) results[i] = _.pluck(args, "" + i);
return results;
};
// If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**),
// we need this function. Return the position of the first occurrence of an
// item in an array, or -1 if the item is not included in the array.
// Delegates to **ECMAScript 5**'s native `indexOf` if available.
// If the array is large and already in sort order, pass `true`
// for **isSorted** to use binary search.
_.indexOf = function(array, item, isSorted) {
if (array == null) return -1;
var i, l;
if (isSorted) {
i = _.sortedIndex(array, item);
return array[i] === item ? i : -1;
}
if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item);
for (i = 0, l = array.length; i < l; i++) if (i in array && array[i] === item) return i;
return -1;
};
// Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.
_.lastIndexOf = function(array, item) {
if (array == null) return -1;
if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) return array.lastIndexOf(item);
var i = array.length;
while (i--) if (i in array && array[i] === item) return i;
return -1;
};
// Generate an integer Array containing an arithmetic progression. A port of
// the native Python `range()` function. See
// [the Python documentation](http://docs.python.org/library/functions.html#range).
_.range = function(start, stop, step) {
if (arguments.length <= 1) {
stop = start || 0;
start = 0;
}
step = arguments[2] || 1;
var len = Math.max(Math.ceil((stop - start) / step), 0);
var idx = 0;
var range = new Array(len);
while(idx < len) {
range[idx++] = start;
start += step;
}
return range;
};
// Function (ahem) Functions
// ------------------
// Reusable constructor function for prototype setting.
var ctor = function(){};
// Create a function bound to a given object (assigning `this`, and arguments,
// optionally). Binding with arguments is also known as `curry`.
// Delegates to **ECMAScript 5**'s native `Function.bind` if available.
// We check for `func.bind` first, to fail fast when `func` is undefined.
_.bind = function bind(func, context) {
var bound, args;
if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
if (!_.isFunction(func)) throw new TypeError;
args = slice.call(arguments, 2);
return bound = function() {
if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));
ctor.prototype = func.prototype;
var self = new ctor;
var result = func.apply(self, args.concat(slice.call(arguments)));
if (Object(result) === result) return result;
return self;
};
};
// Bind all of an object's methods to that object. Useful for ensuring that
// all callbacks defined on an object belong to it.
_.bindAll = function(obj) {
var funcs = slice.call(arguments, 1);
if (funcs.length == 0) funcs = _.functions(obj);
each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });
return obj;
};
// Memoize an expensive function by storing its results.
_.memoize = function(func, hasher) {
var memo = {};
hasher || (hasher = _.identity);
return function() {
var key = hasher.apply(this, arguments);
return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments));
};
};
// Delays a function for the given number of milliseconds, and then calls
// it with the arguments supplied.
_.delay = function(func, wait) {
var args = slice.call(arguments, 2);
return setTimeout(function(){ return func.apply(func, args); }, wait);
};
// Defers a function, scheduling it to run after the current call stack has
// cleared.
_.defer = function(func) {
return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
};
// Returns a function, that, when invoked, will only be triggered at most once
// during a given window of time.
_.throttle = function(func, wait) {
var context, args, timeout, throttling, more;
var whenDone = _.debounce(function(){ more = throttling = false; }, wait);
return function() {
context = this; args = arguments;
var later = function() {
timeout = null;
if (more) func.apply(context, args);
whenDone();
};
if (!timeout) timeout = setTimeout(later, wait);
if (throttling) {
more = true;
} else {
func.apply(context, args);
}
whenDone();
throttling = true;
};
};
// Returns a function, that, as long as it continues to be invoked, will not
// be triggered. The function will be called after it stops being called for
// N milliseconds.
_.debounce = function(func, wait) {
var timeout;
return function() {
var context = this, args = arguments;
var later = function() {
timeout = null;
func.apply(context, args);
};
clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
};
// Returns a function that will be executed at most one time, no matter how
// often you call it. Useful for lazy initialization.
_.once = function(func) {
var ran = false, memo;
return function() {
if (ran) return memo;
ran = true;
return memo = func.apply(this, arguments);
};
};
// Returns the first function passed as an argument to the second,
// allowing you to adjust arguments, run code before and after, and
// conditionally execute the original function.
_.wrap = function(func, wrapper) {
return function() {
var args = [func].concat(slice.call(arguments, 0));
return wrapper.apply(this, args);
};
};
// Returns a function that is the composition of a list of functions, each
// consuming the return value of the function that follows.
_.compose = function() {
var funcs = arguments;
return function() {
var args = arguments;
for (var i = funcs.length - 1; i >= 0; i--) {
args = [funcs[i].apply(this, args)];
}
return args[0];
};
};
// Returns a function that will only be executed after being called N times.
_.after = function(times, func) {
if (times <= 0) return func();
return function() {
if (--times < 1) { return func.apply(this, arguments); }
};
};
// Object Functions
// ----------------
// Retrieve the names of an object's properties.
// Delegates to **ECMAScript 5**'s native `Object.keys`
_.keys = nativeKeys || function(obj) {
if (obj !== Object(obj)) throw new TypeError('Invalid object');
var keys = [];
for (var key in obj) if (_.has(obj, key)) keys[keys.length] = key;
return keys;
};
// Retrieve the values of an object's properties.
_.values = function(obj) {
return _.map(obj, _.identity);
};
// Return a sorted list of the function names available on the object.
// Aliased as `methods`
_.functions = _.methods = function(obj) {
var names = [];
for (var key in obj) {
if (_.isFunction(obj[key])) names.push(key);
}
return names.sort();
};
// Extend a given object with all the properties in passed-in object(s).
_.extend = function(obj) {
each(slice.call(arguments, 1), function(source) {
for (var prop in source) {
obj[prop] = source[prop];
}
});
return obj;
};
// Fill in a given object with default properties.
_.defaults = function(obj) {
each(slice.call(arguments, 1), function(source) {
for (var prop in source) {
if (obj[prop] == null) obj[prop] = source[prop];
}
});
return obj;
};
// Create a (shallow-cloned) duplicate of an object.
_.clone = function(obj) {
if (!_.isObject(obj)) return obj;
return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
};
// Invokes interceptor with the obj, and then returns obj.
// The primary purpose of this method is to "tap into" a method chain, in
// order to perform operations on intermediate results within the chain.
_.tap = function(obj, interceptor) {
interceptor(obj);
return obj;
};
// Internal recursive comparison function.
function eq(a, b, stack) {
// Identical objects are equal. `0 === -0`, but they aren't identical.
// See the Harmony `egal` proposal: http://wiki.ecmascript.org/doku.php?id=harmony:egal.
if (a === b) return a !== 0 || 1 / a == 1 / b;
// A strict comparison is necessary because `null == undefined`.
if (a == null || b == null) return a === b;
// Unwrap any wrapped objects.
if (a._chain) a = a._wrapped;
if (b._chain) b = b._wrapped;
// Invoke a custom `isEqual` method if one is provided.
if (a.isEqual && _.isFunction(a.isEqual)) return a.isEqual(b);
if (b.isEqual && _.isFunction(b.isEqual)) return b.isEqual(a);
// Compare `[[Class]]` names.
var className = toString.call(a);
if (className != toString.call(b)) return false;
switch (className) {
// Strings, numbers, dates, and booleans are compared by value.
case '[object String]':
// Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
// equivalent to `new String("5")`.
return a == String(b);
case '[object Number]':
// `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for
// other numeric values.
return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b);
case '[object Date]':
case '[object Boolean]':
// Coerce dates and booleans to numeric primitive values. Dates are compared by their
// millisecond representations. Note that invalid dates with millisecond representations
// of `NaN` are not equivalent.
return +a == +b;
// RegExps are compared by their source patterns and flags.
case '[object RegExp]':
return a.source == b.source &&
a.global == b.global &&
a.multiline == b.multiline &&
a.ignoreCase == b.ignoreCase;
}
if (typeof a != 'object' || typeof b != 'object') return false;
// Assume equality for cyclic structures. The algorithm for detecting cyclic
// structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
var length = stack.length;
while (length--) {
// Linear search. Performance is inversely proportional to the number of
// unique nested structures.
if (stack[length] == a) return true;
}
// Add the first object to the stack of traversed objects.
stack.push(a);
var size = 0, result = true;
// Recursively compare objects and arrays.
if (className == '[object Array]') {
// Compare array lengths to determine if a deep comparison is necessary.
size = a.length;
result = size == b.length;
if (result) {
// Deep compare the contents, ignoring non-numeric properties.
while (size--) {
// Ensure commutative equality for sparse arrays.
if (!(result = size in a == size in b && eq(a[size], b[size], stack))) break;
}
}
} else {
// Objects with different constructors are not equivalent.
if ('constructor' in a != 'constructor' in b || a.constructor != b.constructor) return false;
// Deep compare objects.
for (var key in a) {
if (_.has(a, key)) {
// Count the expected number of properties.
size++;
// Deep compare each member.
if (!(result = _.has(b, key) && eq(a[key], b[key], stack))) break;
}
}
// Ensure that both objects contain the same number of properties.
if (result) {
for (key in b) {
if (_.has(b, key) && !(size--)) break;
}
result = !size;
}
}
// Remove the first object from the stack of traversed objects.
stack.pop();
return result;
}
// Perform a deep comparison to check if two objects are equal.
_.isEqual = function(a, b) {
return eq(a, b, []);
};
// Is a given array, string, or object empty?
// An "empty" object has no enumerable own-properties.
_.isEmpty = function(obj) {
if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;
for (var key in obj) if (_.has(obj, key)) return false;
return true;
};
// Is a given value a DOM element?
_.isElement = function(obj) {
return !!(obj && obj.nodeType == 1);
};
// Is a given value an array?
// Delegates to ECMA5's native Array.isArray
_.isArray = nativeIsArray || function(obj) {
return toString.call(obj) == '[object Array]';
};
// Is a given variable an object?
_.isObject = function(obj) {
return obj === Object(obj);
};
// Is a given variable an arguments object?
_.isArguments = function(obj) {
return toString.call(obj) == '[object Arguments]';
};
if (!_.isArguments(arguments)) {
_.isArguments = function(obj) {
return !!(obj && _.has(obj, 'callee'));
};
}
// Is a given value a function?
_.isFunction = function(obj) {
return toString.call(obj) == '[object Function]';
};
// Is a given value a string?
_.isString = function(obj) {
return toString.call(obj) == '[object String]';
};
// Is a given value a number?
_.isNumber = function(obj) {
return toString.call(obj) == '[object Number]';
};
// Is the given value `NaN`?
_.isNaN = function(obj) {
// `NaN` is the only value for which `===` is not reflexive.
return obj !== obj;
};
// Is a given value a boolean?
_.isBoolean = function(obj) {
return obj === true || obj === false || toString.call(obj) == '[object Boolean]';
};
// Is a given value a date?
_.isDate = function(obj) {
return toString.call(obj) == '[object Date]';
};
// Is the given value a regular expression?
_.isRegExp = function(obj) {
return toString.call(obj) == '[object RegExp]';
};
// Is a given value equal to null?
_.isNull = function(obj) {
return obj === null;
};
// Is a given variable undefined?
_.isUndefined = function(obj) {
return obj === void 0;
};
// Has own property?
_.has = function(obj, key) {
return hasOwnProperty.call(obj, key);
};
// Utility Functions
// -----------------
// Run Underscore.js in *noConflict* mode, returning the `_` variable to its
// previous owner. Returns a reference to the Underscore object.
_.noConflict = function() {
root._ = previousUnderscore;
return this;
};
// Keep the identity function around for default iterators.
_.identity = function(value) {
return value;
};
// Run a function **n** times.
_.times = function (n, iterator, context) {
for (var i = 0; i < n; i++) iterator.call(context, i);
};
// Escape a string for HTML interpolation.
_.escape = function(string) {
return (''+string).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&#x27;').replace(/\//g,'&#x2F;');
};
// Add your own custom functions to the Underscore object, ensuring that
// they're correctly added to the OOP wrapper as well.
_.mixin = function(obj) {
each(_.functions(obj), function(name){
addToWrapper(name, _[name] = obj[name]);
});
};
// Generate a unique integer id (unique within the entire client session).
// Useful for temporary DOM ids.
var idCounter = 0;
_.uniqueId = function(prefix) {
var id = idCounter++;
return prefix ? prefix + id : id;
};
// By default, Underscore uses ERB-style template delimiters, change the
// following template settings to use alternative delimiters.
_.templateSettings = {
evaluate : /<%([\s\S]+?)%>/g,
interpolate : /<%=([\s\S]+?)%>/g,
escape : /<%-([\s\S]+?)%>/g
};
// When customizing `templateSettings`, if you don't want to define an
// interpolation, evaluation or escaping regex, we need one that is
// guaranteed not to match.
var noMatch = /.^/;
// Within an interpolation, evaluation, or escaping, remove HTML escaping
// that had been previously added.
var unescape = function(code) {
return code.replace(/\\\\/g, '\\').replace(/\\'/g, "'");
};
// JavaScript micro-templating, similar to John Resig's implementation.
// Underscore templating handles arbitrary delimiters, preserves whitespace,
// and correctly escapes quotes within interpolated code.
_.template = function(str, data) {
var c = _.templateSettings;
var tmpl = 'var __p=[],print=function(){__p.push.apply(__p,arguments);};' +
'with(obj||{}){__p.push(\'' +
str.replace(/\\/g, '\\\\')
.replace(/'/g, "\\'")
.replace(c.escape || noMatch, function(match, code) {
return "',_.escape(" + unescape(code) + "),'";
})
.replace(c.interpolate || noMatch, function(match, code) {
return "'," + unescape(code) + ",'";
})
.replace(c.evaluate || noMatch, function(match, code) {
return "');" + unescape(code).replace(/[\r\n\t]/g, ' ') + ";__p.push('";
})
.replace(/\r/g, '\\r')
.replace(/\n/g, '\\n')
.replace(/\t/g, '\\t')
+ "');}return __p.join('');";
var func = new Function('obj', '_', tmpl);
if (data) return func(data, _);
return function(data) {
return func.call(this, data, _);
};
};
// Add a "chain" function, which will delegate to the wrapper.
_.chain = function(obj) {
return _(obj).chain();
};
// The OOP Wrapper
// ---------------
// If Underscore is called as a function, it returns a wrapped object that
// can be used OO-style. This wrapper holds altered versions of all the
// underscore functions. Wrapped objects may be chained.
var wrapper = function(obj) { this._wrapped = obj; };
// Expose `wrapper.prototype` as `_.prototype`
_.prototype = wrapper.prototype;
// Helper function to continue chaining intermediate results.
var result = function(obj, chain) {
return chain ? _(obj).chain() : obj;
};
// A method to easily add functions to the OOP wrapper.
var addToWrapper = function(name, func) {
wrapper.prototype[name] = function() {
var args = slice.call(arguments);
unshift.call(args, this._wrapped);
return result(func.apply(_, args), this._chain);
};
};
// Add all of the Underscore functions to the wrapper object.
_.mixin(_);
// Add all mutator Array functions to the wrapper.
each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
var method = ArrayProto[name];
wrapper.prototype[name] = function() {
var wrapped = this._wrapped;
method.apply(wrapped, arguments);
var length = wrapped.length;
if ((name == 'shift' || name == 'splice') && length === 0) delete wrapped[0];
return result(wrapped, this._chain);
};
});
// Add all accessor Array functions to the wrapper.
each(['concat', 'join', 'slice'], function(name) {
var method = ArrayProto[name];
wrapper.prototype[name] = function() {
return result(method.apply(this._wrapped, arguments), this._chain);
};
});
// Start chaining a wrapped Underscore object.
wrapper.prototype.chain = function() {
this._chain = true;
return this;
};
// Extracts the result from a wrapped and chained object.
wrapper.prototype.value = function() {
return this._wrapped;
};
}).call(this);

View File

@ -0,0 +1,23 @@
// Underscore.js 0.5.5
// (c) 2009 Jeremy Ashkenas, DocumentCloud Inc.
// Underscore is freely distributable under the terms of the MIT license.
// Portions of Underscore are inspired by or borrowed from Prototype.js,
// Oliver Steele's Functional, and John Resig's Micro-Templating.
// For all details and documentation:
// http://documentcloud.github.com/underscore/
(function(){var j=this,n=j._,i=function(a){this._wrapped=a},m=typeof StopIteration!=="undefined"?StopIteration:"__break__",b=j._=function(a){return new i(a)};if(typeof exports!=="undefined")exports._=b;var k=Array.prototype.slice,o=Array.prototype.unshift,p=Object.prototype.toString,q=Object.prototype.hasOwnProperty,r=Object.prototype.propertyIsEnumerable;b.VERSION="0.5.5";b.each=function(a,c,d){try{if(a.forEach)a.forEach(c,d);else if(b.isArray(a)||b.isArguments(a))for(var e=0,f=a.length;e<f;e++)c.call(d,
a[e],e,a);else{var g=b.keys(a);f=g.length;for(e=0;e<f;e++)c.call(d,a[g[e]],g[e],a)}}catch(h){if(h!=m)throw h;}return a};b.map=function(a,c,d){if(a&&b.isFunction(a.map))return a.map(c,d);var e=[];b.each(a,function(f,g,h){e.push(c.call(d,f,g,h))});return e};b.reduce=function(a,c,d,e){if(a&&b.isFunction(a.reduce))return a.reduce(b.bind(d,e),c);b.each(a,function(f,g,h){c=d.call(e,c,f,g,h)});return c};b.reduceRight=function(a,c,d,e){if(a&&b.isFunction(a.reduceRight))return a.reduceRight(b.bind(d,e),c);
var f=b.clone(b.toArray(a)).reverse();b.each(f,function(g,h){c=d.call(e,c,g,h,a)});return c};b.detect=function(a,c,d){var e;b.each(a,function(f,g,h){if(c.call(d,f,g,h)){e=f;b.breakLoop()}});return e};b.select=function(a,c,d){if(a&&b.isFunction(a.filter))return a.filter(c,d);var e=[];b.each(a,function(f,g,h){c.call(d,f,g,h)&&e.push(f)});return e};b.reject=function(a,c,d){var e=[];b.each(a,function(f,g,h){!c.call(d,f,g,h)&&e.push(f)});return e};b.all=function(a,c,d){c=c||b.identity;if(a&&b.isFunction(a.every))return a.every(c,
d);var e=true;b.each(a,function(f,g,h){(e=e&&c.call(d,f,g,h))||b.breakLoop()});return e};b.any=function(a,c,d){c=c||b.identity;if(a&&b.isFunction(a.some))return a.some(c,d);var e=false;b.each(a,function(f,g,h){if(e=c.call(d,f,g,h))b.breakLoop()});return e};b.include=function(a,c){if(b.isArray(a))return b.indexOf(a,c)!=-1;var d=false;b.each(a,function(e){if(d=e===c)b.breakLoop()});return d};b.invoke=function(a,c){var d=b.rest(arguments,2);return b.map(a,function(e){return(c?e[c]:e).apply(e,d)})};b.pluck=
function(a,c){return b.map(a,function(d){return d[c]})};b.max=function(a,c,d){if(!c&&b.isArray(a))return Math.max.apply(Math,a);var e={computed:-Infinity};b.each(a,function(f,g,h){g=c?c.call(d,f,g,h):f;g>=e.computed&&(e={value:f,computed:g})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);var e={computed:Infinity};b.each(a,function(f,g,h){g=c?c.call(d,f,g,h):f;g<e.computed&&(e={value:f,computed:g})});return e.value};b.sortBy=function(a,c,d){return b.pluck(b.map(a,
function(e,f,g){return{value:e,criteria:c.call(d,e,f,g)}}).sort(function(e,f){e=e.criteria;f=f.criteria;return e<f?-1:e>f?1:0}),"value")};b.sortedIndex=function(a,c,d){d=d||b.identity;for(var e=0,f=a.length;e<f;){var g=e+f>>1;d(a[g])<d(c)?(e=g+1):(f=g)}return e};b.toArray=function(a){if(!a)return[];if(a.toArray)return a.toArray();if(b.isArray(a))return a;if(b.isArguments(a))return k.call(a);return b.values(a)};b.size=function(a){return b.toArray(a).length};b.first=function(a,c,d){return c&&!d?k.call(a,
0,c):a[0]};b.rest=function(a,c,d){return k.call(a,b.isUndefined(c)||d?1:c)};b.last=function(a){return a[a.length-1]};b.compact=function(a){return b.select(a,function(c){return!!c})};b.flatten=function(a){return b.reduce(a,[],function(c,d){if(b.isArray(d))return c.concat(b.flatten(d));c.push(d);return c})};b.without=function(a){var c=b.rest(arguments);return b.select(a,function(d){return!b.include(c,d)})};b.uniq=function(a,c){return b.reduce(a,[],function(d,e,f){if(0==f||(c===true?b.last(d)!=e:!b.include(d,
e)))d.push(e);return d})};b.intersect=function(a){var c=b.rest(arguments);return b.select(b.uniq(a),function(d){return b.all(c,function(e){return b.indexOf(e,d)>=0})})};b.zip=function(){for(var a=b.toArray(arguments),c=b.max(b.pluck(a,"length")),d=new Array(c),e=0;e<c;e++)d[e]=b.pluck(a,String(e));return d};b.indexOf=function(a,c){if(a.indexOf)return a.indexOf(c);for(var d=0,e=a.length;d<e;d++)if(a[d]===c)return d;return-1};b.lastIndexOf=function(a,c){if(a.lastIndexOf)return a.lastIndexOf(c);for(var d=
a.length;d--;)if(a[d]===c)return d;return-1};b.range=function(a,c,d){var e=b.toArray(arguments),f=e.length<=1;a=f?0:e[0];c=f?e[0]:e[1];d=e[2]||1;e=Math.ceil((c-a)/d);if(e<=0)return[];e=new Array(e);f=a;for(var g=0;1;f+=d){if((d>0?f-c:c-f)>=0)return e;e[g++]=f}};b.bind=function(a,c){var d=b.rest(arguments,2);return function(){return a.apply(c||j,d.concat(b.toArray(arguments)))}};b.bindAll=function(a){var c=b.rest(arguments);if(c.length==0)c=b.functions(a);b.each(c,function(d){a[d]=b.bind(a[d],a)});
return a};b.delay=function(a,c){var d=b.rest(arguments,2);return setTimeout(function(){return a.apply(a,d)},c)};b.defer=function(a){return b.delay.apply(b,[a,1].concat(b.rest(arguments)))};b.wrap=function(a,c){return function(){var d=[a].concat(b.toArray(arguments));return c.apply(c,d)}};b.compose=function(){var a=b.toArray(arguments);return function(){for(var c=b.toArray(arguments),d=a.length-1;d>=0;d--)c=[a[d].apply(this,c)];return c[0]}};b.keys=function(a){if(b.isArray(a))return b.range(0,a.length);
var c=[];for(var d in a)q.call(a,d)&&c.push(d);return c};b.values=function(a){return b.map(a,b.identity)};b.functions=function(a){return b.select(b.keys(a),function(c){return b.isFunction(a[c])}).sort()};b.extend=function(a,c){for(var d in c)a[d]=c[d];return a};b.clone=function(a){if(b.isArray(a))return a.slice(0);return b.extend({},a)};b.tap=function(a,c){c(a);return a};b.isEqual=function(a,c){if(a===c)return true;var d=typeof a;if(d!=typeof c)return false;if(a==c)return true;if(!a&&c||a&&!c)return false;
if(a.isEqual)return a.isEqual(c);if(b.isDate(a)&&b.isDate(c))return a.getTime()===c.getTime();if(b.isNaN(a)&&b.isNaN(c))return true;if(b.isRegExp(a)&&b.isRegExp(c))return a.source===c.source&&a.global===c.global&&a.ignoreCase===c.ignoreCase&&a.multiline===c.multiline;if(d!=="object")return false;if(a.length&&a.length!==c.length)return false;d=b.keys(a);var e=b.keys(c);if(d.length!=e.length)return false;for(var f in a)if(!b.isEqual(a[f],c[f]))return false;return true};b.isEmpty=function(a){return b.keys(a).length==
0};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=function(a){return!!(a&&a.concat&&a.unshift)};b.isArguments=function(a){return a&&b.isNumber(a.length)&&!b.isArray(a)&&!r.call(a,"length")};b.isFunction=function(a){return!!(a&&a.constructor&&a.call&&a.apply)};b.isString=function(a){return!!(a===""||a&&a.charCodeAt&&a.substr)};b.isNumber=function(a){return p.call(a)==="[object Number]"};b.isDate=function(a){return!!(a&&a.getTimezoneOffset&&a.setUTCFullYear)};b.isRegExp=function(a){return!!(a&&
a.test&&a.exec&&(a.ignoreCase||a.ignoreCase===false))};b.isNaN=function(a){return b.isNumber(a)&&isNaN(a)};b.isNull=function(a){return a===null};b.isUndefined=function(a){return typeof a=="undefined"};b.noConflict=function(){j._=n;return this};b.identity=function(a){return a};b.breakLoop=function(){throw m;};var s=0;b.uniqueId=function(a){var c=s++;return a?a+c:c};b.template=function(a,c){a=new Function("obj","var p=[],print=function(){p.push.apply(p,arguments);};with(obj){p.push('"+a.replace(/[\r\t\n]/g,
" ").replace(/'(?=[^%]*%>)/g,"\t").split("'").join("\\'").split("\t").join("'").replace(/<%=(.+?)%>/g,"',$1,'").split("<%").join("');").split("%>").join("p.push('")+"');}return p.join('');");return c?a(c):a};b.forEach=b.each;b.foldl=b.inject=b.reduce;b.foldr=b.reduceRight;b.filter=b.select;b.every=b.all;b.some=b.any;b.head=b.first;b.tail=b.rest;b.methods=b.functions;var l=function(a,c){return c?b(a).chain():a};b.each(b.functions(b),function(a){var c=b[a];i.prototype[a]=function(){var d=b.toArray(arguments);
o.call(d,this._wrapped);return l(c.apply(b,d),this._chain)}});b.each(["pop","push","reverse","shift","sort","splice","unshift"],function(a){var c=Array.prototype[a];i.prototype[a]=function(){c.apply(this._wrapped,arguments);return l(this._wrapped,this._chain)}});b.each(["concat","join","slice"],function(a){var c=Array.prototype[a];i.prototype[a]=function(){return l(c.apply(this._wrapped,arguments),this._chain)}});i.prototype.chain=function(){this._chain=true;return this};i.prototype.value=function(){return this._wrapped}})();

Binary file not shown.

After

Width:  |  Height:  |  Size: 372 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 363 B

View File

@ -0,0 +1,808 @@
/*
* websupport.js
* ~~~~~~~~~~~~~
*
* sphinx.websupport utilties for all documentation.
*
* :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
(function($) {
$.fn.autogrow = function() {
return this.each(function() {
var textarea = this;
$.fn.autogrow.resize(textarea);
$(textarea)
.focus(function() {
textarea.interval = setInterval(function() {
$.fn.autogrow.resize(textarea);
}, 500);
})
.blur(function() {
clearInterval(textarea.interval);
});
});
};
$.fn.autogrow.resize = function(textarea) {
var lineHeight = parseInt($(textarea).css('line-height'), 10);
var lines = textarea.value.split('\n');
var columns = textarea.cols;
var lineCount = 0;
$.each(lines, function() {
lineCount += Math.ceil(this.length / columns) || 1;
});
var height = lineHeight * (lineCount + 1);
$(textarea).css('height', height);
};
})(jQuery);
(function($) {
var comp, by;
function init() {
initEvents();
initComparator();
}
function initEvents() {
$('a.comment-close').live("click", function(event) {
event.preventDefault();
hide($(this).attr('id').substring(2));
});
$('a.vote').live("click", function(event) {
event.preventDefault();
handleVote($(this));
});
$('a.reply').live("click", function(event) {
event.preventDefault();
openReply($(this).attr('id').substring(2));
});
$('a.close-reply').live("click", function(event) {
event.preventDefault();
closeReply($(this).attr('id').substring(2));
});
$('a.sort-option').live("click", function(event) {
event.preventDefault();
handleReSort($(this));
});
$('a.show-proposal').live("click", function(event) {
event.preventDefault();
showProposal($(this).attr('id').substring(2));
});
$('a.hide-proposal').live("click", function(event) {
event.preventDefault();
hideProposal($(this).attr('id').substring(2));
});
$('a.show-propose-change').live("click", function(event) {
event.preventDefault();
showProposeChange($(this).attr('id').substring(2));
});
$('a.hide-propose-change').live("click", function(event) {
event.preventDefault();
hideProposeChange($(this).attr('id').substring(2));
});
$('a.accept-comment').live("click", function(event) {
event.preventDefault();
acceptComment($(this).attr('id').substring(2));
});
$('a.delete-comment').live("click", function(event) {
event.preventDefault();
deleteComment($(this).attr('id').substring(2));
});
$('a.comment-markup').live("click", function(event) {
event.preventDefault();
toggleCommentMarkupBox($(this).attr('id').substring(2));
});
}
/**
* Set comp, which is a comparator function used for sorting and
* inserting comments into the list.
*/
function setComparator() {
// If the first three letters are "asc", sort in ascending order
// and remove the prefix.
if (by.substring(0,3) == 'asc') {
var i = by.substring(3);
comp = function(a, b) { return a[i] - b[i]; };
} else {
// Otherwise sort in descending order.
comp = function(a, b) { return b[by] - a[by]; };
}
// Reset link styles and format the selected sort option.
$('a.sel').attr('href', '#').removeClass('sel');
$('a.by' + by).removeAttr('href').addClass('sel');
}
/**
* Create a comp function. If the user has preferences stored in
* the sortBy cookie, use those, otherwise use the default.
*/
function initComparator() {
by = 'rating'; // Default to sort by rating.
// If the sortBy cookie is set, use that instead.
if (document.cookie.length > 0) {
var start = document.cookie.indexOf('sortBy=');
if (start != -1) {
start = start + 7;
var end = document.cookie.indexOf(";", start);
if (end == -1) {
end = document.cookie.length;
by = unescape(document.cookie.substring(start, end));
}
}
}
setComparator();
}
/**
* Show a comment div.
*/
function show(id) {
$('#ao' + id).hide();
$('#ah' + id).show();
var context = $.extend({id: id}, opts);
var popup = $(renderTemplate(popupTemplate, context)).hide();
popup.find('textarea[name="proposal"]').hide();
popup.find('a.by' + by).addClass('sel');
var form = popup.find('#cf' + id);
form.submit(function(event) {
event.preventDefault();
addComment(form);
});
$('#s' + id).after(popup);
popup.slideDown('fast', function() {
getComments(id);
});
}
/**
* Hide a comment div.
*/
function hide(id) {
$('#ah' + id).hide();
$('#ao' + id).show();
var div = $('#sc' + id);
div.slideUp('fast', function() {
div.remove();
});
}
/**
* Perform an ajax request to get comments for a node
* and insert the comments into the comments tree.
*/
function getComments(id) {
$.ajax({
type: 'GET',
url: opts.getCommentsURL,
data: {node: id},
success: function(data, textStatus, request) {
var ul = $('#cl' + id);
var speed = 100;
$('#cf' + id)
.find('textarea[name="proposal"]')
.data('source', data.source);
if (data.comments.length === 0) {
ul.html('<li>No comments yet.</li>');
ul.data('empty', true);
} else {
// If there are comments, sort them and put them in the list.
var comments = sortComments(data.comments);
speed = data.comments.length * 100;
appendComments(comments, ul);
ul.data('empty', false);
}
$('#cn' + id).slideUp(speed + 200);
ul.slideDown(speed);
},
error: function(request, textStatus, error) {
showError('Oops, there was a problem retrieving the comments.');
},
dataType: 'json'
});
}
/**
* Add a comment via ajax and insert the comment into the comment tree.
*/
function addComment(form) {
var node_id = form.find('input[name="node"]').val();
var parent_id = form.find('input[name="parent"]').val();
var text = form.find('textarea[name="comment"]').val();
var proposal = form.find('textarea[name="proposal"]').val();
if (text == '') {
showError('Please enter a comment.');
return;
}
// Disable the form that is being submitted.
form.find('textarea,input').attr('disabled', 'disabled');
// Send the comment to the server.
$.ajax({
type: "POST",
url: opts.addCommentURL,
dataType: 'json',
data: {
node: node_id,
parent: parent_id,
text: text,
proposal: proposal
},
success: function(data, textStatus, error) {
// Reset the form.
if (node_id) {
hideProposeChange(node_id);
}
form.find('textarea')
.val('')
.add(form.find('input'))
.removeAttr('disabled');
var ul = $('#cl' + (node_id || parent_id));
if (ul.data('empty')) {
$(ul).empty();
ul.data('empty', false);
}
insertComment(data.comment);
var ao = $('#ao' + node_id);
ao.find('img').attr({'src': opts.commentBrightImage});
if (node_id) {
// if this was a "root" comment, remove the commenting box
// (the user can get it back by reopening the comment popup)
$('#ca' + node_id).slideUp();
}
},
error: function(request, textStatus, error) {
form.find('textarea,input').removeAttr('disabled');
showError('Oops, there was a problem adding the comment.');
}
});
}
/**
* Recursively append comments to the main comment list and children
* lists, creating the comment tree.
*/
function appendComments(comments, ul) {
$.each(comments, function() {
var div = createCommentDiv(this);
ul.append($(document.createElement('li')).html(div));
appendComments(this.children, div.find('ul.comment-children'));
// To avoid stagnating data, don't store the comments children in data.
this.children = null;
div.data('comment', this);
});
}
/**
* After adding a new comment, it must be inserted in the correct
* location in the comment tree.
*/
function insertComment(comment) {
var div = createCommentDiv(comment);
// To avoid stagnating data, don't store the comments children in data.
comment.children = null;
div.data('comment', comment);
var ul = $('#cl' + (comment.node || comment.parent));
var siblings = getChildren(ul);
var li = $(document.createElement('li'));
li.hide();
// Determine where in the parents children list to insert this comment.
for(i=0; i < siblings.length; i++) {
if (comp(comment, siblings[i]) <= 0) {
$('#cd' + siblings[i].id)
.parent()
.before(li.html(div));
li.slideDown('fast');
return;
}
}
// If we get here, this comment rates lower than all the others,
// or it is the only comment in the list.
ul.append(li.html(div));
li.slideDown('fast');
}
function acceptComment(id) {
$.ajax({
type: 'POST',
url: opts.acceptCommentURL,
data: {id: id},
success: function(data, textStatus, request) {
$('#cm' + id).fadeOut('fast');
$('#cd' + id).removeClass('moderate');
},
error: function(request, textStatus, error) {
showError('Oops, there was a problem accepting the comment.');
}
});
}
function deleteComment(id) {
$.ajax({
type: 'POST',
url: opts.deleteCommentURL,
data: {id: id},
success: function(data, textStatus, request) {
var div = $('#cd' + id);
if (data == 'delete') {
// Moderator mode: remove the comment and all children immediately
div.slideUp('fast', function() {
div.remove();
});
return;
}
// User mode: only mark the comment as deleted
div
.find('span.user-id:first')
.text('[deleted]').end()
.find('div.comment-text:first')
.text('[deleted]').end()
.find('#cm' + id + ', #dc' + id + ', #ac' + id + ', #rc' + id +
', #sp' + id + ', #hp' + id + ', #cr' + id + ', #rl' + id)
.remove();
var comment = div.data('comment');
comment.username = '[deleted]';
comment.text = '[deleted]';
div.data('comment', comment);
},
error: function(request, textStatus, error) {
showError('Oops, there was a problem deleting the comment.');
}
});
}
function showProposal(id) {
$('#sp' + id).hide();
$('#hp' + id).show();
$('#pr' + id).slideDown('fast');
}
function hideProposal(id) {
$('#hp' + id).hide();
$('#sp' + id).show();
$('#pr' + id).slideUp('fast');
}
function showProposeChange(id) {
$('#pc' + id).hide();
$('#hc' + id).show();
var textarea = $('#pt' + id);
textarea.val(textarea.data('source'));
$.fn.autogrow.resize(textarea[0]);
textarea.slideDown('fast');
}
function hideProposeChange(id) {
$('#hc' + id).hide();
$('#pc' + id).show();
var textarea = $('#pt' + id);
textarea.val('').removeAttr('disabled');
textarea.slideUp('fast');
}
function toggleCommentMarkupBox(id) {
$('#mb' + id).toggle();
}
/** Handle when the user clicks on a sort by link. */
function handleReSort(link) {
var classes = link.attr('class').split(/\s+/);
for (var i=0; i<classes.length; i++) {
if (classes[i] != 'sort-option') {
by = classes[i].substring(2);
}
}
setComparator();
// Save/update the sortBy cookie.
var expiration = new Date();
expiration.setDate(expiration.getDate() + 365);
document.cookie= 'sortBy=' + escape(by) +
';expires=' + expiration.toUTCString();
$('ul.comment-ul').each(function(index, ul) {
var comments = getChildren($(ul), true);
comments = sortComments(comments);
appendComments(comments, $(ul).empty());
});
}
/**
* Function to process a vote when a user clicks an arrow.
*/
function handleVote(link) {
if (!opts.voting) {
showError("You'll need to login to vote.");
return;
}
var id = link.attr('id');
if (!id) {
// Didn't click on one of the voting arrows.
return;
}
// If it is an unvote, the new vote value is 0,
// Otherwise it's 1 for an upvote, or -1 for a downvote.
var value = 0;
if (id.charAt(1) != 'u') {
value = id.charAt(0) == 'u' ? 1 : -1;
}
// The data to be sent to the server.
var d = {
comment_id: id.substring(2),
value: value
};
// Swap the vote and unvote links.
link.hide();
$('#' + id.charAt(0) + (id.charAt(1) == 'u' ? 'v' : 'u') + d.comment_id)
.show();
// The div the comment is displayed in.
var div = $('div#cd' + d.comment_id);
var data = div.data('comment');
// If this is not an unvote, and the other vote arrow has
// already been pressed, unpress it.
if ((d.value !== 0) && (data.vote === d.value * -1)) {
$('#' + (d.value == 1 ? 'd' : 'u') + 'u' + d.comment_id).hide();
$('#' + (d.value == 1 ? 'd' : 'u') + 'v' + d.comment_id).show();
}
// Update the comments rating in the local data.
data.rating += (data.vote === 0) ? d.value : (d.value - data.vote);
data.vote = d.value;
div.data('comment', data);
// Change the rating text.
div.find('.rating:first')
.text(data.rating + ' point' + (data.rating == 1 ? '' : 's'));
// Send the vote information to the server.
$.ajax({
type: "POST",
url: opts.processVoteURL,
data: d,
error: function(request, textStatus, error) {
showError('Oops, there was a problem casting that vote.');
}
});
}
/**
* Open a reply form used to reply to an existing comment.
*/
function openReply(id) {
// Swap out the reply link for the hide link
$('#rl' + id).hide();
$('#cr' + id).show();
// Add the reply li to the children ul.
var div = $(renderTemplate(replyTemplate, {id: id})).hide();
$('#cl' + id)
.prepend(div)
// Setup the submit handler for the reply form.
.find('#rf' + id)
.submit(function(event) {
event.preventDefault();
addComment($('#rf' + id));
closeReply(id);
})
.find('input[type=button]')
.click(function() {
closeReply(id);
});
div.slideDown('fast', function() {
$('#rf' + id).find('textarea').focus();
});
}
/**
* Close the reply form opened with openReply.
*/
function closeReply(id) {
// Remove the reply div from the DOM.
$('#rd' + id).slideUp('fast', function() {
$(this).remove();
});
// Swap out the hide link for the reply link
$('#cr' + id).hide();
$('#rl' + id).show();
}
/**
* Recursively sort a tree of comments using the comp comparator.
*/
function sortComments(comments) {
comments.sort(comp);
$.each(comments, function() {
this.children = sortComments(this.children);
});
return comments;
}
/**
* Get the children comments from a ul. If recursive is true,
* recursively include childrens' children.
*/
function getChildren(ul, recursive) {
var children = [];
ul.children().children("[id^='cd']")
.each(function() {
var comment = $(this).data('comment');
if (recursive)
comment.children = getChildren($(this).find('#cl' + comment.id), true);
children.push(comment);
});
return children;
}
/** Create a div to display a comment in. */
function createCommentDiv(comment) {
if (!comment.displayed && !opts.moderator) {
return $('<div class="moderate">Thank you! Your comment will show up '
+ 'once it is has been approved by a moderator.</div>');
}
// Prettify the comment rating.
comment.pretty_rating = comment.rating + ' point' +
(comment.rating == 1 ? '' : 's');
// Make a class (for displaying not yet moderated comments differently)
comment.css_class = comment.displayed ? '' : ' moderate';
// Create a div for this comment.
var context = $.extend({}, opts, comment);
var div = $(renderTemplate(commentTemplate, context));
// If the user has voted on this comment, highlight the correct arrow.
if (comment.vote) {
var direction = (comment.vote == 1) ? 'u' : 'd';
div.find('#' + direction + 'v' + comment.id).hide();
div.find('#' + direction + 'u' + comment.id).show();
}
if (opts.moderator || comment.text != '[deleted]') {
div.find('a.reply').show();
if (comment.proposal_diff)
div.find('#sp' + comment.id).show();
if (opts.moderator && !comment.displayed)
div.find('#cm' + comment.id).show();
if (opts.moderator || (opts.username == comment.username))
div.find('#dc' + comment.id).show();
}
return div;
}
/**
* A simple template renderer. Placeholders such as <%id%> are replaced
* by context['id'] with items being escaped. Placeholders such as <#id#>
* are not escaped.
*/
function renderTemplate(template, context) {
var esc = $(document.createElement('div'));
function handle(ph, escape) {
var cur = context;
$.each(ph.split('.'), function() {
cur = cur[this];
});
return escape ? esc.text(cur || "").html() : cur;
}
return template.replace(/<([%#])([\w\.]*)\1>/g, function() {
return handle(arguments[2], arguments[1] == '%' ? true : false);
});
}
/** Flash an error message briefly. */
function showError(message) {
$(document.createElement('div')).attr({'class': 'popup-error'})
.append($(document.createElement('div'))
.attr({'class': 'error-message'}).text(message))
.appendTo('body')
.fadeIn("slow")
.delay(2000)
.fadeOut("slow");
}
/** Add a link the user uses to open the comments popup. */
$.fn.comment = function() {
return this.each(function() {
var id = $(this).attr('id').substring(1);
var count = COMMENT_METADATA[id];
var title = count + ' comment' + (count == 1 ? '' : 's');
var image = count > 0 ? opts.commentBrightImage : opts.commentImage;
var addcls = count == 0 ? ' nocomment' : '';
$(this)
.append(
$(document.createElement('a')).attr({
href: '#',
'class': 'sphinx-comment-open' + addcls,
id: 'ao' + id
})
.append($(document.createElement('img')).attr({
src: image,
alt: 'comment',
title: title
}))
.click(function(event) {
event.preventDefault();
show($(this).attr('id').substring(2));
})
)
.append(
$(document.createElement('a')).attr({
href: '#',
'class': 'sphinx-comment-close hidden',
id: 'ah' + id
})
.append($(document.createElement('img')).attr({
src: opts.closeCommentImage,
alt: 'close',
title: 'close'
}))
.click(function(event) {
event.preventDefault();
hide($(this).attr('id').substring(2));
})
);
});
};
var opts = {
processVoteURL: '/_process_vote',
addCommentURL: '/_add_comment',
getCommentsURL: '/_get_comments',
acceptCommentURL: '/_accept_comment',
deleteCommentURL: '/_delete_comment',
commentImage: '/static/_static/comment.png',
closeCommentImage: '/static/_static/comment-close.png',
loadingImage: '/static/_static/ajax-loader.gif',
commentBrightImage: '/static/_static/comment-bright.png',
upArrow: '/static/_static/up.png',
downArrow: '/static/_static/down.png',
upArrowPressed: '/static/_static/up-pressed.png',
downArrowPressed: '/static/_static/down-pressed.png',
voting: false,
moderator: false
};
if (typeof COMMENT_OPTIONS != "undefined") {
opts = jQuery.extend(opts, COMMENT_OPTIONS);
}
var popupTemplate = '\
<div class="sphinx-comments" id="sc<%id%>">\
<p class="sort-options">\
Sort by:\
<a href="#" class="sort-option byrating">best rated</a>\
<a href="#" class="sort-option byascage">newest</a>\
<a href="#" class="sort-option byage">oldest</a>\
</p>\
<div class="comment-header">Comments</div>\
<div class="comment-loading" id="cn<%id%>">\
loading comments... <img src="<%loadingImage%>" alt="" /></div>\
<ul id="cl<%id%>" class="comment-ul"></ul>\
<div id="ca<%id%>">\
<p class="add-a-comment">Add a comment\
(<a href="#" class="comment-markup" id="ab<%id%>">markup</a>):</p>\
<div class="comment-markup-box" id="mb<%id%>">\
reStructured text markup: <i>*emph*</i>, <b>**strong**</b>, \
<tt>``code``</tt>, \
code blocks: <tt>::</tt> and an indented block after blank line</div>\
<form method="post" id="cf<%id%>" class="comment-form" action="">\
<textarea name="comment" cols="80"></textarea>\
<p class="propose-button">\
<a href="#" id="pc<%id%>" class="show-propose-change">\
Propose a change &#9657;\
</a>\
<a href="#" id="hc<%id%>" class="hide-propose-change">\
Propose a change &#9663;\
</a>\
</p>\
<textarea name="proposal" id="pt<%id%>" cols="80"\
spellcheck="false"></textarea>\
<input type="submit" value="Add comment" />\
<input type="hidden" name="node" value="<%id%>" />\
<input type="hidden" name="parent" value="" />\
</form>\
</div>\
</div>';
var commentTemplate = '\
<div id="cd<%id%>" class="sphinx-comment<%css_class%>">\
<div class="vote">\
<div class="arrow">\
<a href="#" id="uv<%id%>" class="vote" title="vote up">\
<img src="<%upArrow%>" />\
</a>\
<a href="#" id="uu<%id%>" class="un vote" title="vote up">\
<img src="<%upArrowPressed%>" />\
</a>\
</div>\
<div class="arrow">\
<a href="#" id="dv<%id%>" class="vote" title="vote down">\
<img src="<%downArrow%>" id="da<%id%>" />\
</a>\
<a href="#" id="du<%id%>" class="un vote" title="vote down">\
<img src="<%downArrowPressed%>" />\
</a>\
</div>\
</div>\
<div class="comment-content">\
<p class="tagline comment">\
<span class="user-id"><%username%></span>\
<span class="rating"><%pretty_rating%></span>\
<span class="delta"><%time.delta%></span>\
</p>\
<div class="comment-text comment"><#text#></div>\
<p class="comment-opts comment">\
<a href="#" class="reply hidden" id="rl<%id%>">reply &#9657;</a>\
<a href="#" class="close-reply" id="cr<%id%>">reply &#9663;</a>\
<a href="#" id="sp<%id%>" class="show-proposal">proposal &#9657;</a>\
<a href="#" id="hp<%id%>" class="hide-proposal">proposal &#9663;</a>\
<a href="#" id="dc<%id%>" class="delete-comment hidden">delete</a>\
<span id="cm<%id%>" class="moderation hidden">\
<a href="#" id="ac<%id%>" class="accept-comment">accept</a>\
</span>\
</p>\
<pre class="proposal" id="pr<%id%>">\
<#proposal_diff#>\
</pre>\
<ul class="comment-children" id="cl<%id%>"></ul>\
</div>\
<div class="clearleft"></div>\
</div>\
</div>';
var replyTemplate = '\
<li>\
<div class="reply-div" id="rd<%id%>">\
<form id="rf<%id%>">\
<textarea name="comment" cols="80"></textarea>\
<input type="submit" value="Add reply" />\
<input type="button" value="Cancel" />\
<input type="hidden" name="parent" value="<%id%>" />\
<input type="hidden" name="node" value="" />\
</form>\
</div>\
</li>';
$(document).ready(function() {
init();
});
})(jQuery);
$(document).ready(function() {
// add comment anchors for all paragraphs that are commentable
$('.sphinx-has-comment').comment();
// highlight search words in search results
$("div.context").each(function() {
var params = $.getQueryParameters();
var terms = (params.q) ? params.q[0].split(/\s+/) : [];
var result = $(this);
$.each(terms, function() {
result.highlightText(this.toLowerCase(), 'highlighted');
});
});
// directly open comment window if requested
var anchor = document.location.hash;
if (anchor.substring(0, 9) == '#comment-') {
$('#ao' + anchor.substring(9)).click();
document.location.hash = '#s' + anchor.substring(9);
}
});

1491
lorax-composer/genindex.html Normal file

File diff suppressed because it is too large Load Diff

133
lorax-composer/index.html Normal file
View File

@ -0,0 +1,133 @@
<!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>Welcome to Loraxs documentation! &mdash; Lorax 19.7.10 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: '19.7.10',
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>
<link rel="top" title="Lorax 19.7.10 documentation" href="#" />
<link rel="next" title="Introduction to Lorax" href="intro.html" />
</head>
<body>
<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 class="right" >
<a href="intro.html" title="Introduction to Lorax"
accesskey="N">next</a> |</li>
<li><a href="#">Lorax 19.7.10 documentation</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="welcome-to-lorax-s-documentation">
<h1>Welcome to Lorax&#8217;s documentation!<a class="headerlink" href="#welcome-to-lorax-s-documentation" title="Permalink to this headline"></a></h1>
<p>Contents:</p>
<div class="toctree-wrapper compound">
<ul>
<li class="toctree-l1"><a class="reference internal" href="intro.html">Introduction to Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="intro.html#before-lorax">Before Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="lorax-composer.html">lorax-composer</a></li>
<li class="toctree-l1"><a class="reference internal" href="modules.html">pylorax</a></li>
</ul>
</div>
</div>
<div class="section" id="indices-and-tables">
<h1>Indices and tables<a class="headerlink" href="#indices-and-tables" title="Permalink to this headline"></a></h1>
<ul class="simple">
<li><a class="reference internal" href="genindex.html"><em>Index</em></a></li>
<li><a class="reference internal" href="py-modindex.html"><em>Module Index</em></a></li>
<li><a class="reference internal" href="search.html"><em>Search Page</em></a></li>
</ul>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3><a href="#">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Welcome to Lorax&#8217;s documentation!</a><ul>
</ul>
</li>
<li><a class="reference internal" href="#indices-and-tables">Indices and tables</a></li>
</ul>
<h4>Next topic</h4>
<p class="topless"><a href="intro.html"
title="next chapter">Introduction to Lorax</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/index.txt"
rel="nofollow">Show Source</a></li>
</ul>
<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 class="right" >
<a href="intro.html" title="Introduction to Lorax"
>next</a> |</li>
<li><a href="#">Lorax 19.7.10 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2017, Red Hat, Inc..
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>

172
lorax-composer/intro.html Normal file
View File

@ -0,0 +1,172 @@
<!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>Introduction to Lorax &mdash; Lorax 19.7.10 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: '19.7.10',
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>
<link rel="top" title="Lorax 19.7.10 documentation" href="index.html" />
<link rel="next" title="lorax-composer" href="lorax-composer.html" />
<link rel="prev" title="Welcome to Loraxs documentation!" href="index.html" />
</head>
<body>
<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 class="right" >
<a href="lorax-composer.html" title="lorax-composer"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="index.html" title="Welcome to Loraxs documentation!"
accesskey="P">previous</a> |</li>
<li><a href="index.html">Lorax 19.7.10 documentation</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="introduction-to-lorax">
<h1>Introduction to Lorax<a class="headerlink" href="#introduction-to-lorax" title="Permalink to this headline"></a></h1>
<p>I am the Lorax. I speak for the trees [and images].</p>
<p>Lorax is used to build the Anaconda Installer boot.iso, it consists of a
library, pylorax, a set of templates, and the lorax script. Its operation
is driven by a customized set of Mako templates that lists the packages
to be installed, steps to execute to remove unneeded files, and creation
of the iso for all of the supported architectures.</p>
</div>
<div class="section" id="before-lorax">
<h1>Before Lorax<a class="headerlink" href="#before-lorax" title="Permalink to this headline"></a></h1>
<p>Tree building tools such as pungi and revisor rely on &#8216;buildinstall&#8217; in
anaconda/scripts/ to produce the boot images and other such control files
in the final tree. The existing buildinstall scripts written in a mix of
bash and Python are unmaintainable. Lorax is an attempt to replace them
with something more flexible.</p>
<p>EXISTING WORKFLOW:</p>
<p>pungi and other tools call scripts/buildinstall, which in turn call other
scripts to do the image building and data generation. Here&#8217;s how it
currently looks:</p>
<blockquote>
<div><dl class="docutils">
<dt>-&gt; buildinstall</dt>
<dd><ul class="first simple">
<li>process command line options</li>
<li>write temporary yum.conf to point to correct repo</li>
<li>find anaconda release RPM</li>
<li>unpack RPM, pull in those versions of upd-instroot, mk-images,
maketreeinfo.py, makestamp.py, and buildinstall</li>
</ul>
<p>-&gt; call upd-instroot</p>
<p>-&gt; call maketreeinfo.py</p>
<p>-&gt; call mk-images (which figures out which mk-images.ARCH to call)</p>
<p>-&gt; call makestamp.py</p>
<ul class="last simple">
<li>clean up</li>
</ul>
</dd>
</dl>
</div></blockquote>
<p>PROBLEMS:</p>
<p>The existing workflow presents some problems with maintaining the scripts.
First, almost all knowledge of what goes in to the stage 1 and stage 2
images lives in upd-instroot. The mk-images* scripts copy things from the
root created by upd-instroot in order to build the stage 1 image, though
it&#8217;s not completely clear from reading the scripts.</p>
<p>NEW IDEAS:</p>
<p>Create a new central driver with all information living in Python modules.
Configuration files will provide the knowledge previously contained in the
upd-instroot and mk-images* scripts.</p>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3><a href="index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Introduction to Lorax</a></li>
<li><a class="reference internal" href="#before-lorax">Before Lorax</a></li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="index.html"
title="previous chapter">Welcome to Lorax&#8217;s documentation!</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="lorax-composer.html"
title="next chapter">lorax-composer</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/intro.txt"
rel="nofollow">Show Source</a></li>
</ul>
<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 class="right" >
<a href="lorax-composer.html" title="lorax-composer"
>next</a> |</li>
<li class="right" >
<a href="index.html" title="Welcome to Loraxs documentation!"
>previous</a> |</li>
<li><a href="index.html">Lorax 19.7.10 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2017, Red Hat, Inc..
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>

View File

@ -0,0 +1,226 @@
<!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>lorax-composer &mdash; Lorax 19.7.10 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: '19.7.10',
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>
<link rel="top" title="Lorax 19.7.10 documentation" href="index.html" />
<link rel="next" title="pylorax" href="modules.html" />
<link rel="prev" title="Introduction to Lorax" href="intro.html" />
</head>
<body>
<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 class="right" >
<a href="modules.html" title="pylorax"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="intro.html" title="Introduction to Lorax"
accesskey="P">previous</a> |</li>
<li><a href="index.html">Lorax 19.7.10 documentation</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="lorax-composer">
<h1>lorax-composer<a class="headerlink" href="#lorax-composer" title="Permalink to this headline"></a></h1>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Authors:</th><td class="field-body">Brian C. Lane &lt;<a class="reference external" href="mailto:bcl&#37;&#52;&#48;redhat&#46;com">bcl<span>&#64;</span>redhat<span>&#46;</span>com</a>&gt;</td>
</tr>
</tbody>
</table>
<p>lorax-composer is an API server that is compatible with the Weldr project&#8217;s
bdcs-api REST protocol. More information on Weldr can be found <a class="reference external" href="http://www.weldr.io">on the Weldr
blog</a>.</p>
<p>The server runs as root, and communication with it is via a unix domain socket
(<tt class="docutils literal"><span class="pre">/run/weldr/api.socket</span></tt> by default). The directory and socket are owned by
root:weldr so that any user in the weldr group can use the API to control
lorax-composer.</p>
<p>When starting the server it will check for the correct permissions and
ownership of a pre-existing directory, or it will create a new one if it
doesn&#8217;t exist. The socket path and group owner&#8217;s name can be changed from the
cmdline by passing it the <tt class="docutils literal"><span class="pre">--socket</span></tt> and <tt class="docutils literal"><span class="pre">--group</span></tt> arguments.</p>
<p>As of version 19.7.7 it will drop root privileges for the API thread. The queue
and compose thread still runs as root because it needs to be able to
mount/umount files and run Anaconda.</p>
<div class="section" id="logs">
<h2>Logs<a class="headerlink" href="#logs" title="Permalink to this headline"></a></h2>
<p>Logs are stored under <tt class="docutils literal"><span class="pre">/var/log/lorax-composer/</span></tt> and include all console
messages as well as extra debugging info and API requests.</p>
</div>
<div class="section" id="quickstart">
<h2>Quickstart<a class="headerlink" href="#quickstart" title="Permalink to this headline"></a></h2>
<ol class="arabic simple">
<li>Create a <tt class="docutils literal"><span class="pre">weldr</span></tt> user and group by running <tt class="docutils literal"><span class="pre">useradd</span> <span class="pre">weldr</span></tt></li>
<li>Remove any pre-existing socket directory with <tt class="docutils literal"><span class="pre">rm</span> <span class="pre">-rf</span> <span class="pre">/run/weldr/</span></tt>
A new directory with correct permissions will be created the first time the server runs.</li>
<li>Either start it via systemd with <tt class="docutils literal"><span class="pre">systemctl</span> <span class="pre">start</span> <span class="pre">lorax-composer</span></tt> or
run it directly with <tt class="docutils literal"><span class="pre">lorax-composer</span> <span class="pre">/path/to/recipes/</span></tt></li>
</ol>
<p>The <tt class="docutils literal"><span class="pre">/path/to/recipes/</span></tt> is where the recipe&#8217;s git repo will be created, and
all the recipes created with the <tt class="docutils literal"><span class="pre">/api/v0/recipes/new</span></tt> route will be stored.
If there are recipe <tt class="docutils literal"><span class="pre">.toml</span></tt> files in the top level of the directory they will
be imported into the recipe git storage.</p>
</div>
<div class="section" id="composing-images">
<h2>Composing Images<a class="headerlink" href="#composing-images" title="Permalink to this headline"></a></h2>
<p>As of version 19.7.7 lorax-composer can create <tt class="docutils literal"><span class="pre">tar</span></tt> output images. You can use curl to start
a compose like this:</p>
<div class="highlight-python"><pre>curl --unix-socket /run/weldr/api.socket -X POST -H "Content-Type: application/json" -d '{"recipe_name": "http-server", "compose_type": "tar", "branch": "master"}' http:///api/v0/compose</pre>
</div>
<p>And then monitor it by passing the returned build UUID to <tt class="docutils literal"><span class="pre">/compose/status/&lt;uuid&gt;</span></tt>.</p>
<p>Version 19.7.10 adds support for <tt class="docutils literal"><span class="pre">live-iso</span></tt> and <tt class="docutils literal"><span class="pre">partitioned-disk</span></tt></p>
</div>
<div class="section" id="adding-output-types">
<h2>Adding Output Types<a class="headerlink" href="#adding-output-types" title="Permalink to this headline"></a></h2>
<p>livemedia-creator supports a large number of output types, and only some of
these are currently available via lorax-composer. To add a new output type to
lorax-composer a kickstart file needs to be added to <tt class="docutils literal"><span class="pre">./share/composer/</span></tt>. The
name of the kickstart is what will be used by the <tt class="docutils literal"><span class="pre">/compose/types</span></tt> route, and the
<tt class="docutils literal"><span class="pre">compose_type</span></tt> field of the POST to start a compose. It also needs to have
code added to the <a class="reference internal" href="pylorax.api.html#pylorax.api.compose.compose_args" title="pylorax.api.compose.compose_args"><tt class="xref py py-func docutils literal"><span class="pre">pylorax.api.compose.compose_args()</span></tt></a> function. The
<tt class="docutils literal"><span class="pre">_MAP</span></tt> entry in this function defines what lorax-composer will pass to
<a class="reference internal" href="pylorax.html#pylorax.installer.novirt_install" title="pylorax.installer.novirt_install"><tt class="xref py py-func docutils literal"><span class="pre">pylorax.installer.novirt_install()</span></tt></a> when it runs the compose. When the
compose is finished the output files need to be copied out of the build
directory (<tt class="docutils literal"><span class="pre">/var/lib/lorax/composer/results/&lt;UUID&gt;/compose/</span></tt>),
<a class="reference internal" href="pylorax.api.html#pylorax.api.compose.move_compose_results" title="pylorax.api.compose.move_compose_results"><tt class="xref py py-func docutils literal"><span class="pre">pylorax.api.compose.move_compose_results()</span></tt></a> handles this for each type.
You should move them instead of copying to save space.</p>
<p>If the new output type does not have support in livemedia-creator it should be
added there first. This will make the output available to the widest number of
users.</p>
<div class="section" id="example-add-partitioned-disk-support">
<h3>Example: Add partitioned disk support<a class="headerlink" href="#example-add-partitioned-disk-support" title="Permalink to this headline"></a></h3>
<p>Partitioned disk support is something that livemedia-creator already supports
via the <tt class="docutils literal"><span class="pre">--make-disk</span></tt> cmdline argument. To add this to lorax-composer it
needs 3 things:</p>
<ul class="simple">
<li>A <tt class="docutils literal"><span class="pre">partitioned-disk.ks</span></tt> file in <tt class="docutils literal"><span class="pre">./share/composer/</span></tt></li>
<li>A new entry in the _MAP in <a class="reference internal" href="pylorax.api.html#pylorax.api.compose.compose_args" title="pylorax.api.compose.compose_args"><tt class="xref py py-func docutils literal"><span class="pre">pylorax.api.compose.compose_args()</span></tt></a></li>
<li>Add a bit of code to <a class="reference internal" href="pylorax.api.html#pylorax.api.compose.move_compose_results" title="pylorax.api.compose.move_compose_results"><tt class="xref py py-func docutils literal"><span class="pre">pylorax.api.compose.move_compose_results()</span></tt></a> to move the disk image from
the compose directory to the results directory.</li>
</ul>
<p>The <tt class="docutils literal"><span class="pre">partitioned-disk.ks</span></tt> is pretty similar to the example minimal kickstart
in <tt class="docutils literal"><span class="pre">./docs/rhel7-minimal.ks</span></tt>. You should remove the <tt class="docutils literal"><span class="pre">url</span></tt> and <tt class="docutils literal"><span class="pre">repo</span></tt>
commands, they will be added by the compose process. Make sure the bootloader
packages are included in the <tt class="docutils literal"><span class="pre">%packages</span></tt> section at the end of the kickstart,
and you will want to leave off the <tt class="docutils literal"><span class="pre">%end</span></tt> so that the compose can append the
list of packages from the recipe.</p>
<p>The new <tt class="docutils literal"><span class="pre">_MAP</span></tt> entry should be a copy of one of the existing entries, but with <tt class="docutils literal"><span class="pre">make_disk</span></tt> set
to <tt class="docutils literal"><span class="pre">True</span></tt>. Make sure that none of the other <tt class="docutils literal"><span class="pre">make_*</span></tt> options are <tt class="docutils literal"><span class="pre">True</span></tt>. The <tt class="docutils literal"><span class="pre">image_name</span></tt> is
what the name of the final image will be.</p>
<p><tt class="docutils literal"><span class="pre">move_compose_results()</span></tt> can be as simple as moving the output file into
the results directory, or it could do some post-processing on it. The end of
the function should always clean up the <tt class="docutils literal"><span class="pre">./compose/</span></tt> directory, removing any
unneeded extra files. This is especially true for the <tt class="docutils literal"><span class="pre">live-iso</span></tt> since it produces
the contents of the iso as well as the boot.iso itself.</p>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3><a href="index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">lorax-composer</a><ul>
<li><a class="reference internal" href="#logs">Logs</a></li>
<li><a class="reference internal" href="#quickstart">Quickstart</a></li>
<li><a class="reference internal" href="#composing-images">Composing Images</a></li>
<li><a class="reference internal" href="#adding-output-types">Adding Output Types</a><ul>
<li><a class="reference internal" href="#example-add-partitioned-disk-support">Example: Add partitioned disk support</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="intro.html"
title="previous chapter">Introduction to Lorax</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="modules.html"
title="next chapter">pylorax</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/lorax-composer.txt"
rel="nofollow">Show Source</a></li>
</ul>
<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 class="right" >
<a href="modules.html" title="pylorax"
>next</a> |</li>
<li class="right" >
<a href="intro.html" title="Introduction to Lorax"
>previous</a> |</li>
<li><a href="index.html">Lorax 19.7.10 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2017, Red Hat, Inc..
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>

158
lorax-composer/modules.html Normal file
View File

@ -0,0 +1,158 @@
<!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>pylorax &mdash; Lorax 19.7.10 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: '19.7.10',
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>
<link rel="top" title="Lorax 19.7.10 documentation" href="index.html" />
<link rel="next" title="pylorax Package" href="pylorax.html" />
<link rel="prev" title="lorax-composer" href="lorax-composer.html" />
</head>
<body>
<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 class="right" >
<a href="pylorax.html" title="pylorax Package"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="lorax-composer.html" title="lorax-composer"
accesskey="P">previous</a> |</li>
<li><a href="index.html">Lorax 19.7.10 documentation</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="pylorax">
<h1>pylorax<a class="headerlink" href="#pylorax" title="Permalink to this headline"></a></h1>
<div class="toctree-wrapper compound">
<ul>
<li class="toctree-l1"><a class="reference internal" href="pylorax.html">pylorax Package</a><ul>
<li class="toctree-l2"><a class="reference internal" href="pylorax.html#id1"><tt class="docutils literal"><span class="pre">pylorax</span></tt> Package</a></li>
<li class="toctree-l2"><a class="reference internal" href="pylorax.html#module-pylorax.base"><tt class="docutils literal"><span class="pre">base</span></tt> Module</a></li>
<li class="toctree-l2"><a class="reference internal" href="pylorax.html#module-pylorax.buildstamp"><tt class="docutils literal"><span class="pre">buildstamp</span></tt> Module</a></li>
<li class="toctree-l2"><a class="reference internal" href="pylorax.html#module-pylorax.creator"><tt class="docutils literal"><span class="pre">creator</span></tt> Module</a></li>
<li class="toctree-l2"><a class="reference internal" href="pylorax.html#module-pylorax.decorators"><tt class="docutils literal"><span class="pre">decorators</span></tt> Module</a></li>
<li class="toctree-l2"><a class="reference internal" href="pylorax.html#module-pylorax.discinfo"><tt class="docutils literal"><span class="pre">discinfo</span></tt> Module</a></li>
<li class="toctree-l2"><a class="reference internal" href="pylorax.html#module-pylorax.executils"><tt class="docutils literal"><span class="pre">executils</span></tt> Module</a></li>
<li class="toctree-l2"><a class="reference internal" href="pylorax.html#module-pylorax.imgutils"><tt class="docutils literal"><span class="pre">imgutils</span></tt> Module</a></li>
<li class="toctree-l2"><a class="reference internal" href="pylorax.html#module-pylorax.installer"><tt class="docutils literal"><span class="pre">installer</span></tt> Module</a></li>
<li class="toctree-l2"><a class="reference internal" href="pylorax.html#module-pylorax.logmonitor"><tt class="docutils literal"><span class="pre">logmonitor</span></tt> Module</a></li>
<li class="toctree-l2"><a class="reference internal" href="pylorax.html#module-pylorax.ltmpl"><tt class="docutils literal"><span class="pre">ltmpl</span></tt> Module</a></li>
<li class="toctree-l2"><a class="reference internal" href="pylorax.html#module-pylorax.output"><tt class="docutils literal"><span class="pre">output</span></tt> Module</a></li>
<li class="toctree-l2"><a class="reference internal" href="pylorax.html#module-pylorax.sysutils"><tt class="docutils literal"><span class="pre">sysutils</span></tt> Module</a></li>
<li class="toctree-l2"><a class="reference internal" href="pylorax.html#module-pylorax.treebuilder"><tt class="docutils literal"><span class="pre">treebuilder</span></tt> Module</a></li>
<li class="toctree-l2"><a class="reference internal" href="pylorax.html#module-pylorax.treeinfo"><tt class="docutils literal"><span class="pre">treeinfo</span></tt> Module</a></li>
<li class="toctree-l2"><a class="reference internal" href="pylorax.html#module-pylorax.yumhelper"><tt class="docutils literal"><span class="pre">yumhelper</span></tt> Module</a></li>
<li class="toctree-l2"><a class="reference internal" href="pylorax.html#subpackages">Subpackages</a><ul>
<li class="toctree-l3"><a class="reference internal" href="pylorax.api.html">api Package</a><ul>
<li class="toctree-l4"><a class="reference internal" href="pylorax.api.html#id1"><tt class="docutils literal"><span class="pre">api</span></tt> Package</a></li>
<li class="toctree-l4"><a class="reference internal" href="pylorax.api.html#module-pylorax.api.compose"><tt class="docutils literal"><span class="pre">compose</span></tt> Module</a></li>
<li class="toctree-l4"><a class="reference internal" href="pylorax.api.html#module-pylorax.api.config"><tt class="docutils literal"><span class="pre">config</span></tt> Module</a></li>
<li class="toctree-l4"><a class="reference internal" href="pylorax.api.html#module-pylorax.api.crossdomain"><tt class="docutils literal"><span class="pre">crossdomain</span></tt> Module</a></li>
<li class="toctree-l4"><a class="reference internal" href="pylorax.api.html#module-pylorax.api.projects"><tt class="docutils literal"><span class="pre">projects</span></tt> Module</a></li>
<li class="toctree-l4"><a class="reference internal" href="pylorax.api.html#module-pylorax.api.queue"><tt class="docutils literal"><span class="pre">queue</span></tt> Module</a></li>
<li class="toctree-l4"><a class="reference internal" href="pylorax.api.html#module-pylorax.api.recipes"><tt class="docutils literal"><span class="pre">recipes</span></tt> Module</a></li>
<li class="toctree-l4"><a class="reference internal" href="pylorax.api.html#module-pylorax.api.server"><tt class="docutils literal"><span class="pre">server</span></tt> Module</a></li>
<li class="toctree-l4"><a class="reference internal" href="pylorax.api.html#module-pylorax.api.v0"><tt class="docutils literal"><span class="pre">v0</span></tt> Module</a></li>
<li class="toctree-l4"><a class="reference internal" href="pylorax.api.html#module-pylorax.api.workspace"><tt class="docutils literal"><span class="pre">workspace</span></tt> Module</a></li>
<li class="toctree-l4"><a class="reference internal" href="pylorax.api.html#module-pylorax.api.yumbase"><tt class="docutils literal"><span class="pre">yumbase</span></tt> Module</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h4>Previous topic</h4>
<p class="topless"><a href="lorax-composer.html"
title="previous chapter">lorax-composer</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="pylorax.html"
title="next chapter">pylorax Package</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/modules.txt"
rel="nofollow">Show Source</a></li>
</ul>
<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 class="right" >
<a href="pylorax.html" title="pylorax Package"
>next</a> |</li>
<li class="right" >
<a href="lorax-composer.html" title="lorax-composer"
>previous</a> |</li>
<li><a href="index.html">Lorax 19.7.10 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2017, Red Hat, Inc..
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>

BIN
lorax-composer/objects.inv Normal file

Binary file not shown.

View File

@ -0,0 +1,246 @@
<!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>Python Module Index &mdash; Lorax 19.7.10 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: '19.7.10',
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>
<link rel="top" title="Lorax 19.7.10 documentation" href="index.html" />
</head>
<body>
<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="#" title="Python Module Index"
>modules</a> |</li>
<li><a href="index.html">Lorax 19.7.10 documentation</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<h1>Python Module Index</h1>
<div class="modindex-jumpbox">
<a href="#cap-p"><strong>p</strong></a>
</div>
<table class="indextable modindextable" cellspacing="0" cellpadding="2">
<tr class="pcap"><td></td><td>&nbsp;</td><td></td></tr>
<tr class="cap" id="cap-p"><td></td><td>
<strong>p</strong></td><td></td></tr>
<tr>
<td><img src="_static/minus.png" class="toggler"
id="toggle-1" style="display: none" alt="-" /></td>
<td>
<tt class="xref">pylorax</tt></td><td>
<em></em></td></tr>
<tr class="cg-1">
<td></td>
<td>&nbsp;&nbsp;&nbsp;
<a href="pylorax.html#module-pylorax.__init__"><tt class="xref">pylorax.__init__</tt></a></td><td>
<em></em></td></tr>
<tr class="cg-1">
<td></td>
<td>&nbsp;&nbsp;&nbsp;
<a href="pylorax.api.html#module-pylorax.api"><tt class="xref">pylorax.api</tt></a></td><td>
<em></em></td></tr>
<tr class="cg-1">
<td></td>
<td>&nbsp;&nbsp;&nbsp;
<a href="pylorax.api.html#module-pylorax.api.compose"><tt class="xref">pylorax.api.compose</tt></a></td><td>
<em></em></td></tr>
<tr class="cg-1">
<td></td>
<td>&nbsp;&nbsp;&nbsp;
<a href="pylorax.api.html#module-pylorax.api.config"><tt class="xref">pylorax.api.config</tt></a></td><td>
<em></em></td></tr>
<tr class="cg-1">
<td></td>
<td>&nbsp;&nbsp;&nbsp;
<a href="pylorax.api.html#module-pylorax.api.crossdomain"><tt class="xref">pylorax.api.crossdomain</tt></a></td><td>
<em></em></td></tr>
<tr class="cg-1">
<td></td>
<td>&nbsp;&nbsp;&nbsp;
<a href="pylorax.api.html#module-pylorax.api.projects"><tt class="xref">pylorax.api.projects</tt></a></td><td>
<em></em></td></tr>
<tr class="cg-1">
<td></td>
<td>&nbsp;&nbsp;&nbsp;
<a href="pylorax.api.html#module-pylorax.api.queue"><tt class="xref">pylorax.api.queue</tt></a></td><td>
<em></em></td></tr>
<tr class="cg-1">
<td></td>
<td>&nbsp;&nbsp;&nbsp;
<a href="pylorax.api.html#module-pylorax.api.recipes"><tt class="xref">pylorax.api.recipes</tt></a></td><td>
<em></em></td></tr>
<tr class="cg-1">
<td></td>
<td>&nbsp;&nbsp;&nbsp;
<a href="pylorax.api.html#module-pylorax.api.server"><tt class="xref">pylorax.api.server</tt></a></td><td>
<em></em></td></tr>
<tr class="cg-1">
<td></td>
<td>&nbsp;&nbsp;&nbsp;
<a href="pylorax.api.html#module-pylorax.api.v0"><tt class="xref">pylorax.api.v0</tt></a></td><td>
<em></em></td></tr>
<tr class="cg-1">
<td></td>
<td>&nbsp;&nbsp;&nbsp;
<a href="pylorax.api.html#module-pylorax.api.workspace"><tt class="xref">pylorax.api.workspace</tt></a></td><td>
<em></em></td></tr>
<tr class="cg-1">
<td></td>
<td>&nbsp;&nbsp;&nbsp;
<a href="pylorax.api.html#module-pylorax.api.yumbase"><tt class="xref">pylorax.api.yumbase</tt></a></td><td>
<em></em></td></tr>
<tr class="cg-1">
<td></td>
<td>&nbsp;&nbsp;&nbsp;
<a href="pylorax.html#module-pylorax.base"><tt class="xref">pylorax.base</tt></a></td><td>
<em></em></td></tr>
<tr class="cg-1">
<td></td>
<td>&nbsp;&nbsp;&nbsp;
<a href="pylorax.html#module-pylorax.buildstamp"><tt class="xref">pylorax.buildstamp</tt></a></td><td>
<em></em></td></tr>
<tr class="cg-1">
<td></td>
<td>&nbsp;&nbsp;&nbsp;
<a href="pylorax.html#module-pylorax.creator"><tt class="xref">pylorax.creator</tt></a></td><td>
<em></em></td></tr>
<tr class="cg-1">
<td></td>
<td>&nbsp;&nbsp;&nbsp;
<a href="pylorax.html#module-pylorax.decorators"><tt class="xref">pylorax.decorators</tt></a></td><td>
<em></em></td></tr>
<tr class="cg-1">
<td></td>
<td>&nbsp;&nbsp;&nbsp;
<a href="pylorax.html#module-pylorax.discinfo"><tt class="xref">pylorax.discinfo</tt></a></td><td>
<em></em></td></tr>
<tr class="cg-1">
<td></td>
<td>&nbsp;&nbsp;&nbsp;
<a href="pylorax.html#module-pylorax.executils"><tt class="xref">pylorax.executils</tt></a></td><td>
<em></em></td></tr>
<tr class="cg-1">
<td></td>
<td>&nbsp;&nbsp;&nbsp;
<a href="pylorax.html#module-pylorax.imgutils"><tt class="xref">pylorax.imgutils</tt></a></td><td>
<em></em></td></tr>
<tr class="cg-1">
<td></td>
<td>&nbsp;&nbsp;&nbsp;
<a href="pylorax.html#module-pylorax.installer"><tt class="xref">pylorax.installer</tt></a></td><td>
<em></em></td></tr>
<tr class="cg-1">
<td></td>
<td>&nbsp;&nbsp;&nbsp;
<a href="pylorax.html#module-pylorax.logmonitor"><tt class="xref">pylorax.logmonitor</tt></a></td><td>
<em></em></td></tr>
<tr class="cg-1">
<td></td>
<td>&nbsp;&nbsp;&nbsp;
<a href="pylorax.html#module-pylorax.ltmpl"><tt class="xref">pylorax.ltmpl</tt></a></td><td>
<em></em></td></tr>
<tr class="cg-1">
<td></td>
<td>&nbsp;&nbsp;&nbsp;
<a href="pylorax.html#module-pylorax.output"><tt class="xref">pylorax.output</tt></a></td><td>
<em></em></td></tr>
<tr class="cg-1">
<td></td>
<td>&nbsp;&nbsp;&nbsp;
<a href="pylorax.html#module-pylorax.sysutils"><tt class="xref">pylorax.sysutils</tt></a></td><td>
<em></em></td></tr>
<tr class="cg-1">
<td></td>
<td>&nbsp;&nbsp;&nbsp;
<a href="pylorax.html#module-pylorax.treebuilder"><tt class="xref">pylorax.treebuilder</tt></a></td><td>
<em></em></td></tr>
<tr class="cg-1">
<td></td>
<td>&nbsp;&nbsp;&nbsp;
<a href="pylorax.html#module-pylorax.treeinfo"><tt class="xref">pylorax.treeinfo</tt></a></td><td>
<em></em></td></tr>
<tr class="cg-1">
<td></td>
<td>&nbsp;&nbsp;&nbsp;
<a href="pylorax.html#module-pylorax.yumhelper"><tt class="xref">pylorax.yumhelper</tt></a></td><td>
<em></em></td></tr>
</table>
</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="#" title="Python Module Index"
>modules</a> |</li>
<li><a href="index.html">Lorax 19.7.10 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2017, Red Hat, Inc..
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>

File diff suppressed because it is too large Load Diff

1611
lorax-composer/pylorax.html Normal file

File diff suppressed because it is too large Load Diff

105
lorax-composer/search.html Normal file
View File

@ -0,0 +1,105 @@
<!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>Search &mdash; Lorax 19.7.10 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: '19.7.10',
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/searchtools.js"></script>
<link rel="top" title="Lorax 19.7.10 documentation" href="index.html" />
<script type="text/javascript">
jQuery(function() { Search.loadIndex("searchindex.js"); });
</script>
</head>
<body>
<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">Lorax 19.7.10 documentation</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<h1 id="search-documentation">Search</h1>
<div id="fallback" class="admonition warning">
<script type="text/javascript">$('#fallback').hide();</script>
<p>
Please activate JavaScript to enable the search
functionality.
</p>
</div>
<p>
From here you can search these documents. Enter your search
words into the box below and click "search". Note that the search
function will automatically search for all of the words. Pages
containing fewer words won't appear in the result list.
</p>
<form action="" method="get">
<input type="text" name="q" value="" />
<input type="submit" value="search" />
<span id="search-progress" style="padding-left: 10px"></span>
</form>
<div id="search-results">
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
</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">Lorax 19.7.10 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2017, Red Hat, Inc..
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>

File diff suppressed because one or more lines are too long