Stephen Halpin
Stephen Halpin

Reputation: 13

How do I compare timestamps in ansible with until?

I'm trying to compare some times in until:

- name: Reproduce issue
  hosts: localhost
  gather_facts: no
  vars:
    run_time: '{{ "%s" | strftime | int + 10 }}'

  tasks:
  - debug: var=run_time

  - name: Wait until current time > run_time
    ansible.builtin.shell:
      cmd: date +%s
      executable: /bin/bash
    register: command_output
    until: (command_output.stdout | int) > (run_time | int)
    retries: 2
    timeout: 10

I would expect the first time the task runs with until it will fail because command_output.stdout is less than run_time, but that after a retry it would complete successfully. However it fails, even though I can see command_output.stdout is larger.

2022-03-19 22:02:52,453 p=59827 u=shalpin n=ansible | PLAY [Reproduce issue] *********************************************************
2022-03-19 22:02:52,468 p=59827 u=shalpin n=ansible | TASK [debug] *******************************************************************
2022-03-19 22:02:52,505 p=59827 u=shalpin n=ansible | ok: [localhost] => {
    "run_time": "1647752582"
}
2022-03-19 22:02:52,509 p=59827 u=shalpin n=ansible | TASK [Wait until current time > run_time] **************************************
2022-03-19 22:03:03,699 p=59827 u=shalpin n=ansible | fatal: [localhost]: FAILED! => {"attempts": 2, "changed": true, "cmd": "date +%s", "delta": "0:00:00.013925", "end": "2022-03-19 22:03:03.641597", "msg": "", "rc": 0, "start": "2022-03-19 22:03:03.627672", "stderr": "", "stderr_lines": [], "stdout": "1647752583", "stdout_lines": ["1647752583"]}
2022-03-19 22:03:03,702 p=59827 u=shalpin n=ansible | PLAY RECAP *********************************************************************
2022-03-19 22:03:03,702 p=59827 u=shalpin n=ansible | localhost                  : ok=1    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0

I tried using jinja2_native = True in ansible.cfg, but I didn't notice any difference.

Versions: ansible [core 2.12.2] jinja version = 3.0.3

Upvotes: 1

Views: 814

Answers (1)

Frenchy
Frenchy

Reputation: 17007

you are using a template, so each time you call the var, you call the template, as you can see in this playbook, i display the var and the var is changed each time i call it: (so its normal your task failed!)

- name: Reproduce issue
  hosts: localhost
  gather_facts: no
  vars:
    run_time: '{{ "%s" | strftime | int }}'
  tasks:
    - debug: var=run_time
    - pause: seconds=2
    - debug: var=run_time


TASK [debug]
ok: [localhost] => {
    "run_time": "1647763003" <-------------------
}

TASK [pause] 
Pausing for 2 seconds
(ctrl+C then 'C' = continue early, ctrl+C then 'A' = abort)
ok: [localhost]

TASK [debug] 
ok: [localhost] => {
    "run_time": "1647763005" <-------------------

to avoid that, use set_fact:

- name: Reproduce issue
  hosts: localhost
  gather_facts: no
  tasks:
    - set_fact:
        run_time: '{{ "%s" | strftime | int }}'
    - debug: var=run_time
    - pause: seconds=2
    - debug: var=run_time


TASK [debug] 
ok: [localhost] => {
    "run_time": "1647763486" <-------------------
}

TASK [pause] 
Pausing for 2 seconds
(ctrl+C then 'C' = continue early, ctrl+C then 'A' = abort)
ok: [localhost]

TASK [debug] 
ok: [localhost] => {
    "run_time": "1647763486" <-------------------
}

set_fact sets the result of template and not the template.

In this case no problem for your playbook, the run_time keeps its original content.

Upvotes: 1

Related Questions