Below I'm trying to get a command running involving input from previous output, in this case copy flash:file01 flash:file02 with 2 derived from the REGEX_FILTERING task.
- name: REGEX_FILTERING
command: "cat /home/ubuntu/show_switch.txt"
register: line1
- debug: var="{{ line1.stdout_lines | regex_replace('(?<!\*).?') }}"
register: number
- name: COMMAND_INPUT
cli_command:
command: 'copy flash:file01 flash:file0 {{ number }}'
prompt: '[confirm]'
answer: ''
Here's the error message:
<ommited>
"stdout_lines": [
"Switch/Stack Mac Address : d4a0.2ae9.ec00",
" H/W Current",
"----------------------------------------------------------",
" 1 Member 001f.9df6.2d80 5 0 Ready ",
"*2 Master d4a0.2ae9.ec00 15 0 Ready ",
" 3 Member 0016.c733.cd00 5 0 Ready"
]
}
TASK [debug] *****************************************************************************************************************************************************************************
task path: /home/ubuntu/test1.yml:109
ok: [CSR1] => {
"2": "2"
}
TASK [COMMAND_INPUT] *********************************************************************************************************************************************************************
task path: /home/ubuntu/test1.yml:112
<192.168.255.133> ESTABLISH LOCAL CONNECTION FOR USER: ubuntu
<192.168.255.133> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /home/ubuntu/.ansible/tmp/ansible-local-7528uUJSLh/ansible-tmp-1542986468.48-164922344690120 `" && echo ansible-tmp-1542986468.48-164922344690120="` echo /home/ubuntu/.ansible/tmp/ansible-local-7528uUJSLh/ansible-tmp-1542986468.48-164922344690120 `" ) && sleep 0'
Using module file /usr/lib/python2.7/dist-packages/ansible/modules/network/cli/cli_command.py
<192.168.255.133> PUT /home/ubuntu/.ansible/tmp/ansible-local-7528uUJSLh/tmpkozHVx TO /home/ubuntu/.ansible/tmp/ansible-local-7528uUJSLh/ansible-tmp-1542986468.48-164922344690120/AnsiballZ_cli_command.py
<192.168.255.133> EXEC /bin/sh -c 'chmod u+x /home/ubuntu/.ansible/tmp/ansible-local-7528uUJSLh/ansible-tmp-1542986468.48-164922344690120/ /home/ubuntu/.ansible/tmp/ansible-local-7528uUJSLh/ansible-tmp-1542986468.48-164922344690120/AnsiballZ_cli_command.py && sleep 0'
<192.168.255.133> EXEC /bin/sh -c '/usr/bin/python /home/ubuntu/.ansible/tmp/ansible-local-7528uUJSLh/ansible-tmp-1542986468.48-164922344690120/AnsiballZ_cli_command.py && sleep 0'
<192.168.255.133> EXEC /bin/sh -c 'rm -f -r /home/ubuntu/.ansible/tmp/ansible-local-7528uUJSLh/ansible-tmp-1542986468.48-164922344690120/ > /dev/null 2>&1 && sleep 0'
The full traceback is:
WARNING: The below traceback may *not* be related to the actual failure.
File "/tmp/ansible_cli_command_payload_U1p385/__main__.py", line 150, in main
response = connection.get(**module.params)
File "/tmp/ansible_cli_command_payload_U1p385/ansible_cli_command_payload.zip/ansible/module_utils/connection.py", line 173, in __rpc__
raise ConnectionError(to_text(msg, errors='surrogate_then_replace'), code=code)
fatal: [CSR1]: FAILED! => {
"changed": false,
"invocation": {
"module_args": {
"answer": [
""
],
"check_all": false,
"command": "copy flash:file01 flash:file0 {'failed': False, u'2': u'2', 'changed': False}",
"prompt": [
"[confirm]"
],
"sendonly": false
}
},
"msg": "copy flash:file01 flash:file0 {'failed': False, u'2': u'2', 'changed': False}\r\n ^\r\n% Invalid input detected at '^' marker.\r\n\r\nCSR1#\r\nCSR1#"
"command": "copy flash:file01 flash:file0 {'failed': False, u'2': u'2', 'changed': False}",
Is happening because the register: number is not in fact the number, rather it's the ansible result of the debug: output. Since number is a python dict, when it is injected into your command, it is just serialized as if str() were called upon the dict
It is far more likely that what you want is to capture that variable locally in the task, to make it just be the result of the jinja2 expression, and not the result of an ansible task:
- cli_command:
command: 'copy flash:file01 flash:file0 {{ number }}'
vars:
number: "{{ line1.stdout_lines | regex_replace('(?<!\*).?') }}"
I also suspect you will be happier with line1.stdout, which is a str of the entire output, versus line1.stdout_lines which is a list of str, making the regex_replace on a list kind of weird -- I'm surprised it actually even let you do that, to be honest
Related
I have this recipe:
- name: Kill usr/bin/perl -w /usr/share/debconf/frontend
shell: "{{ item }}"
with_items:
- 'pkill -9 -f debconf/frontend || echo'
changed_when: false # Don't report changed state
When I run this on the command line, it returns a 0 exit code thanks to || echo:
~$ pkill -9 -f debconf/frontend || echo
~$ $?
0
However running in Ansible it shows this:
failed: [testhost1] (item=pkill -9 -f debconf/frontend || echo) => {"ansible_loop_var": "item", "changed": false, "cmd": "pkill -9 -f debconf/frontend || echo", "delta": "0:00:00.132296", "end": "2023-01-13 10:34:11.098765", "item": "sudo pkill -9 -f debconf/frontend || echo", "msg": "non-zero return code", "rc": -9, "start": "2023-01-13 10:34:10.966469", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
Any ideas what I'm doing wrong?
Starting a test process via
perl -MPOSIX -e '$0="test"; pause' &
a minimal example playbook
---
- hosts: localhost
become: false
gather_facts: false
tasks:
- name: Shell task
shell:
cmd: "{{ item }}"
with_items:
- 'pkill -9 -f test || echo'
register: result
- name: Show result
debug:
msg: "{{ result }}"
reproduce the issue. Using instead
with_items:
- 'pkill -9 -f test'
or
with_items:
- 'kill -9 $(pgrep test) || echo'
will execute without an error.
Links
How can I start a process with any name which does nothing?
How to kill a running process using Ansible?
Similar Q&A
with the same error message
Ansible: How force kill process ...?
Further Reading
Since it is recommended to use Ansible modules instead of shell commands if possible
pids module – Retrieves process IDs list if the process is running otherwise return empty list
---
- hosts: localhost
become: false
gather_facts: false
tasks:
- name: Get Process ID (PID)
pids:
name: test
register: PID
- name: Show PID
debug:
msg: "{{ PID.pids | first }}"
- name: Shell task
shell:
cmd: "kill -9 {{ PID.pids | first }}"
register: result
- name: Show result
debug:
msg: "{{ result }}"
Ah, this is because running pkill from inside of Ansible causes it to kill itself (bug in pkill?)
In any case, a workaround is to do this:
with_items:
- 'if pgrep -f "debconf/frontend" | grep -v $$; then sudo pkill -9 -f "debconf/frontend"; fi'
I am trying to write a role to remove all helper addresses for a Cisco Router interface. There can be one or more helper addresses returned in stdout_lines. I use filters to remove labels and extra scapes from the lines and put the results into an array to use in the subsequent command loop. I seem to get the correct info but using the value fails.
Here is my role:
---
- name: read helpers
register: helper_facts
ios_command:
commands:
- show ip interface {{ interface }} | section Helper
- set_fact:
helper_addr: []
- set_fact:
helper_addr: "{{ helper_addr }} + [ '{{ item | regex_replace ('Helper address.* ','') | trim }}' ]"
with_items: "{{ helper_facts.stdout_lines }}"
- name: remove helpers
ios_command:
commands:
- no ip helper-address {{ item }}
with_items: "{{ helper_addr }}"
Here is a snip of the output with the error I get:
ok: [ONTMDFRTR01] => (item= 172.16.0.22) => {
"ansible_facts": {
"helper_addr": [
"192.1.0.1",
"172.16.0.22"
]
},
"ansible_loop_var": "item",
"changed": false,
"item": " 172.16.0.22"
}
TASK [remove_helpers : remove helpers] **********************************************************************************
task path: /home/msimon/USPS/roles/remove_helpers/tasks/main.yml:15
Monday 03 May 2021 16:44:23 -0400 (0:00:00.704) 0:00:05.874 ************
<10.32.178.252> ESTABLISH LOCAL CONNECTION FOR USER: root
<10.32.178.252> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /root/.ansible/tmp/ansible-local-23291P_KVGE `"&& mkdir "1-258083848203070 `" && echo ansible-tmp-1620074664.59-23371-258083848203070="` echo /root/.ansible/tmp/ansible-local-232
Using module file /usr/lib/python2.7/site-packages/ansible/modules/network/ios/ios_command.py
<10.32.178.252> PUT /root/.ansible/tmp/ansible-local-23291P_KVGE/tmpuSDML5 TO /root/.ansible/tmp/ansible-local-23291P_KVG
<10.32.178.252> EXEC /bin/sh -c 'chmod u+x /root/.ansible/tmp/ansible-local-23291P_KVGE/ansible-tmp-1620074664.59-23371-24.59-23371-258083848203070/AnsiballZ_ios_command.py && sleep 0'
<10.32.178.252> EXEC /bin/sh -c '/usr/bin/python /root/.ansible/tmp/ansible-local-23291P_KVGE/ansible-tmp-1620074664.59-2
<10.32.178.252> EXEC /bin/sh -c 'rm -f -r /root/.ansible/tmp/ansible-local-23291P_KVGE/ansible-tmp-1620074664.59-23371-25
The full traceback is:
WARNING: The below traceback may *not* be related to the actual failure.
File "/tmp/ansible_ios_command_payload_IFZQ7s/ansible_ios_command_payload.zip/ansible/module_utils/network/ios/ios.py",
return connection.run_commands(commands=commands, check_rc=check_rc)
File "/tmp/ansible_ios_command_payload_IFZQ7s/ansible_ios_command_payload.zip/ansible/module_utils/connection.py", line
raise ConnectionError(to_text(msg, errors='surrogate_then_replace'), code=code)
failed: [ONTMDFRTR01] (item=192.1.0.1) => {
"ansible_loop_var": "item",
"changed": false,
"invocation": {
"module_args": {
"auth_pass": null,
"authorize": null,
"commands": [
"no ip helper-address 192.1.0.1"
],
"host": null,
"interval": 1,
"match": "all",
"password": null,
"port": null,
"provider": null,
"retries": 10,
"ssh_keyfile": null,
"timeout": null,
"username": null,
"wait_for": null
}
},
"item": "192.1.0.1",
"msg": "no ip helper-address 192.1.0.1\r\nno ip helper-address 192.1.0.1\r\n ^\r\n% Invalid input detected at '^' m
}```
Thanks to mdaniel's comment I found the answer. I cut this from a larger playbook and left out the commands to setup the interface ("config t" , "int GigabitEthernet0/0/0") needed before the no helper_addres command. My role is now working as expected. Thanks, I hope this helps someone else.
I am reading a base64 file from HashiCorp’s vault with the help of the hashi_vault module. Sample of code:
- name: Vault get b64.pfx file
set_fact:
b64_pfx: "{{ lookup('hashi_vault',
'secret={{ path_pfx }} token={{ token }} url={{ url }} cacert={{ role_path}}/files/CA.pem')}}"
Then as a next step I need to decode this base64 var to a binary format and store it in in a file. I am currently using shell module to do the work. Sample of code:
- name: Decode Base64 file to binary
shell: "echo {{ b64_pfx }} | base64 --decode > {{ pfxFile }}"
delegate_to: localhost
I was looking online for possible solutions e.g. (
Copy module with base64-encoded binary file adds extra character and How to upload encrypted file using ansible vault?).
But the only working solution that I can found is using the shell module. Since this is an old problem is there any workaround on this?
Update:
Do not use Python 2.7 as there seems to be a bug on the b64decode filter (sample below):
<localhost> ESTABLISH LOCAL CONNECTION FOR USER: root
<localhost> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /tmp/ansible-tmp-1573819503.84-50241917358990 `" && echo ansible-tmp-1573819503.84-50241917358990="` echo /tmp/ansible-tmp-1573819503.84-50241917358990 `" ) && sleep 0'
Using module file /usr/lib/python2.7/site-packages/ansible/modules/commands/command.py
<localhost> PUT /tmp/ansible-local-18pweKi1/tmpjQGOz8 TO /tmp/ansible-tmp-1573819503.84-50241917358990/AnsiballZ_command.py
<localhost> EXEC /bin/sh -c 'chmod u+x /tmp/ansible-tmp-1573819503.84-50241917358990/ /tmp/ansible-tmp-1573819503.84-50241917358990/AnsiballZ_command.py && sleep 0'
<localhost> EXEC /bin/sh -c '/usr/bin/python /tmp/ansible-tmp-1573819503.84-50241917358990/AnsiballZ_command.py && sleep 0'
<localhost> EXEC /bin/sh -c 'rm -f -r /tmp/ansible-tmp-1573819503.84-50241917358990/ > /dev/null 2>&1 && sleep 0'
changed: [hostname -> localhost] => {
"changed": true,
"cmd": "shasum -a 1 /tmp/binary_file\nshasum -a 1 /tmp/binary_file.ansible\n",
"delta": "0:00:00.126279",
"end": "2019-11-15 13:05:04.227933",
"invocation": {
"module_args": {
"_raw_params": "shasum -a 1 /tmp/binary_file\nshasum -a 1 /tmp/binary_file.ansible\n",
"_uses_shell": true,
"argv": null,
"chdir": null,
"creates": null,
"executable": null,
"removes": null,
"stdin": null,
"stdin_add_newline": true,
"strip_empty_ends": true,
"warn": true
}
},
"rc": 0,
"start": "2019-11-15 13:05:04.101654",
"stderr": "",
"stderr_lines": [],
"stdout": "4a71465d449a0337329e76106569e39d6aaa5ef0 /tmp/binary_file\nead5cb632f3ee80ce129ef5fe02396686c2761e0 /tmp/binary_file.ansible",
"stdout_lines": [
"4a71465d449a0337329e76106569e39d6aaa5ef0 /tmp/binary_file",
"ead5cb632f3ee80ce129ef5fe02396686c2761e0 /tmp/binary_file.ansible"
]
}
Solution: use Python 3 with b64decode filter (sample below):
<localhost> ESTABLISH LOCAL CONNECTION FOR USER: root
<localhost> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /tmp/ansible-tmp-1573819490.9511943-224511378311227 `" && echo ansible-tmp-1573819490.9511943-224511378311227="` echo /tmp/ansible-tmp-1573819490.9511943-224511378311227 `" ) && sleep 0'
Using module file /usr/local/lib/python3.6/site-packages/ansible/modules/commands/command.py
<localhost> PUT /tmp/ansible-local-18epk_0jsv/tmp4t3gnm7u TO /tmp/ansible-tmp-1573819490.9511943-224511378311227/AnsiballZ_command.py
<localhost> EXEC /bin/sh -c 'chmod u+x /tmp/ansible-tmp-1573819490.9511943-224511378311227/ /tmp/ansible-tmp-1573819490.9511943-224511378311227/AnsiballZ_command.py && sleep 0'
<localhost> EXEC /bin/sh -c '/usr/bin/python /tmp/ansible-tmp-1573819490.9511943-224511378311227/AnsiballZ_command.py && sleep 0'
<localhost> EXEC /bin/sh -c 'rm -f -r /tmp/ansible-tmp-1573819490.9511943-224511378311227/ > /dev/null 2>&1 && sleep 0'
changed: [hostname -> localhost] => {
"changed": true,
"cmd": "shasum -a 1 /tmp/binary_file\nshasum -a 1 /tmp/binary_file.ansible\n",
"delta": "0:00:00.135427",
"end": "2019-11-15 13:04:51.239969",
"invocation": {
"module_args": {
"_raw_params": "shasum -a 1 /tmp/binary_file\nshasum -a 1 /tmp/binary_file.ansible\n",
"_uses_shell": true,
"argv": null,
"chdir": null,
"creates": null,
"executable": null,
"removes": null,
"stdin": null,
"stdin_add_newline": true,
"strip_empty_ends": true,
"warn": true
}
},
"rc": 0,
"start": "2019-11-15 13:04:51.104542",
"stderr": "",
"stderr_lines": [],
"stdout": "4a71465d449a0337329e76106569e39d6aaa5ef0 /tmp/binary_file\n4a71465d449a0337329e76106569e39d6aaa5ef0 /tmp/binary_file.ansible",
"stdout_lines": [
"4a71465d449a0337329e76106569e39d6aaa5ef0 /tmp/binary_file",
"4a71465d449a0337329e76106569e39d6aaa5ef0 /tmp/binary_file.ansible"
]
}
Since Python 2 is reaching the end of life in (January 1, 2020) there is no point of raising the bug.
Using the b64decode filter at least on ansible 2.9 does what you want:
- copy:
dest: '{{ pfxFile }}'
content: '{{ b64_pfx | b64decode }}'
delegate_to: localhost
I confirmed it writes only the specified bytes (no trailing whitespace) and is binary safe.
If you tried that behavior, and it doesn't work for you, then update your question to say that and to include the version of ansible you are using. I also think that bug you linked to has been fixed, because I tried their exact case on ansible 2.9 and it did the right thing:
- hosts: localhost
connection: local
gather_facts: no
tasks:
- set_fact:
string_in_base64: 'sxZARwIVokeqOMGPygc1S20CaGPiKDRGRzg0oSVGmCF2oXHua+9fVhriUQRd8vkmvpHoBmSsI6Y='
- copy:
dest: binary_file.ansible
content: '{{ string_in_base64 | b64decode }}'
- shell: |
echo '{{ string_in_base64 }}' | base64 --decode > binary_file
shasum -a 1 binary_file
shasum -a 1 binary_file.ansible
{
"changed": true,
"cmd": "echo 'sxZARwIVokeqOMGPygc1S20CaGPiKDRGRzg0oSVGmCF2oXHua+9fVhriUQRd8vkmvpHoBmSsI6Y=' | base64 --decode > binary_file\nshasum -a 1 binary_file\nshasum -a 1 binary_file.ansible\n",
"delta": "0:00:00.162251",
"end": "2019-11-13 13:10:56.683186",
"rc": 0,
"start": "2019-11-13 13:10:56.520935",
"stderr": "",
"stderr_lines": [],
"stdout": "7e88df04cf47019ae22e9c658b62c26b706c6ea5 binary_file\n7e88df04cf47019ae22e9c658b62c26b706c6ea5 binary_file.ansible",
"stdout_lines": [
"7e88df04cf47019ae22e9c658b62c26b706c6ea5 binary_file",
"7e88df04cf47019ae22e9c658b62c26b706c6ea5 binary_file.ansible"
]
}
This is simpler than the other answers. Just pipe the function at the end of the lookup()
- name: Vault get b64.pfx file
set_fact:
b64_pfx: "{{ lookup('hashi_vault',
'secret={{ path_pfx }} token={{ token }} url={{ url }} cacert={{ role_path}}/files/CA.pem') | b64decode }}"
I am trying to use a variable and the results of a previous task as input. Here is my code.
---
- hosts: localhost
vars:
v_hostname: XXXXXXXXXXXXX
v_datacentre: DC-UK-LON-GS
v_username: YYYYYYYY
v_password: XXXXXXXX
connection: local
gather_facts: false
tasks:
- name: Find the folder for the VM
vmware_guest_find:
hostname: "{{ v_hostname }}"
datacenter: "{{ v_datacentre }}"
username: "{{ v_username }}"
password: "{{ v_password }}"
validate_certs: no
name: MYVMNAME
register: folder
- debug:
msg:
- "{{ folder.folders }}"
- name: Gather facts from VM
connection: local
gather_facts: false
vmware_guest_facts:
hostname: "{{ v_hostname }}"
datacenter: "{{ v_datacentre }}"
username: "{{ v_username }}"
password: "{{ v_password }}"
validate_certs: no
folder: "{{ v_datacentre }}{{ folder.folders }}"
name: MYVMNAME
The last line tries to use the defined variable v_datacentre and append the value from the registered fact from the previous task. However the concatenation produces some unwanted wrapping chars:
ansible-playbook 2.4.2.0
config file = /etc/ansible/ansible.cfg
configured module search path = [u'/export/home/ansible/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python2.7/site-packages/ansible
executable location = /bin/ansible-playbook
python version = 2.7.5 (default, May 3 2017, 07:55:04) [GCC 4.8.5 20150623 (Red Hat 4.8.5-14)]
Using /etc/ansible/ansible.cfg as config file
Parsed /export/home/ansible/inventory_prod inventory source with ini plugin
[WARNING]: Ignoring invalid attribute: gather_facts
PLAYBOOK: mainvm.yml *****************************************************************************************************************************************
1 plays in mainvm.yml
PLAY [localhost] *********************************************************************************************************************************************
META: ran handlers
TASK [TEST1] *************************************************************************************************************************************************
task path: /export/home/ansible/mainvm.yml:12
Using module file /usr/lib/python2.7/site-packages/ansible/modules/cloud/vmware/vmware_guest_find.py
<127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: ansible
<127.0.0.1> EXEC /bin/sh -c 'echo ~ && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /export/home/ansible/.ansible/tmp/ansible-tmp-1523621823.18-119950066241401 `" && echo ansible-tmp-1523621823.18-119950066241401="` echo /export/home/ansible/.ansible/tmp/ansible-tmp-1523621823.18-119950066241401 `" ) && sleep 0'
<127.0.0.1> PUT /tmp/tmpM_Pf2B TO /export/home/ansible/.ansible/tmp/ansible-tmp-1523621823.18-119950066241401/vmware_guest_find.py
<127.0.0.1> EXEC /bin/sh -c 'chmod u+x /export/home/ansible/.ansible/tmp/ansible-tmp-1523621823.18-119950066241401/ /export/home/ansible/.ansible/tmp/ansible-tmp-1523621823.18-119950066241401/vmware_guest_find.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '/usr/bin/python2 /export/home/ansible/.ansible/tmp/ansible-tmp-1523621823.18-119950066241401/vmware_guest_find.py; rm -rf "/export/home/ansible/.ansible/tmp/ansible-tmp-1523621823.18-119950066241401/" > /dev/null 2>&1 && sleep 0'
ok: [localhost] => {
"changed": false,
"folders": [
"/vm/LON-GS-AD/LON-GS-AD-UNIX"
],
"invocation": {
"module_args": {
"datacenter": "DC-UK-LON-GS",
"hostname": "XXXXXXXXXXXXX",
"name": "MYVMNAME",
"password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
"username": "XXXXXXXX",
"uuid": null,
"validate_certs": false
}
}
}
TASK [debug] *************************************************************************************************************************************************
task path: /export/home/ansible/mainvm.yml:23
ok: [localhost] => {
"msg": [
[
"/vm/LON-GS-AD/LON-GS-AD-UNIX"
]
]
}
TASK [Gather facts from standalone ESXi server] **************************************************************************************************************
task path: /export/home/ansible/mainvm.yml:28
Using module file /usr/lib/python2.7/site-packages/ansible/modules/cloud/vmware/vmware_guest_facts.py
<127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: ansible
<127.0.0.1> EXEC /bin/sh -c 'echo ~ && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /export/home/ansible/.ansible/tmp/ansible-tmp-1523621827.79-78942665802166 `" && echo ansible-tmp-1523621827.79-78942665802166="` echo /export/home/ansible/.ansible/tmp/ansible-tmp-1523621827.79-78942665802166 `" ) && sleep 0'
<127.0.0.1> PUT /tmp/tmp43NXf_ TO /export/home/ansible/.ansible/tmp/ansible-tmp-1523621827.79-78942665802166/vmware_guest_facts.py
<127.0.0.1> EXEC /bin/sh -c 'chmod u+x /export/home/ansible/.ansible/tmp/ansible-tmp-1523621827.79-78942665802166/ /export/home/ansible/.ansible/tmp/ansible-tmp-1523621827.79-78942665802166/vmware_guest_facts.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '/usr/bin/python2 /export/home/ansible/.ansible/tmp/ansible-tmp-1523621827.79-78942665802166/vmware_guest_facts.py; rm -rf "/export/home/ansible/.ansible/tmp/ansible-tmp-1523621827.79-78942665802166/" > /dev/null 2>&1 && sleep 0'
fatal: [localhost]: FAILED! => {
"changed": false,
"invocation": {
"module_args": {
"datacenter": "XXXXXX",
"folder": "DC-UK-LON-GS[u'/vm/LON-GS-AD/LON-GS-AD-UNIX']",
"hostname": "XXXXXXXXXXXXX",
"name": "MYVMNAME",
"name_match": "first",
"password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
"username": "XXXXXXXX",
"uuid": null,
"validate_certs": false
}
},
"msg": "Unable to gather facts for non-existing VM MYVMNAME"
}
to retry, use: --limit #/export/home/ansible/mainvm.retry
PLAY RECAP ***************************************************************************************************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=1
The results of folder.folders is correctly printed by debug but in the last step the concatenation gives:
"folder": "DC-UK-LON-GS[u'/vm/LON-GS-AD/LON-GS-AD-UNIX']",
I confess to being a bit of an Ansible newbie but I don't understand where the [u' and ] come from. I just want to use the combined strings as input. Can anyone please explain or show solution or point me at some beginners documents for this sort of variable use?
Thanks.
So after some further playing turns out that the vmware_guest_find returns a list (and it's in the docs!!!) so I need to either pick the 1st item if there will only be one group or loop though them.
folder: "{{ v_datacentre }}{{ folder.folders[0] }}"
This does the job.
I am running a custom command because I haven't found a working module doing what I need, and I want to adjust the changed flag to reflect the actual behaviour:
- name: Remove unused images
shell: '[ -n "$(docker images -q -f dangling=true)" ] && docker rmi $(docker images -q -f dangling=true) || echo Ignoring failure...'
register: command_result
changed_when: "command_result.stdout == 'Ignoring failure...'"
- debug: var="1 {{ command_result.stdout }}"
when: "command_result.stdout != 'Ignoring failure...'"
- debug: var="2 {{ command_result.stdout }}"
when: "command_result.stdout == 'Ignoring failure...'"
(I know the shell command is ugly and could be improved by a more complex script but I don't want to for now)
Running this task on an host where no Docker image can be removed gives the following output:
TASK: [utils.dockercleaner | Remove unused images] ****************************
changed: [cloud-host] => {"changed": true, "cmd": "[ -n \"$(docker images -q -f dangling=true)\" ] && docker rmi $(docker images -q -f dangling=true) || echo Ignoring failure...", "delta": "0:00:00.064451", "end": "2015-07-30 18:37:25.620135", "rc": 0, "start": "2015-07-30 18:37:25.555684", "stderr": "", "stdout": "Ignoring failure...", "stdout_lines": ["Ignoring failure..."], "warnings": []}
TASK: [utils.dockercleaner | debug var="DIFFERENT {{ command_result.stdout }}"] ***
skipping: [cloud-host]
TASK: [utils.dockercleaner | debug var="EQUAL {{ command_result.stdout }}"] ***
ok: [cloud-host] => {
"var": {
"EQUAL Ignoring failure...": "EQUAL Ignoring failure..."
}
}
So, I have this stdout return value "stdout": "Ignoring failure...", and the debug task shows the strings are equal, so why is the task still displayed as "changed"?
I am using ansible 1.9.1.
The documentation I am refering to is this one: http://docs.ansible.com/ansible/playbooks_error_handling.html#overriding-the-changed-result
I think you may have misinterpreted what changed_when does.
changed_when marks the task as changed based on the evaluation of the conditional statement which in your case is:
"command_result.stdout == 'Ignoring failure...'"
So whenever this condition is true, the task will be marked as changed.