Reputation: 313
I would like to know if there is a way to print information while a module is executing -- primarily as a means to demonstrate that the process is working and has not hung. Specifically, I am trying to get feedback during the execution of the cloudformation module. I tried modifying the (Python) source code to include the following:
def debug(msg):
print json.dumps({
"DEBUG" : msg
})
...
debug("The stack operation is still working...")
What this did, of course, was store all this output and only print it all after the module had finished executing. So for particularly large cloudformation templates, this means that I wait around for 5 minutes or so, and then suddenly see a large amount of text appear on the screen at the end. What I was expecting was to see "The stack operation is still working..." printed every x seconds.
It would seem that the Asynchronous Actions and Polling are what I'm looking for... but this didn't work, either. The entire task, "Launch CloudFormation for {{ stackname }}", was skipped entirely. See below for the relevant (YAML) snippet from my playbook:
- name: Launch CloudFormation for {{ stackname }}
cloudformation: >
stack_name="{{ stackname }}" state=present
region="{{ region }}" disable_rollback=true
template="{{ template }}"
register: cloud
args:
template_parameters:
KeyName: "{{ keyName }}"
Region: "{{ region }}"
SecurityGroup: "{{ securityGroup }}"
BootStrapper: "{{ bootStrapper }}"
BootStrapCommand: "powershell.exe -executionpolicy unrestricted -File C:\\{{ bootStrapper }} {{ region }}"
S3Bucket: "{{ s3Bucket }}"
async: 3600
poll: 30
This tells me that async is meant for typical shell commands, and not complex modules such as cloudformation. OR -- I may have done something wrong.
Could anyone shed some light on this situation? Again, for large cloudformation tasks that take a while, I would like some periodic indication that the task is still running, and not hanging. I appreciate the help!
Upvotes: 22
Views: 29158
Reputation: 11
I use the following to run a shell command in background and print the output (partly based on podarok's answer above). Provide the command to be executed in the background_shell_command variable, and run as playbook or using include_tasks:
---
- name: Run shell command in background
shell: "({{ background_shell_command }}>/tmp/background_task_output 2>&1; echo $? > /tmp/background_task_return_code) & echo $!"
register: background_task
- name: check if background task has finished
debug:
var: "lookup('pipe','tr \"\\r\" \"\\n\"</tmp/background_task_output | tail -1')"
retries: 10000000
delay: 1
until: "{{ lookup('pipe','ps -p {{ background_task.stdout | int }} >>/dev/null 2>&1 && echo false || echo true') }}"
- name: check return value of background task
shell: "cat /tmp/background_task_return_code"
register: background_task_exit_code
- name: fail if background task has failed
fail:
msg: "Error: the background command '{{ background_shell_command }}' has failed with return code {{ background_task_exit_code.stdout | int }}"
when: background_task_exit_code.stdout | int != 0
Upvotes: 1
Reputation: 1046
My approach for localhost module:
...
module.log(msg='test!!!!!!!!!!!!!!!!!')
...
Then on another window:
$ tail -f /var/log/messages
Nov 29 22:32:44 nfvi-ansible-xxxx python2: ansible-test-module test!!!!!!!!!!!!!!!!!
Upvotes: 11
Reputation: 41
There is a way around this, and it will display real-time output, however you'll have to deal with injected prefixes on each line. It's messy/hackish but for debugging/monitoring purposes it gets the job done:
- name: Run some command and echo it's realtime stdout
shell: ":"
with_lines: "/usr/bin/some_long_running_command with arguments and such here"
The command :
is just a noop, you can easily use command: /usr/bin/true
if that's easier. In any case, this will output lines similar to:
changed: [localhost] => (item=first output line)
changed: [localhost] => (item=second output line)
changed: [localhost] => (item=third output line)
Upvotes: 1
Reputation: 535
The answer is simple - no. Ansible is a Continuous system that aims to handle ability to run over a bunch of servers and displaying real-time stdout results can be very unconvenient.
But I think You can use some tricks if Your destination system can support execution in background. I see that Your system is windows, so You have to install cygwin onto it for ability to run background commands like "sleep 20 &" in the example below
You can run this playbook with ansible-playbook -vv background.yml
You can see that stdout changing.
echo Test---- >> /tmp/test && tail /tmp/test
is a demo command. You should output data to some file and tail it for ability to see the progress. Or You may look at file size of stdout file and display it. Use imagination )))
# @file background.yml
- hosts: 127.0.0.1
connection: local
gather_facts: no
tasks:
- name: Background operation
shell: "sleep 20 & \ PPID=$! \ echo $PPID"
register: bcktsk
- name: Check PPID
shell: "kill -0 {{ bcktsk.stdout | int + 2 }}"
register: checkppid
ignore_errors: true
- name: Check if process still active
shell: "echo Test---- >> /tmp/test && tail /tmp/test && kill -0 {{ bcktsk.stdout | int + 2 }}"
register: test
when: checkppid.rc == 0
until: test.rc ==1
delay: 2
retries: 10000
ignore_errors: true
Upvotes: 9