Update beta: add intro docs for python types

This commit is contained in:
Darko Poljak 2019-05-13 11:25:01 +02:00
parent 50ea470ef8
commit 2da9d112f7
3 changed files with 202 additions and 1 deletions

View file

@ -393,3 +393,108 @@ How to include a type into upstream cdist
If you think your type may be useful for others, ensure it works with the
current master branch of cdist and have a look at `cdist hacking <cdist-hacker.html>`_ on
how to submit it.
Python types
------------
From version/branch **beta** cdist support python types, types that are written
in python language with cdist's core support. cdist detects such type if type is
detectable as a python package, i.e. if **__init__.py** file is present in type's
root directory. Upon that detection cdist will try to run such type as core python
type.
Note that this differs from plain cdist type where scripts are written in pure
python and have a proper shebang.
Core python types replace manifest and gencode scripts. Parameters, singleton,
nonparallel are still defined as for common types. Explorer code is also written
in shell, since this is the code that is directly executed at target host.
When writing python type you can extend **cdist.core.PythonType** class.
You need to implement the following methods:
* **type_manifest**: implementation should yield **cdist.core.ManifestEntry**
instances, or **yield from ()** if type does not use other types
* **type_gencode**: implementation should return a string consisting of lines
of shell code that will be executed at target host.
**cdist.core.ManifestEntry** is a python type way for invoking another cdist type.
Example:
.. code-block:: sh
...
class DummyConfig(PythonType):
def type_manifest(self):
# Invoking pyhton file type with provided stdin source with
# specified content.
filepy = ManifestEntry(name='__file_py', stdin='dummy=py\n',
parameters={
'/root/dummypy.conf': None,
'--mode': '0640',
'--owner': 'root',
'--group': 'root',
'--source': '-',
})
yield filepy
# Invoking pyhton file type with specified file as source.
self_path = os.path.dirname(os.path.realpath(__file__))
conf_path = os.path.join(self_path, 'files', 'dummypy.conf')
filepy = ManifestEntry(name='__file_py',
parameters={
'/root/dummypy2.conf': None,
'--mode': '0640',
'--owner': 'root',
'--group': 'root',
'--source': conf_path,
})
yield filepy
# Invoking standard shell file type with stdin source feeded
# from file.
self_path = os.path.dirname(os.path.realpath(__file__))
conf_path = os.path.join(self_path, 'files', 'dummysh.conf')
with open(conf_path, 'r') as f:
filepy = ManifestEntry(name='__file', stdin=f,
parameters={
'/root/dummysh.conf': None,
'--mode': '0600',
'--owner': 'root',
'--group': 'root',
'--source': '-',
})
yield filepy
...
**cdist.core.PythonType** class provides the following methods:
* **get_parameter**: get type parameter
* **get_explorer_file**: get path to file for specified explorer
* **get_explorer**: get value for specified explorer
* **run_local**: run specified command locally
* **run_remote**: run specified command remotely
* **transfer**: transfer specified source to the remote
* **die**: raise error
* **send_message**: send message
* **receive_message**: get message.
When running python type, cdist will save output streams to **gencode-py**,
stdout and stderr output files.
As a reference implementation you can take a look at **__file_py** type,
which is re-implementation of **__file** type.
Furthermore, under **docs/dev/python-types** there are sample cdist conf directory,
init manifests and scripts for running and measuring duration of samples.
There, under **conf/type/__dummy_config** you can find another example of
python type, which (unlike **__file_py** type) also uses new manifest implementation
that yields **ManifestEntry** instances.
**NOTE** that python types implementation is under the beta, not directly controled by
the **-b/--beta** option. It is controled by the explicit usage of python types in
your config.
Also, this documenation is only an introduction, and not a complete guide to python
types. Currently, it is just a short introduction so one can start to write and use
python types.

View file

