簡體   English   中英

如何使用 Ansible 過濾樹中每個文件的最新版本?

[英]How to filter the latest version of every file in a tree using Ansible?

我有一個包含各種文件的中等大小的目錄樹:

  • /some/place/distfiles/foo-1.2.jar
  • /some/place/distfiles/subdir/foo-1.3.jar
  • /some/place/distfiles/bar-1.1.jar
  • /some/place/distfiles/bar-1.1.2.jar

我使用find-module來獲取完整列表,但我只需要每個foobar最新版本。 例如,上面的集合需要簡化為:

  • /some/place/distfiles/subdir/foo-1.3.jar
  • /some/place/distfiles/bar-1.1.2.jar

不,我不能依賴文件的時間戳——只能依賴文件名的數字部分......

有人可以建議一種優雅的方法嗎?

這將是一些非常重要的 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM