running ptython script in role

i want to run a python script in a role. currently the script is in the tasks directory but i also tried the file dir which also is not working. where i have to put this script so it can be found at runtime?

`

  • local_action: command “{{ item }}”
    with_items:
  • “inventoryctl.py group -U -n LNZ”
  • “inventoryctl.py host -U -H {{ inventory_hostname }} -g LNZ”
    when: (itsv_machine_serial.stdout is match “IBM,02781A6BX”) or
    (itsv_machine_serial.stdout is match “IBM,02781A6CX”) or
    (itsv_machine_serial.stdout is match “IBM,02781A6DX”)

`

result:

`
TASK [hostgroups : command] ***********************************************************************************************************************************************************************************
failed: [AMTEST1 → localhost] (item=inventoryctl.py group -U -n LNZ) => {“changed”: false, “cmd”: “‘inventoryctl.py group -U -n LNZ’”, “item”: “inventoryctl.py group -U -n LNZ”, “msg”: “[Errno 2] No such file or directory”, “rc”: 2}
failed: [AMTEST1 → localhost] (item=inventoryctl.py host -U -H AMTEST1 -g LNZ) => {“changed”: false, “cmd”: “‘inventoryctl.py host -U -H AMTEST1 -g LNZ’”, “item”: “inventoryctl.py host -U -H AMTEST1 -g LNZ”, “msg”: “[Errno 2] No such file or directory”, “rc”: 2}

`

playbook

`

  • name: run test play
    hosts: all
    gather_facts: yes
    roles:

  • hostgroups
    tasks:

  • name: print out the hostname of target
    command: hostname

  • name: Print itsv_lparname
    debug:
    var: hostvars[inventory_hostname].inventory_lparname

  • name: Print inventory_hostname
    debug:
    var: hostvars[inventory_hostname].inventory_hostname

- name: Display all variables/facts known for a host

debug:

#var: hostvars[inventory_hostname]

`

i want to run a python script in a role. currently the script is in the
tasks directory but i also tried the file dir which also is not working.
where i have to put this script so it can be found at runtime?

It's using path to find the executable, is it not in the path you need to use relative path or absolute path.

- local_action: command "{{ item }}"
  with_items:
          - "inventoryctl.py group -U -n LNZ"
          - "inventoryctl.py host -U -H {{ inventory_hostname }} -g LNZ"
  when: (itsv_machine_serial.stdout is match "IBM,02781A6BX") or
        (itsv_machine_serial.stdout is match "IBM,02781A6CX") or
        (itsv_machine_serial.stdout is match "IBM,02781A6DX")

If you have roles/hostgroups/files/inventoryctl.py the command would be

   roles/hostgroups/files/inventoryctl.py

hmm…does not work.

`
TASK [hostgroups : command] ***********************************************************************************************************************************************************************************
failed: [AMTEST1 → localhost] (item=roles/hostgroups/files/inventoryctl.py group -U -n LNZ) => {“changed”: false, “cmd”: “‘roles/hostgroups/files/inventoryctl.py group -U -n LNZ’”, “item”: “roles/hostgroups/files/inventoryctl.py group -U -n LNZ”, “msg”: “[Errno 2] No such file or directory”, “rc”: 2}
failed: [AMTEST1 → localhost] (item=roles/hostgroups/files/inventoryctl.py host -U -H AMTEST1 -g LNZ) => {“changed”: false, “cmd”: “‘roles/hostgroups/files/inventoryctl.py host -U -H AMTEST1 -g LNZ’”, “item”: “roles/hostgroups/files/inventoryctl.py host -U -H AMTEST1 -g LNZ”, “msg”: “[Errno 2] No such file or directory”, “rc”: 2}

PLAY RECAP ****************************************************************************************************************************************************************************************************
AMTEST1 : ok=3 changed=2 unreachable=0 failed=1

root@lpgaixmgmtlx01:/etc/ansible/aix>file roles/hostgroups/files/inventoryctl.py
roles/hostgroups/files/inventoryctl.py: Python script, ASCII text executable

`

