<h5 dir="auto">ISSUE TYPE</h5>

<ul dir="auto">
<li>Bug Report</li>
</ul>
<h5 dir="auto">COMPONENT NAME</h5>
<p dir="auto">retries loop</p>
<h5 dir="auto">ANSIBLE VERSION</h5>

<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="ansible 2.4.2.0
python version = 2.7.12 (default, Nov 20 2017, 18:23:56) [GCC 5.4.0 20160609]"><pre class="notranslate"><code class="notranslate">ansible 2.4.2.0
python version = 2.7.12 (default, Nov 20 2017, 18:23:56) [GCC 5.4.0 20160609]
</code></pre></div>
<h5 dir="auto">CONFIGURATION</h5>
<p dir="auto">default</p>
<h5 dir="auto">OS / ENVIRONMENT</h5>
<p dir="auto">Debian 9</p>
<h5 dir="auto">SUMMARY</h5>
<p dir="auto">While using <code class="notranslate">retries</code> loop in a task, <code class="notranslate">attempts</code> key from registered variable is not defined during first iteration. On Ansible 1.9.6, it was.<br>
In <a href="https://github.com/sereinity/ansible/blob/1e08e9a55f3207515e32299c99fd8cd22dc6a833/lib/ansible/executor/task_executor.py#L555">task_executor.py</a>, <code class="notranslate">attempts</code> key is defined only if <code class="notranslate">retries &gt; 1: </code>.</p>
<p dir="auto">This is a problem with my use case:<br>
I need to check that a host successfully went down after ordering reboot. This task can take some time, and the modules (ping) and or shell commands (nc, ...) raise an error when the host enters the expected state. So I use the retries loop with failed_when to override the fail behaviour.</p>
<h5 dir="auto">STEPS TO REPRODUCE</h5>
<p dir="auto">Run the following task with Ansible &gt;= 2.0. Destination host is up.</p>
<div class="highlight highlight-source-yaml notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="- name: Wait for instance to shutdown
  shell: 'nc -w 1 -zv {{ ansible_ssh_host }} 22'
  register: connection_shutdown
  failed_when: connection_shutdown.attempts &gt;= 5
  until: connection_shutdown.stderr.find(&quot;succeeded&quot;) == -1
  delegate_to: 127.0.0.1 
  retries: 5"><pre class="notranslate">- <span class="pl-ent">name</span>: <span class="pl-s">Wait for instance to shutdown</span>
  <span class="pl-ent">shell</span>: <span class="pl-s"><span class="pl-pds">'</span>nc -w 1 -zv {{ ansible_ssh_host }} 22<span class="pl-pds">'</span></span>
  <span class="pl-ent">register</span>: <span class="pl-s">connection_shutdown</span>
  <span class="pl-ent">failed_when</span>: <span class="pl-s">connection_shutdown.attempts &gt;= 5</span>
  <span class="pl-ent">until</span>: <span class="pl-s">connection_shutdown.stderr.find("succeeded") == -1</span>
  <span class="pl-ent">delegate_to</span>: <span class="pl-s">127.0.0.1 </span>
  <span class="pl-ent">retries</span>: <span class="pl-c1">5</span></pre></div>
<h5 dir="auto">EXPECTED RESULTS</h5>
<p dir="auto">Rebooting host between 1st and 2nd iteration of "Wait for instance to shutdown".</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="PLAY [Issue] ***********************************************************************************************

TASK [Gathering Facts] *********************************************************************************************
ok: [host1]

TASK [Wait for instance to shutdown] *******************************************************************************
FAILED - RETRYING: Wait for instance to shutdown (5 retries left).
##### Rebooting host1 #####
changed: [host1 -&gt; 127.0.0.1]

PLAY RECAP *********************************************************************************************************
host1                      : ok=2    changed=1    unreachable=0    failed=0   
"><pre class="notranslate"><code class="notranslate">PLAY [Issue] ***********************************************************************************************

