Error Handling in Playbook has strange behaviour

Hi,

I wrote a playbook to update a group of ubuntu servers and reboot them if required.

If I run it against one host using the -l option it works as expected, running against the whole group (3 hosts) it gives some strange behaviour. The "add to reboot_hosts" task is only executed (and skipped) for the second host in the group. The host which requires a reboot is not rebooted. I think I overlooked something.

Best Regards
Christian Rusa

The playbook looks like this:

- hosts: rusa
   user: "{{ ssh_user }}"
   sudo: yes
   tasks:
   - name: perform dist-upgrade
     apt: upgrade=dist update_cache=yes
   - name: check if reboot is required
     command: ls /var/run/reboot-required
     register: reboot_required
     ignore_errors: True
   - name: add to reboot_hosts
     add_host: name={{ inventory_hostname }} groups=reboot_hosts
     when: reboot_required|success

- hosts: reboot_hosts
   user: "{{ ssh_user }}"
   sudo: yes
   gather_facts: no
   tasks:
   - name: reboot
     command: reboot

The output looks like this:

ansible-playbook -v update.yml

PLAY [rusa]

I forgot: ansible version 1.7 cloned from git last week.

Easier way to do this would be to use the “stat” module, use with “-v” to see what it returns and skip the “ignore_errors” logic.

Still, this doesn’t look right to me.

Can you please file a github ticket with this information so we can investigate and make sure we have test coverage if we can reproduce this behavior?

Thanks!

Doesn’t add host only run once per host loop? I think you need a with_items clause, I would just make it a handler off of stat for the file

Brian Coca

There always is a smarter modules that I don’t know :slight_smile:
Thank you for the hint with the stat module.

Unfortunately I have the same problem with the stat Module, so I will file a github ticket.
It seems that the task “add to reboot_hosts” is only executed for the first host in the ansible hosts file.

I wrote a shorter version for testing.

  • hosts: rusa
    user: “{{ ssh_user }}”
    sudo: yes
    tasks:

  • name: stat /tmp/dummy
    stat: path=/tmp/dummy
    register: dummy

  • name: add to reboot_hosts
    add_host: name=“{{ inventory_hostname }}” groups=reboot_hosts
    when: dummy.stat.exists == true

ansible-playbook bug.yml -v

PLAY [rusa] *******************************************************************

GATHERING FACTS ***************************************************************
ok: [host3.example.com]
ok: [host2.example.com]
ok: [host1.example.com]

TASK: [stat /tmp/dummy] *******************************************************
ok: [host3.example.com] => {“changed”: false, “stat”: {“exists”: false}}
ok: [host2.example.com] => {“changed”: false, “stat”: {“atime”: 1400734828.0029335, “ctime”: 1400560489.169877, “dev”: 64769, “exists”: true, “gid”: 0, “inode”: 5769287, “isblk”: false, “ischr”: false, “isdir”: false, “isfifo”: false, “isgid”: false, “islnk”: false, “isreg”: true, “issock”: false, “isuid”: false, “md5”: “d41d8cd98f00b204e9800998ecf8427e”, “mode”: “0644”, “mtime”: 1400560489.169877, “nlink”: 1, “pw_name”: “root”, “rgrp”: true, “roth”: true, “rusr”: true, “size”: 0, “uid”: 0, “wgrp”: false, “woth”: false, “wusr”: true, “xgrp”: false, “xoth”: false, “xusr”: false}}
ok: [host1.example.com] => {“changed”: false, “stat”: {“exists”: false}}

TASK: [add to reboot_hosts] ***************************************************
skipping: [host1.example.com]

PLAY RECAP ********************************************************************
host2.example.com : ok=2 changed=0 unreachable=0 failed=0
host1.example.com : ok=2 changed=0 unreachable=0 failed=0
host3.example.com : ok=2 changed=0 unreachable=0 failed=0

this is by design, add_hosts has BYPASS_HOST_LOOP = True, which means it executes only 1 time per play, you need to use with_items with it. Your current play cannot work.​

instead of making reboot_hosts into a play just create a reboot handler

  • handlers:
  • name: reboot
    command: reboot

and call it from the first play (notify: reboot) when testing for the existence of /var/run/reboot-required

Right, there’s an open ticket to make sure the add_host module has a very clear example of what to do and what not to do.

Basically it should only be used in the “ec2 provisioning” type plays where it’s adding some temporarily created hosts.

If you want to dynamically add hosts to new groups, “group_by” is the one to use.