I have not done this myself, but I think that the script you are running has to be in the search path (“$PATH”) OR you have to specify an absolute path (“/[…]/myscript.py”) OR you have to specify a path relative to the current working directory - that is, the directory that is the CWD when ansible tries to execute the script.

I think that the CWD is not what you think it is.You could find it out by executing the command “pwd”.

Regards, K.

i put the script in path, same errror…

`
TASK [hostgroups : command] ***********************************************************************************************************************************************************************************
failed: [AMTEST1 → localhost] (item=inventoryctl.py group -U -n LNZ) => {“changed”: false, “cmd”: “‘inventoryctl.py group -U -n LNZ’”, “item”: “inventoryctl.py group -U -n LNZ”, “msg”: “[Errno 2] No such file or directory”, “rc”: 2}
failed: [AMTEST1 → localhost] (item=inventoryctl.py host -U -H AMTEST1 -g LNZ) => {“changed”: false, “cmd”: “‘inventoryctl.py host -U -H AMTEST1 -g LNZ’”, “item”: “inventoryctl.py host -U -H AMTEST1 -g LNZ”, “msg”: “[Errno 2] No such file or directory”, “rc”: 2}

PLAY RECAP ****************************************************************************************************************************************************************************************************
AMTEST1 : ok=2 changed=2 unreachable=0 failed=1

root@lpgaixmgmtlx01:/etc/ansible/aix>which inventoryctl.py
/usr/bin/inventoryctl.py

`

could it be that ansible tries to run the script on the remote node instead of local? this means it runs local right? ([AMTEST1 -> localhost])

Not in YOUR path, in the path Ansible is using when it executes the script. Use the command module and find out what the path is, what the CWD is.

As to whether it is executing on the remote - what have you got in the “hosts” line?

Regards, K.

no idea, there is only one $PATH (even if its not mine, whatever my path is) so i assume that ansible uses exactly that path. ansible runs as the root user here, so roots path should relevant.

When stuff doesn’t work, you have to stop making assumptions.

Use the “command” module to run
a shell command to tell you the hostname, path and CWD on whatever host Ansible is running these tasks on.

Then you will know what’s what and can adjust your playbook.

Regards, K.

`

No output from pwd, but it didn’t fail. Maybe you need to add “-v” to your Ansible command line?

While you are at it, add commands to run “hostname” and “echo $PATH”

Regards, K.

even using {{ role_path}} does not work, this slowly is getting out of hand…

`

  • local_action: command “{{ item }}”
    with_items:
  • “pwd”
  • “{{ role_path }}/files/inventoryctl.py group -U -n LNZ”
  • “{{ role_path }}/files/inventoryctl.py host -U -H {{ inventory_hostname }} -g LNZ”
    when: (itsv_machine_serial.stdout is match “IBM,02781A6BX”) or
    (itsv_machine_serial.stdout is match “IBM,02781A6CX”) or
    (itsv_machine_serial.stdout is match “IBM,02781A6DX”)

`

`
TASK [hostgroups : command] ***********************************************************************************************************************************************************************************
changed: [AMTEST1 → localhost] => (item=pwd)
failed: [AMTEST1 → localhost] (item=/etc/ansible/aix/roles/hostgroups/files/inventoryctl.py group -U -n LNZ) => {“changed”: false, “cmd”: “‘/etc/ansible/aix/roles/hostgroups/files/inventoryctl.py group -U -n LNZ’”, “item”: “/etc/ansible/aix/roles/hostgroups/files/inventoryctl.py group -U -n LNZ”, “msg”: “[Errno 2] No such file or directory”, “rc”: 2}
failed: [AMTEST1 → localhost] (item=/etc/ansible/aix/roles/hostgroups/files/inventoryctl.py host -U -H AMTEST1 -g LNZ) => {“changed”: false, “cmd”: “‘/etc/ansible/aix/roles/hostgroups/files/inventoryctl.py host -U -H AMTEST1 -g LNZ’”, “item”: “/etc/ansible/aix/roles/hostgroups/files/inventoryctl.py host -U -H AMTEST1 -g LNZ”, “msg”: “[Errno 2] No such file or directory”, “rc”: 2}

