Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ansible logging on 'command' task timeout

I'm having issues to get my command output when task timeout is reached.

Here is my task:

  - name: test of echo-ing something
    ansible.builtin.command:
      cmd: "/bin/echo 'it works !'"
    timeout: 10
    register: command_result
    ignore_errors: yes

  - name: command_result
    ansible.builtin.debug:
      var: command_result

When there is no timeout, everything goes well, I have in command_result variable:

ok: [server1] => {
    "command_result": {
        "changed": true,
        "cmd": [
            "/bin/echo",
            "it works !"
        ],
        "delta": "0:00:00.004629",
        "end": "2022-03-24 09:47:12.104234",
        "failed": false,
        "msg": "",
        "rc": 0,
        "start": "2022-03-24 09:47:12.099605",
        "stderr": "",
        "stderr_lines": [],
        "stdout": "it works !",
        "stdout_lines": [
            "it works !"
        ]
    }
}

However, when I make my command triggering the timeout (for example: cmd: "/bin/sleep 40"), I have this :

TASK [test of echo-ing something] ***************************************
fatal: [server1]: FAILED! => {"changed": false, "msg": "The ansible.builtin.command action failed to execute in the expected time frame (10) and was terminated"}
...ignoring

TASK [command_result] ***************************************************
ok: [server1] => {
    "command_result": {
        "changed": false,
        "failed": true,
        "msg": "The ansible.builtin.command action failed to execute in the expected time frame (10) and was terminated"
    }
}

How to get standard output (stdout) and/or standard error (stderr) from the command when timeout is reached ? On my CI/CD, I need it to know why a command had reached the timeout

Thanks !

[EDIT] Regarding the answer given by @vladimir-botka I found another way to timeout command and not tasks. I'm pasting it here just in case it helps other people:

- name: "exec my command"
  ansible.builtin.shell:
    cmd: "timeout -v --foreground --signal=SIGINT 600 my_script.sh"
    chdir: "{{ work_dir }}"
    executable: /bin/bash
  register: cmd_output
- name: "command output"
  ansible.builtin.debug:
    var: cmd_output
like image 409
toussa Avatar asked Jul 01 '26 12:07

toussa


1 Answers

Q: "How to get stdout and/or stderr from the command when timeout is reached ?"

A: When a timeout is reached the task will be terminated not the command. Task keyword timeout says:

Time limit for task to execute in, if exceeded Ansible will interrupt and fail the task.

As a result, you don't get stdout/stderr from the command when the task's timeout is reached.


Note

One might expect to get stdout/stderr from the terminated command. For example, the script

shell> cat sleep_10.sh
#!/bin/bash
echo PID $$
sleep 10
echo Finished
exit 0

Will print Terminated when killed by shell> kill SIGTERM 875125

shell> ./sleep_10.sh
PID 875125
Terminated

But when the script is executed by the Ansible module command

    - command: '$PWD/sleep_10.sh'
      timeout: 5
      register: result
      ignore_errors: true

    - debug:
        var: result

there is no stdout/stderr about the termination. Instead, the message says the task was terminated

  result:
    changed: false
    failed: true
    msg: The command action failed to execute in the expected time frame (5) and was terminated

Running the script asynchronously doesn't help either

    - name: Run an async task
      command: '$PWD/sleep_10.sh'
      async: 5
      poll: 0
      register: result

    - name: Check on an async task
      async_status:
        jid: "{{ result.ansible_job_id }}"
      register: job_result
      until: job_result.finished
      retries: 10
      delay: 2
      ignore_errors: true

    - debug:
        var: job_result

gives (abridged)

TASK [Run an async task] *******************************************
changed: [localhost]

TASK [Check on an async task] **************************************
FAILED - RETRYING: [localhost]: Check on an async task (10 retries left).
FAILED - RETRYING: [localhost]: Check on an async task (9 retries left).
FAILED - RETRYING: [localhost]: Check on an async task (8 retries left).
FAILED - RETRYING: [localhost]: Check on an async task (7 retries left).
FAILED - RETRYING: [localhost]: Check on an async task (6 retries left).
fatal: [localhost]: FAILED! => changed=false 
  ansible_job_id: '633379103837.876333'
  attempts: 6
  child_pid: 876338
  finished: 1
  msg: Timeout exceeded
  results_file: /home/admin/.ansible_async/633379103837.876333
  started: 1
  stderr: ''
  stderr_lines: <omitted>
  stdout: ''
  stdout_lines: <omitted>
...ignoring

TASK [debug] ****************************************************
ok: [localhost] => 
  job_result:
    ansible_job_id: '633379103837.876333'
    attempts: 6
    changed: false
    child_pid: 876338
    failed: true
    finished: 1
    msg: Timeout exceeded
    results_file: /home/admin/.ansible_async/633379103837.876333
    started: 1
    stderr: ''
    stderr_lines: []
    stdout: ''
    stdout_lines: []
like image 69
Vladimir Botka Avatar answered Jul 05 '26 20:07

Vladimir Botka



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!