Reputation: 1519
I have a list of files in a particular directory as shown below:
david@host:~/jobs/process/workspace/files$ ls -lrth
total 68K
-rw-r--r-- 1 david david 7.8K Oct 1 11:10 golden_proc.init.1569953435497
-rw-r--r-- 1 david david 7.7K Oct 2 12:11 golden_proc.init.1570043494149
-rw-r--r-- 1 david david 7.7K Oct 2 20:15 golden_proc.init.1570072510929
Each file name ends with timestamp in it. Now I need to find one latest file which was modified or created just a minute back in ansible.
Is this possible to do in ansible? I saw there is a find module in ansible but not sure how can I make above things work using that module?
---
- name: Play 1
hosts: 127.0.0.1
tasks:
- name: find the latest file
find: paths=/var/lib/jobs/workspace/process/files
file_type=file
age=-{{ time_window }}m
age_stamp=mtime
register: files
Upvotes: 2
Views: 4113
Reputation: 39129
This is definitely something possible, you are even close from the solution.
As you might have seen it doing a debug
of your find
already, the return of it contains a list of files
, this list would just be empty if you have no file.
So it become pretty easy to see when the list is empty with Jinja
- debug:
msg: '{{ files.files if files.files|count > 0 else "cannot find any file" }}'
This syntax is using an inline if
as well as a count
filter.
Regarding the fact that you want the most recent file now, you can also use a set of Jinja filers: the filter sort
will help you sort the files by modification time, and the filter first
will help you get only the first element of you list.
- debug:
msg: '{{ (files.files | sort(attribute="mtime", reverse=true) | first).path }}'
Now you just need to combine both in one long Jinja expression:
- debug:
msg: '{{ (files.files | sort(attribute="mtime", reverse=true) | first).path if files.files|count > 0 else "cannot find any file" }}'
In order to copy the file, you will need one extra Jinja filter that is specific to Ansible and that is basename
, in order to get the name of the file out of its full path
- debug:
msg: '{{ (files.files | sort(attribute="mtime", reverse=true) | first).path | basename if files.files|count > 0 else "cannot find any file" }}'
But you will also need the when
statement so your copy will be skipped if there is no matching file:
- name: Copy file, if found
copy:
src: '{{ (files.files | sort(attribute="mtime", reverse=true) | first).path }}'
dest: '/tmp/{{ (files.files | sort(attribute="mtime", reverse=true) | first).path | basename }}'
when: files.files|count > 0
A full working playbook for you to test:
---
- hosts: localhost
connection: locale
vars:
var_files:
- { 'name': 'a', 'time': 86400 }
- { 'name': 'b', 'time': 30 }
- { 'name': 'c', 'time': 20 }
tasks:
- name: creating a bunch of matching files
file:
path: '/data/{{ item.name }}'
state: touch
with_items: '{{ var_files }}'
- name: aging those files
file:
path: '/data/{{ item.name }}'
modification_time: '{{ "%Y%m%d%H%M.%S" | strftime( ( ansible_date_time.epoch | int ) - item.time ) }}'
with_items: '{{ var_files }}'
- name: find the latest file
find: paths=/data
file_type=file
age=-1m
age_stamp=mtime
register: files
- debug:
msg: '{{ (files.files | sort(attribute="mtime", reverse=true) | first).path if files.files|count > 0 else "cannot find any file" }}'
- name: Copy file, if found
copy:
src: '{{ (files.files | sort(attribute="mtime", reverse=true) | first).path }}'
dest: '/tmp/{{ (files.files | sort(attribute="mtime", reverse=true) | first).path | basename }}'
when: files.files|count > 0
- name: removing files to test the behaviour with no matching files
file:
path: '/data/{{ item.name }}'
state: absent
with_items: '{{ var_files }}'
- name: find the latest file
find: paths=/data
file_type=file
age=-1m
age_stamp=mtime
register: files
- debug:
msg: '{{ (files.files | sort(attribute="mtime", reverse=true) | first).path if files.files|count > 0 else "cannot find any file" }}'
- name: Copy file, if found
copy:
src: '{{ (files.files | sort(attribute="mtime", reverse=true) | first).path }}'
dest: '/tmp/{{ (files.files | sort(attribute="mtime", reverse=true) | first).path | basename }}'
when: files.files|count > 0
And the corresponding output of that playbook
PLAY [localhost] ********************************************************************************************************************************
TASK [Gathering Facts] **************************************************************************************************************************
ok: [localhost]
TASK [creating a bunch of matching files] *******************************************************************************************************
changed: [localhost] => (item={'name': 'a', 'time': 86400})
changed: [localhost] => (item={'name': 'b', 'time': 30})
changed: [localhost] => (item={'name': 'c', 'time': 20})
TASK [aging those files] ************************************************************************************************************************
changed: [localhost] => (item={'name': 'a', 'time': 86400})
changed: [localhost] => (item={'name': 'b', 'time': 30})
changed: [localhost] => (item={'name': 'c', 'time': 20})
TASK [find the latest file] *********************************************************************************************************************
ok: [localhost]
TASK [debug] ************************************************************************************************************************************
ok: [localhost] => {
"msg": "/data/c"
}
TASK [Copy file, if found] **********************************************************************************************************************
changed: [localhost]
TASK [removing files to test the behaviour with no matching files] ******************************************************************************
changed: [localhost] => (item={'name': 'a', 'time': 86400})
changed: [localhost] => (item={'name': 'b', 'time': 30})
changed: [localhost] => (item={'name': 'c', 'time': 20})
TASK [find the latest file] *********************************************************************************************************************
ok: [localhost]
TASK [debug] ************************************************************************************************************************************
ok: [localhost] => {
"msg": "cannot find any file"
}
TASK [Copy file, if found] **********************************************************************************************************************
skipping: [localhost]
PLAY RECAP **************************************************************************************************************************************
localhost : ok=9 changed=4 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
Upvotes: 2