`

Hm.

I haven’t used command much myself, but I think you have to give it space-delimited commands.

Could it be that you are actually telling Ansible to execute a command called “inventoryctl.py host -U -H AMTEST1 -g LNZ”, rather than a command called “inventoryctl.py” with arguments “host”, "-U’, “-H”, “AMTEST1”, “-g”, and “LNZ” ?!?

``
Not sure how to fix that.

Regards, K.

even using {{ role_path}} does not work, this slowly is getting out of
hand...

- local_action: command "{{ item }}"

I think the quotes inn here is your problem, try removing them.

  with_items:
          - "pwd"
          - "{{ role_path }}/files/inventoryctl.py group -U -n LNZ"
          - "{{ role_path }}/files/inventoryctl.py host -U -H {{
inventory_hostname }} -g LNZ"
  when: (itsv_machine_serial.stdout is match "IBM,02781A6BX") or
        (itsv_machine_serial.stdout is match "IBM,02781A6CX") or
        (itsv_machine_serial.stdout is match "IBM,02781A6DX")

TASK [hostgroups : command]
***********************************************************************************************************************************************************************************
changed: [AMTEST1 -> localhost] => (item=pwd)
failed: [AMTEST1 -> localhost] (item=/etc/ansible/aix/roles/hostgroups/files
/inventoryctl.py group -U -n LNZ) => {"changed": false, "cmd":
"'/etc/ansible/aix/roles/hostgroups/files/inventoryctl.py group -U -n LNZ'", "item":

Because of the quotes above you item is
'/etc/ansible/aix/roles/hostgroups/files/inventoryctl.py group -U -n LNZ'

But it need to be without the single quotes, and they are there because of the double quotes in the local_action.

You could avoid problems like this by dropping local_action and use delegate_to instead.

   - command: "{{ item }}"
     delegate_to: localhost
     with_items:
       - "pwd"
       - "{{ role_path }}/files/inventoryctl.py group -U -n LNZ"
       - "{{ role_path }}/files/inventoryctl.py host -U -H {{ inventory_hostname }} -g LNZ"
     when: (itsv_machine_serial.stdout is match "IBM,02781A6BX") or
           (itsv_machine_serial.stdout is match "IBM,02781A6CX") or
           (itsv_machine_serial.stdout is match "IBM,02781A6DX")

modified accordingly, using delegate_to, outcome is even worse. the command completly garbled. i can not imagine why it is this hard to run a simple command with arguments. just "/etc/ansible/aix/roles/hostgroups/files/inventoryctl.py group -U -n LNZ" without any fuss or specials.

`
TASK [hostgroups : command] ***********************************************************************************************************************************************************************************
changed: [AMTEST1 → localhost] => (item=pwd)
failed: [AMTEST1 → localhost] (item=/etc/ansible/aix/roles/hostgroups/files/inventoryctl.py group -U -n LNZ) => {“changed”: true, “cmd”: [“/etc/ansible/aix/roles/hostgroups/files/inventoryctl.py”, “group”, “-U”, “-n”, “LNZ”], “delta”: “0:00:00.109754”, “end”: “2018-08-06 16:36:54.041377”, “item”: “/etc/ansible/aix/roles/hostgroups/files/inventoryctl.py group -U -n LNZ”, “msg”: “non-zero return code”, “rc”: 1, “start”: “2018-08-06 16:36:53.931623”, “stderr”: “Traceback (most recent call last):\n File "/etc/ansible/aix/roles/hostgroups/files/inventoryctl.py", line 549, in \n InventoryCtl()\n File "/etc/ansible/aix/roles/hostgroups/files/inventoryctl.py", line 31, in init\n self.read_settings()\n File "/etc/ansible/aix/roles/hostgroups/files/inventoryctl.py", line 42, in read_settings\n self.myconfig = dict(config.items(‘server’))\n File "/usr/lib/python2.7/site-packages/backports/configparser/init.py", line 869, in items\n raise NoSectionError(section)\nbackports.configparser.NoSectionError: No section: ‘server’”, “stderr_lines”: [“Traceback (most recent call last):”, " File "/etc/ansible/aix/roles/hostgroups/files/inventoryctl.py", line 549, in “, " InventoryCtl()”, " File "/etc/ansible/aix/roles/hostgroups/files/inventoryctl.py", line 31, in init", " self.read_settings()“, " File "/etc/ansible/aix/roles/hostgroups/files/inventoryctl.py", line 42, in read_settings”, " self.myconfig = dict(config.items(‘server’))“, " File "/usr/lib/python2.7/site-packages/backports/configparser/init.py", line 869, in items”, " raise NoSectionError(section)“, “backports.configparser.NoSectionError: No section: ‘server’”], “stdout”: “”, “stdout_lines”: }
failed: [AMTEST1 → localhost] (item=/etc/ansible/aix/roles/hostgroups/files/inventoryctl.py host -U -H AMTEST1 -g LNZ) => {“changed”: true, “cmd”: [”/etc/ansible/aix/roles/hostgroups/files/inventoryctl.py", “host”, “-U”, “-H”, “AMTEST1”, “-g”, “LNZ”], “delta”: “0:00:00.109299”, “end”: “2018-08-06 16:36:54.289337”, “item”: “/etc/ansible/aix/roles/hostgroups/files/inventoryctl.py host -U -H AMTEST1 -g LNZ”, “msg”: “non-zero return code”, “rc”: 1, “start”: “2018-08-06 16:36:54.180038”, “stderr”: “Traceback (most recent call last):\n File "/etc/ansible/aix/roles/hostgroups/files/inventoryctl.py", line 549, in \n InventoryCtl()\n File "/etc/ansible/aix/roles/hostgroups/files/inventoryctl.py", line 31, in init\n self.read_settings()\n File "/etc/ansible/aix/roles/hostgroups/files/inventoryctl.py", line 42, in read_settings\n self.myconfig = dict(config.items(‘server’))\n File "/usr/lib/python2.7/site-packages/backports/configparser/init.py", line 869, in items\n raise NoSectionError(section)\nbackports.configparser.NoSectionError: No section: ‘server’”, “stderr_lines”: [“Traceback (most recent call last):”, " File "/etc/ansible/aix/roles/hostgroups/files/inventoryctl.py", line 549, in “, " InventoryCtl()”, " File "/etc/ansible/aix/roles/hostgroups/files/inventoryctl.py", line 31, in init", " self.read_settings()“, " File "/etc/ansible/aix/roles/hostgroups/files/inventoryctl.py", line 42, in read_settings”, " self.myconfig = dict(config.items(‘server’))“, " File "/usr/lib/python2.7/site-packages/backports/configparser/init.py", line 869, in items”, " raise NoSectionError(section)", “backports.configparser.NoSectionError: No section: ‘server’”], “stdout”: “”, “stdout_lines”: }

`

Well, amazingly enough this is progress!

Your script is now running. The garbage you see is a python stack trace, because the program had a problem - but it did run.

I don’t know what that script does, but from the error message it was parsing some file or other and was unable to find a section called “server”.

Regards, K.

yes, this is because ansible is sending garbage down the stream. “/etc/ansible/aix/roles/hostgroups/files/inventoryctl.py” “group”, “-U”, “-n”, “LNZ” while the script expects this “/etc/ansible/aix/roles/hostgroups/files/inventoryctl.py group -U -n LNZ”

As Karl said, this is progress since Ansible running you command.

You would do yourself(and us) a big favor by setting

   stdout_callback = debug

in ansible.cfg under the [default] section, this will give you a much nicer output.

What happens when you run that script, with those parameters, yourself, manually? On the same host as Ansible is running it on.

This is not garbage, it's just how it's.

$ cat playbook.yml