at - specific time & date

I want to automate a list of command exections with at.

Looking at the at modules documentation I see only unit & count for specify the time and date. That looks a litte unprecise to me.

What is the concepts here to specify something like '16:00 2023-01-19'?

So you are using ansible.posix.at?

That plugin uses a file to run AT as seen at https://github.com/ansible-collections/ansible.posix/blob/main/plugins/modules/at.py#L82

So in the code it uses the now + method. This may be a situation where a command/shell call would be the solution.

I want to automate a list of command exections with at.
What is the concepts here to specify something like '16:00 2023-01-19'?

For example, to schedule a command at "2022-12-12 17:30:00" declare
the variables

    now_datetime: "{{ '%Y-%m-%d %H:%M:%S'|strftime }}"
    at_datetime: "2022-12-12 17:30:00"
    at_seconds: "{{ ((at_datetime|to_datetime) -
                     (now_datetime|
                      to_datetime('%Y-%m-%d %H:%M:%S'))).seconds }}"
    at_minutes: "{{ (at_seconds|int / 60)|int + 1 }}"

gives

    now_datetime: 2022-12-12 17:26:23
    at_datetime: 2022-12-12 17:30:00
    at_seconds: 217
    at_minutes: 4

Use the variable *at_minutes*

    - ansible.posix.at:
        command: date > /tmp/test_at
        count: "{{ at_minutes }}"
        units: minutes
    - command: at -l
      register: out
    - debug:
        var: out.stdout

will display the queue

  out.stdout: "5\tMon Dec 12 17:30:00 2022 a admin"

The command executed as expected

cat /tmp/test_at

Mon 12 Dec 2022 05:30:00 PM CET

Example of a complete playbook for testing

- hosts: localhost

  vars:

    now_datetime: "{{ '%Y-%m-%d %H:%M:%S'|strftime }}"
    at_datetime: "2022-12-12 17:30:00"
    at_seconds: "{{ ((at_datetime|to_datetime) -
                     (now_datetime|
                      to_datetime('%Y-%m-%d %H:%M:%S'))).seconds }}"
    at_minutes: "{{ (at_seconds|int /
    60)|int + 1 }}"

  tasks:

    - debug:
        msg: |
          now_datetime: {{ now_datetime }}
          at_datetime: {{ at_datetime }}
          at_seconds: {{ at_seconds }}
          at_minutes: {{ at_minutes }}

    - ansible.posix.at:
        command: date > /tmp/test_at
        count: "{{ at_minutes }}"
        units: minutes

    - command: at -l
      register: out

    - debug:
        var: out.stdout

thx that really works. It is not really user-friendly though.

Apparently I am not the only one thinking this should be easier, so there is an issue for adding a more intuitive way to specify time and date https://github.com/ansible-collections/ansible.posix/issues/326

thx that really works. It is not really user-friendly though.

Apparently I am not the only one thinking this should be easier, so there is an issue for adding a more intuitive way to specify time and date https://github.com/ansible-collections/ansible.posix/issues/326

> now_datetime: "{{ '%Y-%m-%d %H:%M:%S'|strftime }}"
> at_datetime: "2022-12-12 17:30:00"
> at_seconds: "{{ ((at_datetime|to_datetime) -
> (now_datetime|to_datetime)).seconds }}"
> at_minutes: "{{ (at_seconds|int / 60)|int + 1 }}"
>
> - ansible.posix.at:
> command: date > /tmp/test_at
> count: "{{ at_minutes }}"
> units: minutes

Yes, it's rather awkward. I simplified the declaration of
*at_seconds*. It might be a good idea to have a conversion function
for this, e.g.

        - ansible.posix.at:
            command: date > /tmp/test_at
            count: "{{ at_datetime|at_minutes }}"
            units: minutes
          vars:
            at_datetime: "2022-12-12 17:30:00"
  
Try

cat plugins/filter/at_minutes.py

from datetime import datetime

def at_minutes(at_datetime):
    timesince = datetime.fromisoformat(at_datetime) - datetime.now()
    return int(timesince.total_seconds() / 60 + 1)

class FilterModule(object):

    def filters(self):
        return {
            'at_minutes': at_minutes,
        }

That works! Even with looping

        count: "{{ at_datetime|at_minutes }}"
...
would it be worth a PR on the issue or is this too quick'n'dirty?

It's quick'n'clean I'd say :slight_smile:

Yes, it's worth PR. I'll write tests for this. The question is which
collection?

Yes, it's worth PR. I'll write tests for this. The question is which
collection?

honestly, I am still not really 100% sure what the term 'collection' actually means in the Ansible context and how things are organized. The issue, however, lives in ansible-collection/ansible.posix. Isn't that hint enough?

I'm not sure if this kind of datetime conversion belongs to POSIX.

To learn about collections see https://github.com/ansible-collections

For example, Ansible.Posix, where the module ansible.posix.at comes
from, is "Ansible Collection targeting POSIX and POSIX-ish platforms."
https://docs.ansible.com/ansible/latest/collections/ansible/posix/index.html