2
votes

Comment trier les numéros de version complexes dans Ansible

Je crée un playbook Ansible dans lequel je souhaite récupérer la dernière version d'un logiciel. Pour cela, j'ai utilisé un filtre de «tri» dans Ansible. Cependant, cela devient un peu plus difficile lorsque vous utilisez des numéros de version, qui sont plus complexes et ne sont pas vraiment des nombres, par exemple. 0.2.1 , 0.10.1 .

Voici ce que je fais en ce moment:

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"
}

Le playbook ci-dessus fonctionne, tant que les numéros de version restent sous le numéro 10 (par exemple 0.9.3, mais pas 0.10.2).

Pour montrer le problème:

- 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 }}"


0 commentaires

3 Réponses :


0
votes

Une partie de ce que vous recherchez est le version test , cependant, il est construit sur l'idée qu'un utilisateur veut juste une comparaison. Donc, vous devrez faire un peu de colle pour trouver la "dernière":

- 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 }}

(je ne prétends pas que ce soit la solution optimale, car il est très probable que les versions comparent les unes aux autres plus d'une fois, mais cela devrait fonctionner correctement pour les petites listes de versions)


0 commentaires

2
votes

Une option serait d'écrire un plug-in de filtre .

"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"
]

Ensuite, le simple jeu ci-dessous

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

donne:

> 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


0 commentaires

2
votes

vous pouvez utiliser la version de comparaison de jinja2 au lieu d'installer le plugin de filtre

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

que vous pouvez suivre après: https://docs.ansible.com/ansible/latest/ user_guide / playbooks_tests.html # comparaison de versions


0 commentaires