Using module.is_executable(path) results in an exception

I am trying to develop a new module for Ansible. I need to validate a provided parameter points to a valid executable on the system. I am having problems using the is_executable helper function from Ansible module_utils.

My code looks like follows:

<playbook_path>/library/test_module.py

#!/usr/bin/python

from ansible.module_utils.basic import *

def validate_input(module):
params = module.params

if not module.is_executable(params[‘api_bin’]):
module.fail_json(msg=“Please specify a valid api_bin.”)

def main():
fields = dict(
api_bin = dict(default=‘/bin/echo’)
)

module = AnsibleModule(
argument_spec = fields
)

validate_input(module)

module.exit_json(dict(foo=‘bar’))

if name == ‘main’:
main()

<playbook_path>/playbook.yml

  • name: test api module
    hosts: localhost
    tasks:
  • test_module:

Very Verbose Output:

[root@wks test]# ansible-playbook playbook.yml -vvv
Using /etc/ansible/ansible.cfg as config file
[WARNING]: provided hosts list is empty, only localhost is available

PLAYBOOK: playbook.yml *********************************************************
1 plays in playbook.yml

PLAY [test api module] *********************************************************

TASK [setup] *******************************************************************
Using module file /usr/lib/python2.6/site-packages/ansible/modules/core/system/setup.py
<127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: root
<127.0.0.1> EXEC /bin/sh -c ‘( umask 77 && mkdir -p “echo $HOME/.ansible/tmp/ansible-tmp-1484582250.29-253240644016022” && echo ansible-tmp-1484582250.29-253240644016022=“echo $HOME/.ansible/tmp/ansible-tmp-1484582250.29-253240644016022” ) && sleep 0’
<127.0.0.1> PUT /tmp/tmps9OBmS TO /root/.ansible/tmp/ansible-tmp-1484582250.29-253240644016022/setup.py
<127.0.0.1> EXEC /bin/sh -c ‘chmod u+x /root/.ansible/tmp/ansible-tmp-1484582250.29-253240644016022/ /root/.ansible/tmp/ansible-tmp-1484582250.29-253240644016022/setup.py && sleep 0’
<127.0.0.1> EXEC /bin/sh -c ‘/usr/bin/python2.6 /root/.ansible/tmp/ansible-tmp-1484582250.29-253240644016022/setup.py; rm -rf “/root/.ansible/tmp/ansible-tmp-1484582250.29-253240644016022/” > /dev/null 2>&1 && sleep 0’
ok: [localhost]

TASK [test_module] *************************************************************
task path: /root/test/playbook.yml:4
Using module file /root/test/library/test_module.py
<127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: root
<127.0.0.1> EXEC /bin/sh -c ‘( umask 77 && mkdir -p “echo $HOME/.ansible/tmp/ansible-tmp-1484582250.69-169598441928985” && echo ansible-tmp-1484582250.69-169598441928985=“echo $HOME/.ansible/tmp/ansible-tmp-1484582250.69-169598441928985” ) && sleep 0’
<127.0.0.1> PUT /tmp/tmps9OBmS TO /root/.ansible/tmp/ansible-tmp-1484582250.69-169598441928985/test_module.py
<127.0.0.1> EXEC /bin/sh -c ‘chmod u+x /root/.ansible/tmp/ansible-tmp-1484582250.69-169598441928985/ /root/.ansible/tmp/ansible-tmp-1484582250.69-169598441928985/test_module.py && sleep 0’
<127.0.0.1> EXEC /bin/sh -c ‘/usr/bin/python2.6 /root/.ansible/tmp/ansible-tmp-1484582250.69-169598441928985/test_module.py; rm -rf “/root/.ansible/tmp/ansible-tmp-1484582250.69-169598441928985/” > /dev/null 2>&1 && sleep 0’
An exception occurred during task execution. The full traceback is:
Traceback (most recent call last):
File “/tmp/ansible_lQYk0L/ansible_module_test_module.py”, line 24, in
main()
File “/tmp/ansible_lQYk0L/ansible_module_test_module.py”, line 19, in main
validate_input(module)
File “/tmp/ansible_lQYk0L/ansible_module_test_module.py”, line 7, in validate_input
if not module.is_executable(params[‘api_bin’]):
TypeError: is_executable() takes exactly 1 argument (2 given)

fatal: [localhost]: FAILED! => {
“changed”: false,
“failed”: true,
“invocation”: {
“module_name”: “test_module”
},
“module_stderr”: “Traceback (most recent call last):\n File "/tmp/ansible_lQYk0L/ansible_module_test_module.py", line 24, in \n main()\n File "/tmp/ansible_lQYk0L/ansible_module_test_module.py", line 19, in main\n validate_input(module)\n File "/tmp/ansible_lQYk0L/ansible_module_test_module.py", line 7, in validate_input\n if not module.is_executable(params[‘api_bin’]):\nTypeError: is_executable() takes exactly 1 argument (2 given)\n”,
“module_stdout”: “”,
“msg”: “MODULE FAILURE”
}
to retry, use: --limit @/root/test/playbook.retry

PLAY RECAP *********************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=1

This is due to is_executable not being an instance method. Instead of using module.is_executable, just try is_executable, removing module. from the front.

is_executable is now a top level function in ansible.module_utils.basic, so you have already imported it.