@ -124,6 +124,7 @@
<li class="toctree-l2"><a class="reference internal" href="#log-level-in-types">14.20. Log level in types</a></li>
<li class="toctree-l2"><a class="reference internal" href="#hints-for-typewriters">14.21. Hints for typewriters</a></li>
<li class="toctree-l2"><a class="reference internal" href="#how-to-include-a-type-into-upstream-cdist">14.22. How to include a type into upstream cdist</a></li>
<li class="toctree-l2"><a class="reference internal" href="#python-types">14.23. Python types</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="cdist-types.html">15. cdist types</a></li>
@ -555,6 +556,101 @@ never ever touch this folder).</p>
current master branch of cdist and have a look at <a class="reference external" href="cdist-hacker.html">cdist hacking</a> on
how to submit it.</p>
</div>
<div class="section" id="python-types">
<h2>14.23. Python types<a class="headerlink" href="#python-types" title="Permalink to this headline"></a></h2>
<p>From version/branch <strong>beta</strong> cdist support python types, types that are written
in python language with cdist's core support. cdist detects such type if type is
detectable as a python package, i.e. if <strong>__init__.py</strong> file is present in type's
root directory. Upon that detection cdist will try to run such type as core python
type.</p>
<p>Note that this differs from plain cdist type where scripts are written in pure
python and have a proper shebang.</p>
<p>Core python types replace manifest and gencode scripts. Parameters, singleton,
nonparallel are still defined as for common types. Explorer code is also written
in shell, since this is the code that is directly executed at target host.</p>
<p>When writing python type you can extend <strong>cdist.core.PythonType</strong> class.
You need to implement the following methods:</p>
<ul class="simple">
<li><strong>type_manifest</strong>: implementation should yield <strong>cdist.core.ManifestEntry</strong>
instances, or <strong>yield from ()</strong> if type does not use other types</li>
<li><strong>type_gencode</strong>: implementation should return a string consisting of lines
of shell code that will be executed at target host.</li>
</ul>
<p><strong>cdist.core.ManifestEntry</strong> is a python type way for invoking another cdist type.
Example:</p>
<div class="highlight-sh notranslate"><div class="highlight"><pre><span></span>...
class DummyConfig<span class="o">(</span>PythonType<span class="o">)</span>:
def type_manifest<span class="o">(</span>self<span class="o">)</span>:
<span class="c1"># Invoking pyhton file type with provided stdin source with</span>
<span class="c1"># specified content.</span>
<span class="nv">filepy</span> <span class="o">=</span> ManifestEntry<span class="o">(</span><span class="nv">name</span><span class="o">=</span><span class="s1">&#39;__file_py&#39;</span>, <span class="nv">stdin</span><span class="o">=</span><span class="s1">&#39;dummy=py\n&#39;</span>,
<span class="nv">parameters</span><span class="o">={</span>
<span class="s1">&#39;/root/dummypy.conf&#39;</span>: None,
<span class="s1">&#39;--mode&#39;</span>: <span class="s1">&#39;0640&#39;</span>,
<span class="s1">&#39;--owner&#39;</span>: <span class="s1">&#39;root&#39;</span>,
<span class="s1">&#39;--group&#39;</span>: <span class="s1">&#39;root&#39;</span>,
<span class="s1">&#39;--source&#39;</span>: <span class="s1">&#39;-&#39;</span>,
<span class="o">})</span>
yield filepy
<span class="c1"># Invoking pyhton file type with specified file as source.</span>
<span class="nv">self_path</span> <span class="o">=</span> os.path.dirname<span class="o">(</span>os.path.realpath<span class="o">(</span>__file__<span class="o">))</span>
<span class="nv">conf_path</span> <span class="o">=</span> os.path.join<span class="o">(</span>self_path, <span class="s1">&#39;files&#39;</span>, <span class="s1">&#39;dummypy.conf&#39;</span><span class="o">)</span>
<span class="nv">filepy</span> <span class="o">=</span> ManifestEntry<span class="o">(</span><span class="nv">name</span><span class="o">=</span><span class="s1">&#39;__file_py&#39;</span>,
<span class="nv">parameters</span><span class="o">={</span>
<span class="s1">&#39;/root/dummypy2.conf&#39;</span>: None,
<span class="s1">&#39;--mode&#39;</span>: <span class="s1">&#39;0640&#39;</span>,
<span class="s1">&#39;--owner&#39;</span>: <span class="s1">&#39;root&#39;</span>,
<span class="s1">&#39;--group&#39;</span>: <span class="s1">&#39;root&#39;</span>,
<span class="s1">&#39;--source&#39;</span>: conf_path,
<span class="o">})</span>
yield filepy
<span class="c1"># Invoking standard shell file type with stdin source feeded</span>
<span class="c1"># from file.</span>
<span class="nv">self_path</span> <span class="o">=</span> os.path.dirname<span class="o">(</span>os.path.realpath<span class="o">(</span>__file__<span class="o">))</span>
<span class="nv">conf_path</span> <span class="o">=</span> os.path.join<span class="o">(</span>self_path, <span class="s1">&#39;files&#39;</span>, <span class="s1">&#39;dummysh.conf&#39;</span><span class="o">)</span>
with open<span class="o">(</span>conf_path, <span class="s1">&#39;r&#39;</span><span class="o">)</span> as f:
<span class="nv">filepy</span> <span class="o">=</span> ManifestEntry<span class="o">(</span><span class="nv">name</span><span class="o">=</span><span class="s1">&#39;__file&#39;</span>, <span class="nv">stdin</span><span class="o">=</span>f,
<span class="nv">parameters</span><span class="o">={</span>
<span class="s1">&#39;/root/dummysh.conf&#39;</span>: None,
<span class="s1">&#39;--mode&#39;</span>: <span class="s1">&#39;0600&#39;</span>,
<span class="s1">&#39;--owner&#39;</span>: <span class="s1">&#39;root&#39;</span>,
<span class="s1">&#39;--group&#39;</span>: <span class="s1">&#39;root&#39;</span>,
<span class="s1">&#39;--source&#39;</span>: <span class="s1">&#39;-&#39;</span>,
<span class="o">})</span>
yield filepy
...
</pre></div>
</div>
<p><strong>cdist.core.PythonType</strong> class provides the following methods:</p>
<ul class="simple">
<li><strong>get_parameter</strong>: get type parameter</li>
<li><strong>get_explorer_file</strong>: get path to file for specified explorer</li>
<li><strong>get_explorer</strong>: get value for specified explorer</li>
<li><strong>run_local</strong>: run specified command locally</li>
<li><strong>run_remote</strong>: run specified command remotely</li>
<li><strong>transfer</strong>: transfer specified source to the remote</li>
<li><strong>die</strong>: raise error</li>
<li><strong>send_message</strong>: send message</li>
<li><strong>receive_message</strong>: get message.</li>
</ul>
<p>When running python type, cdist will save output streams to <strong>gencode-py</strong>,
stdout and stderr output files.</p>
<p>As a reference implementation you can take a look at <strong>__file_py</strong> type,
which is re-implementation of <strong>__file</strong> type.</p>
<p>Furthermore, under <strong>docs/dev/python-types</strong> there are sample cdist conf directory,
init manifests and scripts for running and measuring duration of samples.
There, under <strong>conf/type/__dummy_config</strong> you can find another example of
python type, which (unlike <strong>__file_py</strong> type) also uses new manifest implementation
that yields <strong>ManifestEntry</strong> instances.</p>
<p><strong>NOTE</strong> that python types implementation is under the beta, not directly controled by
the <strong>-b/--beta</strong> option. It is controled by the explicit usage of python types in
your config.</p>
<p>Also, this documenation is only an introduction, and not a complete guide to python
types. Currently, it is just a short introduction so one can start to write and use
python types.</p>
</div>
</div>

File diff suppressed because one or more lines are too long