Somayyah Mohammed
Somayyah Mohammed

Reputation: 206

ansible wait until output is received from remote host

I want to automate patching my servers, and using the following playbook:

- name: Patch Upgrade
  block:
    - name: Patch upgrade process
      ansible.netcommon.cli_command:
        command: patch install {{ node_patch }} patches_repository
        check_all: True
        prompt: 
          - "[yes] ?"
          - "[yes] ?"
        answer: 
          - 'yes'
          - 'yes'
      register: result
      until: result.stdout.find("The system is going down for reboot NOW") != -1

During patching the output is similar to this:

ISE/admin#patch install ise-patchbundle-10.1.0.0-Ptach3-19110111.SPA.x86_64.tar.gz FTP_repository
% Warning: Patch installs only on this node. Install with Primary Administration node GUI to install on all nodes in deployment. Continue? (yes/no) [yes] ? yes
Save the current ADE-OS run configuration? (yes/no) [yes] ? yes
Generating configuration...
Saved the ADE-OS run Configuration to startup successfully
Initiating Application Patch installation...

Getting bundle to local machine...
Unbundling Application Package...
Verifying Application Signature...
patch successfully installed

% This application Install or Upgrade requires reboot, rebooting now...
Broadcast message from root@ISE (pts/1) (Fri Feb 14 01:06:21 2020):
Trying to stop processes gracefully. Reload lasts approximately 3 mins
Broadcast message from root@ISE (pts/1) (Fri Feb 14 01:06:21 2020):
Trying to stop processes gracefully. Reload takes approximately 3 mins
Broadcast message from root@ISE (pts/1) (Fri Feb 14 01:06:41 2020):
The system is going down for reboot NOW
Broadcast message from root@ISE (pts/1) (Fri Feb 14 01:06:41 2020):
The system is going down for reboot NOW

Each line is sent one after the other, and there is no specific wait time, the prompts are handled without issues as the patching starts, I want the upgrade task to keep running until the line The system is going down for reboot NOW is received then it should proceed to another task where it waits for the host to get back up.

Unfortunately it's not working as I am getting this instead:

fatal: [serv-1]: FAILED! => 
  msg: 'The conditional check ''result.stdout.find("The system is going down for reboot NOW") != -1'' failed. The error was: error while evaluating conditional (result.stdout.find("The system is going down for reboot NOW") != -1): ''dict object'' has no attribute ''stdout'''

How can I fix this?

Upvotes: 0

Views: 183

Answers (1)

Carlos Monroy Nieblas
Carlos Monroy Nieblas

Reputation: 2283

The broadcast notification "The system is going down for reboot NOW" is triggered and owned by journald (in old OS it was syslog), not the patch command, so they won't be reported to the result of the command; the error happens when the host is restarting, as result will have stderr instead of stdout.

An option would be to monitor the journal (or syslog) for the case that the restart occurs; but there are some caveats:

  • Those broadcast messages can be disabled or routed to a different output than the log or the console, here is an example of how that can be done

  • Not all the patches will trigger a reboot, in that case waiting for the "reboot" message won't appear

Upvotes: 1

Related Questions