Как отсортировать сложные номера версий в Ansible - PullRequest
1 голос
/ 09 мая 2019

Я создаю сборник пьес Ansible, в котором я хочу получить последнюю версию программного обеспечения. Для этого я использовал фильтр сортировки в Ansible. Это, однако, становится немного сложнее при использовании номеров версий, которые являются более сложными и на самом деле не являются числами, например 0.2.1, 0.10.1.

Вот что я сейчас делаю:

- name: Set version to compare
  set_fact:
    versions:
      - "0.1.0"
      - "0.1.5"
      - "0.11.11"
      - "0.9.11"
      - "0.9.3"
      - "0.10.2"
      - "0.6.1"
      - "0.6.0"
      - "0.11.0"
      - "0.6.5"

- name: Sorted list
  debug:
    msg: "{{ versions | sort }}"

- name: Show the latest element
  debug:
    msg: "{{ versions | sort | last }}"

Указанная выше книга воспроизведения работает до тех пор, пока номера версий остаются под номером 10 (например, 0.9.3, но не 0.10.2).

Показать проблему:

TASK [Set version to compare] ***************************************************************************************************************
ok: [localhost]

TASK [Sorted list] **************************************************************************************************************************
ok: [localhost] => {
    "msg": [
        "0.1.0",
        "0.1.5",
        "0.10.2",
        "0.11.0",
        "0.11.11",
        "0.6.0",
        "0.6.1",
        "0.6.5",
        "0.9.11",
        "0.9.3"
    ]
}

TASK [Show the latest element] **************************************************************************************************************
ok: [localhost] => {
    "msg": "0.9.3"
}

В данном примере значение желаемого значения равно 0.11.11

Кто-нибудь знает хороший способ сортировки сложных номеров версий в Ansible? Любая помощь будет оценена. Спасибо.

Ответы [ 3 ]

1 голос
/ 09 мая 2019

Можно было бы написать плагин фильтра .

> cat filter_plugins/sort_versions.py
from distutils.version import LooseVersion


def filter_sort_versions(value):
    return sorted(value, key=LooseVersion)


class FilterModule(object):
    filter_sort = {
        'sort_versions': filter_sort_versions,
    }

    def filters(self):
        return self.filter_sort

Тогда простая игра ниже

- debug:
    msg: "{{ versions | sort_versions }}"

дает:

"msg": [
    "0.1.0", 
    "0.1.5", 
    "0.6.0", 
    "0.6.1", 
    "0.6.5", 
    "0.9.3", 
    "0.9.11", 
    "0.10.2", 
    "0.11.0", 
    "0.11.11"
]
0 голосов
/ 27 июня 2019

вы можете использовать версию сравнения jinja2 вместо установки плагина фильтра

- name: test
  set_fact:
    max_number: "{{ item }}"
  when: max_number |default('0') is version(item, '<')
  loop: "{{ master_version }}"

, за которым вы можете следовать: https://docs.ansible.com/ansible/latest/user_guide/playbooks_tests.html#version-comparison

0 голосов
/ 09 мая 2019

Часть того, что вы ищете, это version тест , однако он основан на идее, что пользователь просто хочет один сравнение. Итак, вам нужно сделать немного клея, чтобы найти «последний»:

- set_fact:
    max_version: >-
      {%- set vmax = {} -%}
      {%- for v_1 in versions -%}
      {%- for v_2 in versions -%}
      {%- if v_1 is version(v_2, ">") and v_1 is version(vmax.get("max", "0.0.0"), ">") -%}
      {%- set _ = vmax.update({"max": v_1}) -%}
      {%- endif -%}
      {%- endfor -%}
      {%- endfor -%}
      {{ vmax.max }}

(я не претендую на то, что это оптимальное решение, так как очень вероятно, что версии сравниваются друг с другом более одного раза, но оно должно хорошо работать для небольших списков версий)

...