mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
Added start of a module development guide, prob needs some editing and maybe some simpler examples
This commit is contained in:
parent
505d3942b0
commit
d9c626e686
18 changed files with 294 additions and 11 deletions
|
@ -118,6 +118,7 @@ s.parentNode.insertBefore(ga, s);
|
|||
<li class="toctree-l1 current"><a class="current reference internal" href="">YAML Syntax</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="playbooks.html">Playbooks</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="api.html">Using the Python API</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="moduledev.html">Module Development Guide</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="faq.html">Frequently Asked Questions</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="man.html">Man Pages</a></li>
|
||||
</ul>
|
||||
|
|
7
api.html
7
api.html
|
@ -26,7 +26,7 @@
|
|||
<script type="text/javascript" src="_static/bootstrap-dropdown.js"></script>
|
||||
<script type="text/javascript" src="_static/bootstrap-scrollspy.js"></script>
|
||||
<link rel="top" title="Ansible - SSH-Based Configuration Management & Deployment" href="index.html" />
|
||||
<link rel="next" title="Frequently Asked Questions" href="faq.html" />
|
||||
<link rel="next" title="Module Development Guide" href="moduledev.html" />
|
||||
<link rel="prev" title="Playbooks" href="playbooks.html" />
|
||||
<script type="text/javascript">
|
||||
(function () {
|
||||
|
@ -118,6 +118,7 @@ s.parentNode.insertBefore(ga, s);
|
|||
<li class="toctree-l1"><a class="reference internal" href="YAMLSyntax.html">YAML Syntax</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="playbooks.html">Playbooks</a></li>
|
||||
<li class="toctree-l1 current"><a class="current reference internal" href="">Using the Python API</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="moduledev.html">Module Development Guide</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="faq.html">Frequently Asked Questions</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="man.html">Man Pages</a></li>
|
||||
</ul>
|
||||
|
@ -139,8 +140,8 @@ s.parentNode.insertBefore(ga, s);
|
|||
|
||||
<li><a href="playbooks.html"
|
||||
title="previous chapter">« Playbooks</a></li>
|
||||
<li><a href="faq.html"
|
||||
title="next chapter">Frequently Asked Questions »</a></li>
|
||||
<li><a href="moduledev.html"
|
||||
title="next chapter">Module Development Guide »</a></li>
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -118,6 +118,7 @@ s.parentNode.insertBefore(ga, s);
|
|||
<li class="toctree-l1"><a class="reference internal" href="YAMLSyntax.html">YAML Syntax</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="playbooks.html">Playbooks</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="api.html">Using the Python API</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="moduledev.html">Module Development Guide</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="faq.html">Frequently Asked Questions</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="man.html">Man Pages</a></li>
|
||||
</ul>
|
||||
|
|
7
faq.html
7
faq.html
|
@ -27,7 +27,7 @@
|
|||
<script type="text/javascript" src="_static/bootstrap-scrollspy.js"></script>
|
||||
<link rel="top" title="Ansible - SSH-Based Configuration Management & Deployment" href="index.html" />
|
||||
<link rel="next" title="Man Pages" href="man.html" />
|
||||
<link rel="prev" title="Using the Python API" href="api.html" />
|
||||
<link rel="prev" title="Module Development Guide" href="moduledev.html" />
|
||||
<script type="text/javascript">
|
||||
(function () {
|
||||
/**
|
||||
|
@ -118,6 +118,7 @@ s.parentNode.insertBefore(ga, s);
|
|||
<li class="toctree-l1"><a class="reference internal" href="YAMLSyntax.html">YAML Syntax</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="playbooks.html">Playbooks</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="api.html">Using the Python API</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="moduledev.html">Module Development Guide</a></li>
|
||||
<li class="toctree-l1 current"><a class="current reference internal" href="">Frequently Asked Questions</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="man.html">Man Pages</a></li>
|
||||
</ul>
|
||||
|
@ -150,8 +151,8 @@ s.parentNode.insertBefore(ga, s);
|
|||
|
||||
|
||||
|
||||
<li><a href="api.html"
|
||||
title="previous chapter">« Using the Python API</a></li>
|
||||
<li><a href="moduledev.html"
|
||||
title="previous chapter">« Module Development Guide</a></li>
|
||||
<li><a href="man.html"
|
||||
title="next chapter">Man Pages »</a></li>
|
||||
|
||||
|
|
|
@ -116,6 +116,7 @@ s.parentNode.insertBefore(ga, s);
|
|||
<li class="toctree-l1"><a class="reference internal" href="YAMLSyntax.html">YAML Syntax</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="playbooks.html">Playbooks</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="api.html">Using the Python API</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="moduledev.html">Module Development Guide</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="faq.html">Frequently Asked Questions</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="man.html">Man Pages</a></li>
|
||||
</ul>
|
||||
|
|
|
@ -118,6 +118,7 @@ s.parentNode.insertBefore(ga, s);
|
|||
<li class="toctree-l1"><a class="reference internal" href="YAMLSyntax.html">YAML Syntax</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="playbooks.html">Playbooks</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="api.html">Using the Python API</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="moduledev.html">Module Development Guide</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="faq.html">Frequently Asked Questions</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="man.html">Man Pages</a></li>
|
||||
</ul>
|
||||
|
|
14
index.html
14
index.html
|
@ -117,6 +117,7 @@ s.parentNode.insertBefore(ga, s);
|
|||
<li class="toctree-l1"><a class="reference internal" href="YAMLSyntax.html">YAML Syntax</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="playbooks.html">Playbooks</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="api.html">Using the Python API</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="moduledev.html">Module Development Guide</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="faq.html">Frequently Asked Questions</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="man.html">Man Pages</a></li>
|
||||
</ul>
|
||||
|
@ -300,6 +301,19 @@ you with questions about Ansible.</p>
|
|||
<li class="toctree-l2"><a class="reference internal" href="api.html#detailed-api-example">Detailed API Example</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="moduledev.html">Module Development Guide</a><ul>
|
||||
<li class="toctree-l2"><a class="reference internal" href="moduledev.html#tutorial">Tutorial</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="moduledev.html#testing-modules">Testing Modules</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="moduledev.html#reading-input">Reading Input</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="moduledev.html#common-pitfalls">Common Pitfalls</a><ul>
|
||||
<li class="toctree-l3"><a class="reference internal" href="moduledev.html#conventions">Conventions</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="moduledev.html#shorthand-vs-json">Shorthand Vs JSON</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="moduledev.html#sharing-your-module">Sharing Your Module</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="moduledev.html#getting-your-module-into-core">Getting Your Module Into Core</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="faq.html">Frequently Asked Questions</a><ul>
|
||||
<li class="toctree-l2"><a class="reference internal" href="faq.html#what-inspired-ansible">What inspired Ansible?</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="faq.html#comparisons">Comparisons</a><ul>
|
||||
|
|
1
man.html
1
man.html
|
@ -117,6 +117,7 @@ s.parentNode.insertBefore(ga, s);
|
|||
<li class="toctree-l1"><a class="reference internal" href="YAMLSyntax.html">YAML Syntax</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="playbooks.html">Playbooks</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="api.html">Using the Python API</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="moduledev.html">Module Development Guide</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="faq.html">Frequently Asked Questions</a></li>
|
||||
<li class="toctree-l1 current"><a class="current reference internal" href="">Man Pages</a></li>
|
||||
</ul>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!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>ansible-playbook</title><link rel="stylesheet" href="./docbook-xsl.css" type="text/css" /><meta name="generator" content="DocBook XSL Stylesheets V1.75.2" /></head><body><div xml:lang="en" class="refentry" title="ansible-playbook" lang="en"><a id="id459632"></a><div class="titlepage"></div><div class="refnamediv"><h2>Name</h2><p>ansible-playbook — run an ansible playbook</p></div><div class="refsynopsisdiv" title="Synopsis"><a id="_synopsis"></a><h2>Synopsis</h2><p>ansible-playbook <filename.yml> … [options]</p></div><div class="refsect1" title="DESCRIPTION"><a id="_description"></a><h2>DESCRIPTION</h2><p><span class="strong"><strong>Ansible playbooks</strong></span> are a configuration and multinode deployment system. Ansible-playbook is the tool
|
||||
<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>ansible-playbook</title><link rel="stylesheet" href="./docbook-xsl.css" type="text/css" /><meta name="generator" content="DocBook XSL Stylesheets V1.75.2" /></head><body><div xml:lang="en" class="refentry" title="ansible-playbook" lang="en"><a id="id530459"></a><div class="titlepage"></div><div class="refnamediv"><h2>Name</h2><p>ansible-playbook — run an ansible playbook</p></div><div class="refsynopsisdiv" title="Synopsis"><a id="_synopsis"></a><h2>Synopsis</h2><p>ansible-playbook <filename.yml> … [options]</p></div><div class="refsect1" title="DESCRIPTION"><a id="_description"></a><h2>DESCRIPTION</h2><p><span class="strong"><strong>Ansible playbooks</strong></span> are a configuration and multinode deployment system. Ansible-playbook is the tool
|
||||
used to run them. See the project home page (link below) for more information.</p></div><div class="refsect1" title="ARGUMENTS"><a id="_arguments"></a><h2>ARGUMENTS</h2><div class="variablelist"><dl><dt><span class="term">
|
||||
<span class="strong"><strong>filename.yml</strong></span>
|
||||
</span></dt><dd>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!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>ansible</title><link rel="stylesheet" href="./docbook-xsl.css" type="text/css" /><meta name="generator" content="DocBook XSL Stylesheets V1.75.2" /></head><body><div xml:lang="en" class="refentry" title="ansible" lang="en"><a id="id303813"></a><div class="titlepage"></div><div class="refnamediv"><h2>Name</h2><p>ansible — run a command somewhere else</p></div><div class="refsynopsisdiv" title="Synopsis"><a id="_synopsis"></a><h2>Synopsis</h2><p>ansible <host-pattern> [-f forks] [-m module_name] [-a args]</p></div><div class="refsect1" title="DESCRIPTION"><a id="_description"></a><h2>DESCRIPTION</h2><p><span class="strong"><strong>Ansible</strong></span> is an extra-simple tool/framework/API for doing 'remote things' over
|
||||
<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>ansible</title><link rel="stylesheet" href="./docbook-xsl.css" type="text/css" /><meta name="generator" content="DocBook XSL Stylesheets V1.75.2" /></head><body><div xml:lang="en" class="refentry" title="ansible" lang="en"><a id="id345285"></a><div class="titlepage"></div><div class="refnamediv"><h2>Name</h2><p>ansible — run a command somewhere else</p></div><div class="refsynopsisdiv" title="Synopsis"><a id="_synopsis"></a><h2>Synopsis</h2><p>ansible <host-pattern> [-f forks] [-m module_name] [-a args]</p></div><div class="refsect1" title="DESCRIPTION"><a id="_description"></a><h2>DESCRIPTION</h2><p><span class="strong"><strong>Ansible</strong></span> is an extra-simple tool/framework/API for doing 'remote things' over
|
||||
SSH.</p></div><div class="refsect1" title="ARGUMENTS"><a id="_arguments"></a><h2>ARGUMENTS</h2><div class="variablelist"><dl><dt><span class="term">
|
||||
<span class="strong"><strong>host-pattern</strong></span>
|
||||
</span></dt><dd>
|
||||
|
|
|
@ -118,6 +118,7 @@ s.parentNode.insertBefore(ga, s);
|
|||
<li class="toctree-l1"><a class="reference internal" href="YAMLSyntax.html">YAML Syntax</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="playbooks.html">Playbooks</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="api.html">Using the Python API</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="moduledev.html">Module Development Guide</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="faq.html">Frequently Asked Questions</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="man.html">Man Pages</a></li>
|
||||
</ul>
|
||||
|
|
|
@ -118,6 +118,7 @@ s.parentNode.insertBefore(ga, s);
|
|||
<li class="toctree-l1"><a class="reference internal" href="YAMLSyntax.html">YAML Syntax</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="playbooks.html">Playbooks</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="api.html">Using the Python API</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="moduledev.html">Module Development Guide</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="faq.html">Frequently Asked Questions</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="man.html">Man Pages</a></li>
|
||||
</ul>
|
||||
|
|
|
@ -118,6 +118,7 @@ s.parentNode.insertBefore(ga, s);
|
|||
<li class="toctree-l1"><a class="reference internal" href="YAMLSyntax.html">YAML Syntax</a></li>
|
||||
<li class="toctree-l1 current"><a class="current reference internal" href="">Playbooks</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="api.html">Using the Python API</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="moduledev.html">Module Development Guide</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="faq.html">Frequently Asked Questions</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="man.html">Man Pages</a></li>
|
||||
</ul>
|
||||
|
@ -191,7 +192,9 @@ alt="Fork me on GitHub"
|
|||
<dt><a class="reference internal" href="YAMLSyntax.html"><em>YAML Syntax</em></a></dt>
|
||||
<dd>Learn about YAML syntax</dd>
|
||||
<dt><a class="reference internal" href="modules.html"><em>Ansible Modules</em></a></dt>
|
||||
<dd>Learn about available modules and writing your own</dd>
|
||||
<dd>Learn about available modules</dd>
|
||||
<dt><a class="reference internal" href="moduledev.html"><em>Module Development Guide</em></a></dt>
|
||||
<dd>Learn how to extend Ansible by writing your own modules</dd>
|
||||
<dt><a class="reference internal" href="patterns.html"><em>The Inventory File, Patterns, and Groups</em></a></dt>
|
||||
<dd>Learn about how to select hosts</dd>
|
||||
<dt><a class="reference external" href="https://github.com/ansible/ansible/tree/master/examples/playbooks">Github examples directory</a></dt>
|
||||
|
|
|
@ -91,6 +91,7 @@ Contents
|
|||
YAMLSyntax
|
||||
playbooks
|
||||
api
|
||||
moduledev
|
||||
faq
|
||||
man
|
||||
|
||||
|
|
253
rst/moduledev.rst
Normal file
253
rst/moduledev.rst
Normal file
|
@ -0,0 +1,253 @@
|
|||
Module Development Guide
|
||||
========================
|
||||
|
||||
.. seealso::
|
||||
|
||||
:doc:`modules`
|
||||
Learn about available modules
|
||||
`Github modules directory <https://github.com/ansible/ansible/tree/master/library>`_
|
||||
Browse source of core modules
|
||||
|
||||
|
||||
Ansible modules are reusable units of magic that can be used by the Ansible API,
|
||||
or by the `ansible` or `ansible-playbook` programs.
|
||||
|
||||
Modules can be written in any language and are found in the path specified
|
||||
by `ANSIBLE_LIBRARY_PATH` or the `--module-path` command line option.
|
||||
|
||||
Tutorial
|
||||
````````
|
||||
|
||||
Let's build a module to get and set the system time. For starters, let's build
|
||||
a module that just outputs the current time.
|
||||
|
||||
We are going to use Python here but any language is possible. Only File I/O and outputing to standard
|
||||
out are required. So, bash, C++, clojure, Python, Ruby, whatever you want
|
||||
is fine.
|
||||
|
||||
It's obvious that you would never really need to build a module to set the system time,
|
||||
the 'command' module could already be used to do this. However, it makes for a decent example.
|
||||
Reading the modules that come with ansible (linked above) is a great way to learn how to write
|
||||
modules. Keep in mind, though, that some modules in ansible's source tree are internalisms,
|
||||
so look at `service` or `yum`, and don't stare too close into things like `async_wrapper` or
|
||||
you'll turn to stone. Nobody ever executes async_wrapper directly.
|
||||
|
||||
Ok, let's get going with an example. We'll use Python. For starters, save this as a file named `time`::
|
||||
|
||||
#!/usr/bin/python
|
||||
|
||||
import datetime
|
||||
import json
|
||||
|
||||
date = str(datetime.datetime.now())
|
||||
print json.dumps({
|
||||
"time" : date
|
||||
})
|
||||
|
||||
Testing Modules
|
||||
```````````````
|
||||
|
||||
There's a useful test script in the source checkout for ansible::
|
||||
|
||||
git clone git@github.com:ansible/ansible.git
|
||||
chmod +x ansible/hacking/test-module
|
||||
|
||||
Let's run the script you just wrote with that::
|
||||
|
||||
ansible/hacking/test-module ./time
|
||||
|
||||
You should see output that looks something like this::
|
||||
|
||||
{u'time': u'2012-03-14 22:13:48.539183'}
|
||||
|
||||
If you did not, you might have a typo in your module, so recheck it and try again
|
||||
|
||||
Reading Input
|
||||
`````````````
|
||||
|
||||
Let's modify the module to allow setting the current time. We'll do this by seeing
|
||||
if a key value pair in the form `time=<string>` is passed in to the module.
|
||||
|
||||
Ansible internally saves arguments to a arguments file. So we must read the file
|
||||
and parse it. The arguments file is just a string, so any form of arguments are legal.
|
||||
Here we'll do some basic parsing to treat the input as key=value.
|
||||
|
||||
The example usage we are trying to achieve to set the time is::
|
||||
|
||||
time time="March 14 22:10"
|
||||
|
||||
If no time parameter is set, we'll just leave the time as is and return the current time.
|
||||
|
||||
.. note:
|
||||
This is obviously an unrealistic idea for a module. You'd most likely just
|
||||
use the shell module. However, it probably makes a decent tutorial.
|
||||
|
||||
Let's look at the code. Read the comments as we'll explain as we go. Note that this
|
||||
highly verbose because it's intended as an educational example. You can write modules
|
||||
a lot shorter than this::
|
||||
|
||||
#!/usr/bin/python
|
||||
|
||||
# import some python modules that we'll use. These are all
|
||||
# available in Python's core
|
||||
|
||||
import datetime
|
||||
import sys
|
||||
import json
|
||||
import os
|
||||
import shlex
|
||||
|
||||
# read the argument string from the arguments file
|
||||
args_file = sys.argv[1]
|
||||
args_data = file(args_file).read()
|
||||
|
||||
# for this module, we're going to do key=value style arguments
|
||||
# this is up to each module to decide what it wants, but all
|
||||
# core modules besides 'command' and 'shell' take key=value
|
||||
# so this is highly recommended
|
||||
|
||||
arguments = shlex.split(args_data)
|
||||
for arg in arguments:
|
||||
|
||||
# ignore any arguments without an equals in it
|
||||
if arg.find("=") != -1:
|
||||
|
||||
(key, value) = arg.split("=")
|
||||
|
||||
# if setting the time, the key 'time'
|
||||
# will contain the value we want to set the time to
|
||||
|
||||
if key == "time":
|
||||
|
||||
# now we'll affect the change. Many modules
|
||||
# will strive to be 'idempotent', meaning they
|
||||
# will only make changes when the desired state
|
||||
# expressed to the module does not match
|
||||
# the current state. Look at 'service'
|
||||
# or 'yum' in the main git tree for an example
|
||||
# of how that might look.
|
||||
|
||||
rc = os.system("date -s \"%s\"" % value)
|
||||
|
||||
# always handle all possible errors
|
||||
#
|
||||
# when returning a failure, include 'failed'
|
||||
# in the return data, and explain the failure
|
||||
# in 'msg'. Both of these conventions are
|
||||
# required however additional keys and values
|
||||
# can be added.
|
||||
|
||||
if rc != 0:
|
||||
print json.dumps({
|
||||
"failed" : True,
|
||||
"msg" : "failed setting the time"
|
||||
})
|
||||
sys.exit(1)
|
||||
|
||||
# when things do not fail, we do not
|
||||
# have any restrictions on what kinds of
|
||||
# data are returned, but it's always a
|
||||
# good idea to include whether or not
|
||||
# a change was made, as that will allow
|
||||
# notifiers to be used in playbooks.
|
||||
|
||||
date = str(datetime.datetime.now())
|
||||
print json.dumps({
|
||||
"time" : date,
|
||||
"changed" : True
|
||||
})
|
||||
sys.exit(0)
|
||||
|
||||
# if no parameters are sent, the module may or
|
||||
# may not error out, this one will just
|
||||
# return the time
|
||||
|
||||
date = str(datetime.datetime.now())
|
||||
print json.dumps({
|
||||
"time" : date
|
||||
})
|
||||
|
||||
Let's test that module::
|
||||
|
||||
../ansible/hacking/test-module ./rst/time time=\"March 14 12:23\"
|
||||
|
||||
This should return something like::
|
||||
|
||||
{"changed": true, "time": "2012-03-14 12:23:00.000307"}
|
||||
|
||||
|
||||
Common Pitfalls
|
||||
```````````````
|
||||
|
||||
If writing a module in Python and you have managed nodes running
|
||||
Python 2.4 or lower, this is generally a good idea, because
|
||||
json isn't in the Python standard library until 2.5.::
|
||||
|
||||
try:
|
||||
import json
|
||||
except ImportError:
|
||||
import simplejson as json
|
||||
|
||||
You should also never do this in a module::
|
||||
|
||||
print "some status message"
|
||||
|
||||
Because the output is supposed to be valid JSON. Except that's not quite true,
|
||||
but we'll get to that later.
|
||||
|
||||
Conventions
|
||||
-----------
|
||||
|
||||
As a reminder from the example code above, here are some basic conventions
|
||||
and guidelines:
|
||||
|
||||
* Include a minimum of dependencies if possible. If there are dependencies, document them at the top of the module file
|
||||
|
||||
* Modules must be self contained in one file to be auto-transferred by ansible
|
||||
|
||||
* If packaging modules in an RPM, they only need to be installed on the control machine and should be dropped into /usr/share/ansible. This is entirely optional.
|
||||
|
||||
* Modules should return JSON or key=value results all on one line. JSON is best if you can do JSON. All return types must be hashes (dictionaries) although they can be nested.
|
||||
|
||||
* In the event of failure, a key of 'failed' should be included, along with a string explanation in 'msg'. Modules that raise tracebacks (stacktraces) are generally considered 'poor' modules, though Ansible can deal with these returns and will automatically convert anything unparseable into a failed result.
|
||||
|
||||
* Return codes are actually not signficant, but continue on with 0=success and non-zero=failure for reasons of future proofing.
|
||||
|
||||
* As results from many hosts will be aggregrated at once, modules should return only relevant output. Returning the entire contents of a log file is generally bad form.
|
||||
|
||||
|
||||
Shorthand Vs JSON
|
||||
-----------------
|
||||
|
||||
To make it easier to write modules in bash and in cases where a JSON
|
||||
module might not be available, it is acceptable for a module to return
|
||||
key=value output all on one line, like this. The Ansible parser
|
||||
will know what to do.::
|
||||
|
||||
somekey=1 somevalue=two favcolor=red
|
||||
|
||||
If you're writing a module in Python or Ruby or whatever, though, returning
|
||||
JSON is probably the simplest way to go.
|
||||
|
||||
|
||||
Sharing Your Module
|
||||
```````````````````
|
||||
|
||||
If you think your module is generally useful to others, Ansible is preparing
|
||||
an 'ansible-contrib' repo. Stop by the mailing list and we'll help you to
|
||||
get your module included. Contrib modules can be implemented in a variety
|
||||
of languages. Including a README with your module is a good idea so folks
|
||||
can understand what arguments it takes and so on. We would like to build
|
||||
up as many of these as possible in as many languages as possible.
|
||||
|
||||
`Ansible Mailing List <http://groups.google.com/group/ansible-project>`_
|
||||
|
||||
Getting Your Module Into Core
|
||||
`````````````````````````````
|
||||
|
||||
High-quality modules with minimal dependencies
|
||||
can be included in the core, but core modules (just due to the programming
|
||||
preferences of the developers) will need to be implemented in Python.
|
||||
Stop by the mailing list to inquire about requirements.
|
||||
|
||||
|
|
@ -6,7 +6,9 @@ Playbooks
|
|||
:doc:`YAMLSyntax`
|
||||
Learn about YAML syntax
|
||||
:doc:`modules`
|
||||
Learn about available modules and writing your own
|
||||
Learn about available modules
|
||||
:doc:`moduledev`
|
||||
Learn how to extend Ansible by writing your own modules
|
||||
:doc:`patterns`
|
||||
Learn about how to select hosts
|
||||
`Github examples directory <https://github.com/ansible/ansible/tree/master/examples/playbooks>`_
|
||||
|
|
|
@ -122,6 +122,7 @@ s.parentNode.insertBefore(ga, s);
|
|||
<li class="toctree-l1"><a class="reference internal" href="YAMLSyntax.html">YAML Syntax</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="playbooks.html">Playbooks</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="api.html">Using the Python API</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="moduledev.html">Module Development Guide</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="faq.html">Frequently Asked Questions</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="man.html">Man Pages</a></li>
|
||||
</ul>
|
||||
|
|
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue