659 lines
81 KiB
HTML
659 lines
81 KiB
HTML
|
|
||
|
|
||
|
<!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 — 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> »</li>
|
||
|
<li><a href="../../index.html" >Module code</a> »</li>
|
||
|
<li><a href="../api.html" accesskey="U">pylorax.api</a> »</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 <http://www.gnu.org/licenses/>.</span>
|
||
|
<span class="c">#</span>
|
||
|
<span class="sd">""" Functions to monitor compose queue and run anaconda"""</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">"pylorax"</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">"""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"> """</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">"composer"</span><span class="p">,</span> <span class="s">"lib_dir"</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">"composer"</span><span class="p">,</span> <span class="s">"share_dir"</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">"""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"> """</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">"""Sort the queue entries by their mtime, not their names"""</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">"queue/new"</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">"queue/run"</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">"queue/run"</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">"queue/new"</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">"Moved unfinished compose </span><span class="si">%s</span><span class="s"> back to new state"</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">"queue/new"</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">"queue/new"</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">"queue/run"</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">"Starting new compose: </span><span class="si">%s</span><span class="s">"</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">"STATUS"</span><span class="p">),</span> <span class="s">"w"</span><span class="p">)</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">"RUNNING</span><span class="se">\n</span><span class="s">"</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">"Finished building </span><span class="si">%s</span><span class="s">, results are in </span><span class="si">%s</span><span class="s">"</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">"STATUS"</span><span class="p">),</span> <span class="s">"w"</span><span class="p">)</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">"FINISHED</span><span class="se">\n</span><span class="s">"</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">"traceback: </span><span class="si">%s</span><span class="s">"</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("Error running compose: %s", 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">"STATUS"</span><span class="p">),</span> <span class="s">"w"</span><span class="p">)</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">"FAILED</span><span class="se">\n</span><span class="s">"</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">"""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"> """</span>
|
||
|
|
||
|
<span class="c"># Check on the ks'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">"final-kickstart.ks"</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">"Missing kickstart file at </span><span class="si">%s</span><span class="s">"</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">"logs/"</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">"config.toml"</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">"Missing config.toml for </span><span class="si">%s</span><span class="s">"</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">"r"</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">"image_name"</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">"image_name"</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">"no_virt"</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">"disk_image"</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">"fs_image"</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">"keep_image"</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">"domacboot"</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">"anaconda_args"</span><span class="p">]</span> <span class="o">=</span> <span class="s">""</span>
|
||
|
<span class="n">cfg_dict</span><span class="p">[</span><span class="s">"proxy"</span><span class="p">]</span> <span class="o">=</span> <span class="s">""</span>
|
||
|
<span class="n">cfg_dict</span><span class="p">[</span><span class="s">"armplatform"</span><span class="p">]</span> <span class="o">=</span> <span class="s">""</span>
|
||
|
<span class="n">cfg_dict</span><span class="p">[</span><span class="s">"squashfs_args"</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">"lorax_templates"</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">"tmp"</span><span class="p">]</span> <span class="o">=</span> <span class="s">"/var/tmp/"</span>
|
||
|
<span class="n">cfg_dict</span><span class="p">[</span><span class="s">"dracut_args"</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">"result_dir"</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">"compose"</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">"result_dir"</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">"/tmp/NOSAVE_INPUT_KS"</span><span class="p">,</span> <span class="s">"/tmp/NOSAVE_LOGS"</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">"w"</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">"CANCEL"</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">"cfg = </span><span class="si">%s</span><span class="s">"</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">"TEST"</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">"r"</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">"TESTING FAILED compose"</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">"w"</span><span class="p">)</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">"TEST IMAGE"</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">"Install finished, chowning results to </span><span class="si">%s</span><span class="s">:</span><span class="si">%s</span><span class="s">"</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">"chown"</span><span class="p">,</span> <span class="s">"-R"</span><span class="p">,</span> <span class="s">"</span><span class="si">%s</span><span class="s">:</span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">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">"""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. 'tar')</span>
|
||
|
<span class="sd"> :rtype: str</span>
|
||
|
<span class="sd"> :raises: RuntimeError if no kickstart template can be found.</span>
|
||
|
<span class="sd"> """</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">"*.ks"</span><span class="p">))</span>
|
||
|
<span class="k">if</span> <span class="s">"final-kickstart"</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">"Cannot find ks template for build </span><span class="si">%s</span><span class="s">"</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">"""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"> """</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">"STATUS"</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">"STATUS"</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">"recipe.toml"</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">"id"</span><span class="p">:</span> <span class="n">build_id</span><span class="p">,</span>
|
||
|
<span class="s">"queue_status"</span><span class="p">:</span> <span class="n">status</span><span class="p">,</span>
|
||
|
<span class="s">"timestamp"</span><span class="p">:</span> <span class="n">mtime</span><span class="p">,</span>
|
||
|
<span class="s">"compose_type"</span><span class="p">:</span> <span class="n">compose_type</span><span class="p">,</span>
|
||
|
<span class="s">"recipe"</span><span class="p">:</span> <span class="n">recipe</span><span class="p">[</span><span class="s">"name"</span><span class="p">],</span>
|
||
|
<span class="s">"version"</span><span class="p">:</span> <span class="n">recipe</span><span class="p">[</span><span class="s">"version"</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">"""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. "new" is the list of uuids that are waiting to be built,</span>
|
||
|
<span class="sd"> and "run" has the uuids that are being built (currently limited to 1 at a time).</span>
|
||
|
<span class="sd"> """</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">"composer"</span><span class="p">,</span> <span class="s">"lib_dir"</span><span class="p">),</span> <span class="s">"queue"</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">"new/*"</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">"run/*"</span><span class="p">))]</span>
|
||
|
|
||
|
<span class="k">return</span> <span class="p">{</span>
|
||
|
<span class="s">"new"</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">"run"</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">"""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"> """</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">"composer"</span><span class="p">,</span> <span class="s">"lib_dir"</span><span class="p">),</span> <span class="s">"results"</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">"""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, "FINISHED", or "FAILED"</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"> """</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">"FINISHED"</span><span class="p">,</span> <span class="s">"FAILED"</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">"composer"</span><span class="p">,</span> <span class="s">"lib_dir"</span><span class="p">),</span> <span class="s">"results"</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">"/*"</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">"Checking status of build </span><span class="si">%s</span><span class="s">"</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">"STATUS"</span><span class="p">),</span> <span class="s">"r"</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">"""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"> """</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 -> RUNNING or it can move from RUNNING -> FINISHED|FAILED</span>
|
||
|
|
||
|
<span class="c"># If it is in WAITING remove the symlink and then check to make sure it didn'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">"composer"</span><span class="p">,</span> <span class="s">"lib_dir"</span><span class="p">),</span> <span class="s">"queue"</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">"new"</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">"run"</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">"composer"</span><span class="p">,</span> <span class="s">"lib_dir"</span><span class="p">),</span> <span class="s">"results"</span><span class="p">,</span> <span class="n">uuid</span><span class="p">,</span> <span class="s">"CANCEL"</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">"w"</span><span class="p">)</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">"</span><span class="se">\n</span><span class="s">"</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">"queue_status"</span><span class="p">]</span> <span class="o">==</span> <span class="s">"FAILED"</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">></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">"Failed to cancel the build of </span><span class="si">%s</span><span class="s">"</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">"""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"> """</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">"composer"</span><span class="p">,</span> <span class="s">"lib_dir"</span><span class="p">),</span> <span class="s">"results"</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"><</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">"Directory length is too short: </span><span class="si">%s</span><span class="s">"</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">"""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"> """</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">"composer"</span><span class="p">,</span> <span class="s">"lib_dir"</span><span class="p">),</span> <span class="s">"results"</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">"</span><span class="si">%s</span><span class="s"> is not a valid build_id"</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">"config.toml"</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">"Missing config.toml for </span><span class="si">%s</span><span class="s">"</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">"r"</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">"frozen.toml"</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">"Missing frozen.toml for </span><span class="si">%s</span><span class="s">"</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">"r"</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">"deps.toml"</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">"Missing deps.toml for </span><span class="si">%s</span><span class="s">"</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">"r"</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">"STATUS"</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">"COMMIT"</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">"r"</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">"id"</span><span class="p">:</span> <span class="n">uuid</span><span class="p">,</span>
|
||
|
<span class="s">"config"</span><span class="p">:</span> <span class="n">cfg_dict</span><span class="p">,</span>
|
||
|
<span class="s">"recipe"</span><span class="p">:</span> <span class="n">frozen_dict</span><span class="p">,</span>
|
||
|
<span class="s">"commit"</span><span class="p">:</span> <span class="n">commit_id</span><span class="p">,</span>
|
||
|
<span class="s">"deps"</span><span class="p">:</span> <span class="n">deps_dict</span><span class="p">,</span>
|
||
|
<span class="s">"compose_type"</span><span class="p">:</span> <span class="n">compose_type</span><span class="p">,</span>
|
||
|
<span class="s">"queue_status"</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">"""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'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"> """</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">"composer"</span><span class="p">,</span> <span class="s">"lib_dir"</span><span class="p">),</span> <span class="s">"results"</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">"</span><span class="si">%s</span><span class="s"> is not a valid build_id"</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">"config.toml"</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">"Missing config.toml for </span><span class="si">%s</span><span class="s">"</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">"r"</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">"image_name"</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">"/logs"</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">"*"</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">"tar"</span><span class="p">,</span> <span class="s">"-C"</span><span class="p">,</span> <span class="n">uuid_dir</span><span class="p">,</span> <span class="s">"-cf-"</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">"""Return the filename and full path of the build'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"> """</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">"composer"</span><span class="p">,</span> <span class="s">"lib_dir"</span><span class="p">),</span> <span class="s">"results"</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">"</span><span class="si">%s</span><span class="s"> is not a valid build_id"</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">"config.toml"</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">"Missing config.toml for </span><span class="si">%s</span><span class="s">"</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">"r"</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">"image_name"</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">"""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"> """</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">"composer"</span><span class="p">,</span> <span class="s">"lib_dir"</span><span class="p">),</span> <span class="s">"results"</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">"</span><span class="si">%s</span><span class="s"> is not a valid build_id"</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">"queue_status"</span><span class="p">]</span> <span class="o">==</span> <span class="s">"RUNNING"</span><span class="p">:</span>
|
||
|
<span class="n">log_path</span> <span class="o">=</span> <span class="s">"/tmp/anaconda.log"</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">"logs"</span><span class="p">,</span> <span class="s">"anaconda"</span><span class="p">,</span> <span class="s">"anaconda.log"</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">"No anaconda.log available."</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">"r"</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"><</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> »</li>
|
||
|
<li><a href="../../index.html" >Module code</a> »</li>
|
||
|
<li><a href="../api.html" >pylorax.api</a> »</li>
|
||
|
</ul>
|
||
|
</div>
|
||
|
<div class="footer">
|
||
|
© Copyright 2017, Red Hat, Inc..
|
||
|
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
|
||
|
</div>
|
||
|
</body>
|
||
|
</html>
|