Hi,
As I began to introduce my projet in another post, I’m currently experimenting a blocking issue.
The thing that I want to do is pretty simple and I think that I am verry close to the solution but I clearly need your help
Here is the flow I want to create :
A playbook executes a module (that I quickly wrote) which runs the sell command apt-show-versions, parse the result and then return it into JSON format.
At the end, a callback is responsible for processing the result and then puting it into a database.
Info: this (great !) web page helped me to do it : http://jpmens.net/2012/09/11/watching-ansible-at-work-callbacks/
It almost works but I’m still have an issue (see under).
So here are the files:
ANSIBLE PLAYBOOK:
- hosts: webservers
user: root
vars:
name: dpkg Tom
tasks:- name: Verify that apt-show-versions is installed and install it if it is not present
action: apt pkg=apt-show-versions state=present- name: Launch a custom dpkg-show-versions module
action: dpkg_tom
ANSIBLE MODULE (in bash language because I don’t know how to do it in Python):
DEFINITION DE LA FONCTION PRINCIPALE
main()
{parseArguments $1
echo -n “{"changed": "False", "name": "dpkg_tom", "packages": [”
nombre_lignes=$(apt-show-versions --upgradeable | wc -l)
compteur=1apt-show-versions --upgradeable | while read line
do
echo “$line” | sed ‘s@^(.?)/(.?) (.?) from (.?) to (.*)@{"\1":{"distribution": "\2","status": "\3","installed_version": "\4","available_version": "\5"@’;echo -ne “}}”
if [ $compteur -lt $nombre_lignes ]
then
echo -ne “,”
ficompteur=$[$compteur + 1]
doneecho -ne “"":{”;
echo -n “]}”
}######################################################
main
Info : this module works just fine (tested without the callback).
ANSIBLE CALLBACK:
import os
import time
import sqlite3dbname = ‘/etc/ansible/cmdb.db’
TIME_FORMAT=‘%Y-%m-%d %H:%M:%S’try:
con = sqlite3.connect(dbname)
cur = con.cursor()
except:
passdef log(host, data):
if type(data) == dict:
invocation = data.pop(‘invocation’, None)
if invocation.get(‘module_name’, None) != ‘setup’:
returnfacts = data.get(‘ansible_facts’, None)
now = time.strftime(TIME_FORMAT, time.localtime())
try:
host
is a unique indexcur.execute(“REPLACE INTO inventory (now, host, arch, dist, distvers, sys,kernel) VALUES(?,?,?,?,?,?,?);”,
(
now,
facts.get(‘ansible_hostname’, None),
facts.get(‘ansible_architecture’, None),
facts.get(‘ansible_distribution’, None),
facts.get(‘ansible_distribution_version’, None),
facts.get(‘ansible_system’, None),
facts.get(‘ansible_kernel’, None),
))
con.commit()
except:
passclass CallbackModule(object):
def runner_on_ok(self, host, res):
log(host, res)
The problem that I have is the following Python error (error raised during callback execution):
fatal: [127.0.0.1] => Traceback (most recent call last):
File “/usr/lib/pymodules/python2.6/ansible/runner/init.py”, line 236, in _executor
exec_rc = self._executor_internal(host)
File “/usr/lib/pymodules/python2.6/ansible/runner/init.py”, line 292, in _executor_internal
return self._executor_internal_inner(host, self.module_name, self.module_args, inject, port)
File “/usr/lib/pymodules/python2.6/ansible/runner/init.py”, line 435, in _executor_internal_inner
self.callbacks.on_ok(host, data)
File “/usr/lib/pymodules/python2.6/ansible/callbacks.py”, line 363, in on_ok
super(PlaybookRunnerCallbacks, self).on_ok(host, host_result)
File “/usr/lib/pymodules/python2.6/ansible/callbacks.py”, line 191, in on_ok
call_callback_module(‘runner_on_ok’, host, res)
File “/usr/lib/pymodules/python2.6/ansible/callbacks.py”, line 50, in call_callback_module
method(*args, **kwargs)
File “/usr/lib/pymodules/python2.6/ansible/callback_plugins/inventory.py”, line 43, in runner_on_ok
log(host, res)
File “/usr/lib/pymodules/python2.6/ansible/callback_plugins/inventory.py”, line 18, in log
if invocation.get(‘module_name’, None) != ‘setup’:
AttributeError: ‘NoneType’ object has no attribute ‘get’FATAL: all hosts have already failed – aborting
Then, I think that this issue is raised because of the lack of module_name in the result that my module give.
Have I to declare my custom module somewhere to make ansible know the module_name of my module?
Have I to put a module_name attribute in my JSON result?
I know that I have a verry poor level in Python and that I’m a beginner in playing with Ansible features so, here I am
Thank you for you awsome project anyway!
Tom