I am struggling with this issue since several days and would appreciate your help. I would like to check if the crontab file for several users exist on a host. If so, a backup shall be done and the oldest x backups shall be removed.
To achieve this I first check if the crontab exists:
- name: check if crontab exists
ansible.builtin.stat:
path: "/var/spool/cron/tabs/{{ item }}"
loop: "{{ users }}"
register: crontabFile
Then I perform a backup of the file:
- name: backup old crontab
ansible.builtin.copy:
src: "{{ item.stat.path }}"
dest: "{{ item.stat.path }}_{{ ansible_date_time.iso8601_basic_short }}"
mode: "preserve"
remote_src: true
loop: "{{ crontabFile.results }}"
when: item.stat.exists
This works fine so far. Afterwards I check for existing backups:
- name: find backups of crontab
ansible.builtin.find:
paths: "{{ item.stat.path | dirname }}"
patterns: "{{ item.stat.path | basename }}_*"
loop: "{{ crontabFile.results }}"
register: crontabBackup
when: item.stat.exists
The next step would be to loop over the results of crontabBackup and remove the oldest x files of the backups for each user individually. The following does not work:
- name: delete oldest backups of crontab, keep last 5
ansible.builtin.file:
path: "{{ item }}"
state: absent
loop: "{{ (crontabBackup.results|selectattr('files', 'defined')|map(attribute='files')|flatten|sort(attribute='mtime')|map(attribute='path')|list)[:-5] }}"
What happens is, that a flat list of all files is generated and the oldest files of this list get removed. What I want is to sort the list per user and remove the files per user.
CodePudding user response:
After trying many different approaches, I think I've figured it out for myself. I will share my solution in case anyone is facing the same issue.
The solution is to use an outer loop that includes the inner loop via include_tasks as mentioned here.
# main.yml
- include_tasks: delete_backups_inner_loop.yml
loop: "{{ crontabBackup.results|selectattr('files', 'defined')|map(attribute='files') }}"
loop_control:
loop_var: userLoop
# delete_backups_inner_loop.yml
- name: delete oldest backups of crontab, keep last 5
ansible.builtin.file:
path: "{{ item.path }}"
state: absent
loop: "{{ (userLoop|sort(attribute='mtime'))[:-5] }}"