![](/img/trans.png)
[英]How to create latest backup file every time in ansible using time stamp. How to copy the latest file(same file to destination)
[英]How to filter the latest version of every file in a tree using Ansible?
我有一個包含各種文件的中等大小的目錄樹:
我使用find-module來獲取完整列表,但我只需要每個foo和bar的最新版本。 例如,上面的集合需要簡化為:
不,我不能依賴文件的時間戳——只能依賴文件名的數字部分......
有人可以建議一種優雅的方法嗎?
這將是一些非常重要的 jinja2,因此您可能更喜歡編寫自定義模塊,以便您可以使用實際的編程語言工作(您仍然可以使用find:
和register:
來捕獲文件名列表,然后給它到您的自定義模塊以根據您的規則匯總每個文件的“最新”)
也就是說,我猜想在將項目從基本名稱到版本號拆分為tuple[str, str]
之后,可以使用version
測試來查找最新的:
- find:
paths:
- /some/place/distfiles
# etc
register: my_jars
- set_fact:
versions_by_filename: >-
{%- set results = {} -%}
{%- for f in my_jars.files -%}
{%- set bn = f.path | basename
| regex_replace(ver_regex, '\\1') -%}
{%- set v = f.path | regex_replace(ver_regex, '\\2') -%}
{%- set _ = results.setdefault(bn, []).append(v) -%}
{%- endfor -%}
{{ results }}
vars:
ver_regex: '(.*)-([0-9.-]+)\.jar'
- set_fact:
most_recent: >-
{%- set results = {} -%}
{%- for fn, ver_list in versions_by_filename.items() -%}
{%- set tmp = namespace(latest=ver_list[0]) -%}
{%- for v in ver_list -%}
{%- if tmp.latest is version(v, '<') -%}
{%- set tmp.latest = v -%}
{%- endif -%}
{%- endfor -%}
{%- set _ = results.update({fn: tmp.latest}) -%}
{%- endfor -%}
{{ results }}
讓我們首先為此目的轉換數據。 例如
- set_fact:
my_files: "{{ result.files|json_query('[].path') }}"
- debug:
var: my_files
給
my_files:
- /some/place/distfiles/foo-1.2.jar
- /some/place/distfiles/bar-1.1.jar
- /some/place/distfiles/bar-1.1.2.jar
- /some/place/distfiles/subdir/foo-1.3.jar
創建字典列表
- set_fact:
my_dict: "{{ my_dict
|default([]) + [
dict(['path', 'archive', 'version']
|zip([item,
(item|basename).split('-')[0],
(item|basename).split('-')[1]|splitext|list|first])) ] }}"
loop: "{{ my_files }}"
- debug:
var: my_dict
給
my_dict:
- archive: foo
path: /some/place/distfiles/foo-1.2.jar
version: '1.2'
- archive: bar
path: /some/place/distfiles/bar-1.1.jar
version: '1.1'
- archive: bar
path: /some/place/distfiles/bar-1.1.2.jar
version: 1.1.2
- archive: foo
path: /some/place/distfiles/subdir/foo-1.3.jar
version: '1.3'
按存檔名稱對項目進行分組
- set_fact:
my_groups: "{{ my_dict|groupby('archive') }}"
- debug:
var: my_groups
給
my_groups:
- - bar
- - archive: bar
path: /some/place/distfiles/bar-1.1.jar
version: '1.1'
- archive: bar
path: /some/place/distfiles/bar-1.1.2.jar
version: 1.1.2
- - foo
- - archive: foo
path: /some/place/distfiles/foo-1.2.jar
version: '1.2'
- archive: foo
path: /some/place/distfiles/subdir/foo-1.3.jar
version: '1.3'
數據准備好后,查找最新版本並打印結果
- debug:
msg: "Latest version of {{ item.0 }} is {{ item.1|json_query(query)|first }}"
vars:
query: "[?version == '{{ latest_version }}'].path"
latest_version: "{{ item.1|json_query('[].version')|max }}"
loop: "{{ my_groups }}"
給
msg: Latest version of bar is /some/place/distfiles/bar-1.1.2.jar
msg: Latest version of foo is /some/place/distfiles/subdir/foo-1.3.jar
信用@mdaniel: “max 一直存在試圖對版本號使用字典排序的問題,因為它聲稱在 1.2 和 1.10 選項中,1.2 是‘最新的’”
可以使用過濾器創建自定義過濾器插件並使用它來選擇最新版本。 例如
$ cat filter_plugins/version_filters.py from distutils.version import LooseVersion def version_max(l): return sorted(l, key=LooseVersion)[-1] class FilterModule(object): def filters(self): return { 'version_max' : version_max }
<archive>-<version>.<extension>
<archive>-<version>.<extension>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.