W moim playbooku próbuję sprawdzić poprawność wersji Pythona. W tym systemie operacyjnym (Linux) mam dwie wersje Pythona:

python --version
Python 2.7.5

python3 --version
Python 3.6.8

Ustawiłem pre_task, aby sprawdzić wersję Ansible, a także wersję Pythona (przykład):

pre_tasks:
    - name: Validate we run with the correct Ansible version
      register: data
      assert:
        that:
          - ansible_version is defined
          - ansible_version.full is version('2.8.0.0', '>=')
          - ansible_python_version is defined
          - ansible_python_version is version('3.6.0', '>=')
        fail_msg: "'Python' version must be 3.6.0 and Ansible 2.8.0 minimal version."
      delegate_to: localhost
      run_once: true

    - name: Get facts
      register: facts
      setup:
        filter: ansible_python_version
      run_once: true

    - name: Debug facts
      debug:
        var: facts

Niestety, kiedy uruchamiam tę rolę, zawodzi, ponieważ wydaje się, że najpierw czytam Python2, a potem Python3.

Warto tutaj wspomnieć, że usunąłem przykład Ansible for Python2:

ansible --version
ansible 2.9.1
  config file = /ripl-nginx/ansible.cfg
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python3.6/site-packages/ansible
  executable location = /usr/local/bin/ansible
  python version = 3.6.8 (default, Aug  7 2019, 17:28:10) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]

Kiedy wykonuję pre_task, kończy się niepowodzeniem w następujący sposób:

fatal: [hostname -> localhost]: FAILED! => {
    "assertion": "ansible_python_version is version('3.6.0', '>=')",
    "changed": false,
    "evaluated_to": false,
    "msg": "'Python' version must be 3.6.0 and Ansible 2.8.0 minimal version."
}

Jeśli zmodyfikuję walidację do 2.7.5 np .:

- ansible_python_version is version('2.7.5', '>=')

Działa doskonale:

ok: [hostname] => {
    "facts": {
        "ansible_facts": {
            "ansible_python_version": "3.6.8"
        },
        "changed": false,
        "failed": false
    }
}

Zauważyłem, że jeśli usunę parametr delegate_to: localhost, najpierw znajdzie Python2, który, jak zakładam, jest przyczyną niepowodzenia (przykład):

pre_tasks:
    - name: Validate we run with the correct Ansible version
      register: data
      assert:
        that:
          - ansible_version is defined
          - ansible_version.full is version('2.8.0.0', '>=')
          - ansible_python_version is defined
          - ansible_python_version is version('2.7.5', '>=')
        fail_msg: "'Python' version must be 3.6.0 and Ansible 2.8.0 minimal version."
      run_once: true

    - name: Get facts
      register: facts
      setup:
        filter: ansible_python_version
      delegate_to: localhost
      run_once: true

    - name: Debug facts
      debug:
        var: facts

Wynik:

ok: [hostname] => {
    "facts": {
        "ansible_facts": {
            "ansible_python_version": "2.7.5"
        },
        "changed": false,
        "failed": false
    }
}

Czy to błąd, czy brakuje mi konfiguracji?

0
Thanos 19 listopad 2019, 14:11

1 odpowiedź

Rozwiązanie problemu (w przypadku, gdy skonfigurowano zmienne grupowe jako ansible_python_interpreter: /usr/bin/python3):

pre_tasks:
    - name: Validate we run with the correct Ansible version
      delegate_to: hostvars[inventory_hostname]['ansible_python_version']
      assert:
        that:
          - ansible_version is defined
          - ansible_version.full is version('2.8.0.0', '>=')
          - ansible_python_version is defined
          - ansible_python_version is version('3.6.0', '>=')
        fail_msg: "'Python' version must be 3.6.0 and Ansible 2.8.0 minimal version."
      run_once: True

Próbka wyjścia:

TASK [Validate we run with the correct Ansible version] *************************************************************************************************************************************************************************************
ok: [hostname -> hostvars[inventory_hostname]['ansible_python_version']] => {
    "changed": false,
    "msg": "All assertions passed"
}

TASK [Debug] ********************************************************************************************************************************************************************************************************************************
ok: [hostname] => {
    "hostvars[inventory_hostname]['ansible_python_version']": "3.6.8"
}

Jeśli preferowanym sposobem jest globalna konfiguracja interpretera, można to zrobić tak jak w głównym pliku ansible.cfg w [defaults] np .:

interpreter_python = /usr/bin/python3

Pamiętaj, że nie możesz mieć obu zdefiniowanych. Albo globalny w pliku ansible.cfg, albo dla każdego środowiska. Aby uzyskać więcej informacji, przeczytaj oficjalną dokumentację (Wykrywanie interpretera).

0
Thanos 19 listopad 2019, 21:07