TASK [Gathering Facts] *********************************************************************************************
ok: [host1]

TASK [Wait for instance to shutdown] *******************************************************************************
FAILED - RETRYING: Wait for instance to shutdown (5 retries left).
##### Rebooting host1 #####
changed: [host1 -&gt; 127.0.0.1]

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

</code></pre></div>
<h5 dir="auto">ACTUAL RESULTS</h5>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="PLAY [Issue] ***********************************************************************************************

TASK [Gathering Facts] *********************************************************************************************
ok: [host1]

TASK [Wait for instance to shutdown] *******************************************************************************
fatal: [host1]: FAILED! =&gt; {&quot;msg&quot;: &quot;The conditional check 'connection_shutdown.attempts &gt;= 5' failed. The error was: error while evaluating conditional (connection_shutdown.attempts &gt;= 5): 'dict object' has no attribute 'attempts'&quot;}
	to retry, use: --limit @/home/gmathon/ansible/test.retry

PLAY RECAP *********************************************************************************************************
host1                      : ok=1    changed=0    unreachable=0    failed=1   
"><pre class="notranslate"><code class="notranslate">PLAY [Issue] ***********************************************************************************************

TASK [Gathering Facts] *********************************************************************************************
ok: [host1]

TASK [Wait for instance to shutdown] *******************************************************************************
fatal: [host1]: FAILED! =&gt; {"msg": "The conditional check 'connection_shutdown.attempts &gt;= 5' failed. The error was: error while evaluating conditional (connection_shutdown.attempts &gt;= 5): 'dict object' has no attribute 'attempts'"}
	to retry, use: --limit @/home/gmathon/ansible/test.retry

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

</code></pre></div>
<h5 dir="auto">ISSUE TYPE</h5>
<ul dir="auto">
<li>Bug Report</li>
</ul>
<h5 dir="auto">COMPONENT NAME</h5>
<p dir="auto">default output plugin?  I'm not sure exactly what this is called.</p>
<h5 dir="auto">ANSIBLE VERSION</h5>
<p dir="auto">all versions are affected.  that's part of the problem.</p>
<h5 dir="auto">CONFIGURATION</h5>
<p dir="auto">I'm complaining about an inane default.  no configuration problems required</p>
<h5 dir="auto">OS / ENVIRONMENT</h5>
<p dir="auto">all</p>
<h5 dir="auto">SUMMARY</h5>
<p dir="auto">ansible error output is impossible to read.  Why oh why can the JSON output not at least by pretty by default?</p>
<h5 dir="auto">STEPS TO REPRODUCE</h5>
<p dir="auto">run any playbook that gives an error</p>
<h5 dir="auto">EXPECTED RESULTS</h5>
<p dir="auto">could we have pretty formatting like this:</p>
<p dir="auto">{<br>
'changed': true,<br>
"cmd": ["rpmbuild", "-ba", "SPECS/thing.spec"],<br>
"delta": "0:00:00.361828",<br>
"stderr":"""<br>
Lots of output<br>
from the program in question<br>
And newlines are interpreted properly!<br>
"""<br>
}</p>
<h5 dir="auto">ACTUAL RESULTS</h5>
<p dir="auto">An unreadable JSON dump.  I don't think I really need to put an example.</p>
<p dir="auto">My efforts to push for adoption of ansible in my organization have been thoroughly hindered by this problem - people can't read the error messages they get and so do not use the tool.</p>
<p dir="auto">You cannot hope to see all the people who are being turned off by this.  Most of them simply stop using and go away.</p>
<p dir="auto">Others (e.g. <a href="http://blog.cliffano.com/2014/04/06/human-readable-ansible-playbook-log-output-using-callback-plugin/" rel="nofollow">http://blog.cliffano.com/2014/04/06/human-readable-ansible-playbook-log-output-using-callback-plugin/</a>) have provided acceptable fixes for this with callback plugins (but it absolutely must be the default, or any solution is moot).  It is time for this ridiculous problem to be solved.  Please please please.</p>