Проверьте, установлено ли уже несколько пакетов на машине redhat, если они недоступны, затем установите их через ansible playbook

#variables #installation #ansible #conditional-statements

Вопрос:

Я хочу проверить, установлены ли определенные пакеты на моих узлах или нет. Если нет, то установите эти пакеты через ansible playbook.

Вот переменные, которые я предоставляю в playbook в качестве входных данных (IP-адреса узлов и пакеты, которые будут установлены):

 exec_server: '10.50.10.40,34.228.208.5'
pkgs:
  - zip
  - unzip
  - git
 

Вот учебник, который я написал, чтобы выяснить, был ли установлен какой-либо из пакетов, и, если нет, установите их.

 - name: Check Package installation
  hosts: "{{ exec_server }}"
  become: yes
  gather_facts: no
  
  tasks:
    - name: Gather the packager facts
      package_facts:
        manager: "auto"
  
    - name: Package status
      debug:
        msg: "{{ item }} {{ 'installed' if item in ansible_facts.packages else 'not installed' }}"
      loop: "{{ pkgs | default([]) }}"
      register: find_output

    - name: install the latest version of not installed Packages
      yum:
        name: "{% if pkgs is undefined in ansible_facts.packages %}-{{ pkgs }}{% endif %}"
        state: latest 
 

Ошибка, с которой я сталкиваюсь:

 Identity added: /tmp/awx_2137_f_94gy2c/artifacts/2137/ssh_key_data (/tmp/awx_2137_f_94gy2c/artifacts/2137/ssh_key_data)

PLAY [Check Package installation] **********************************************

TASK [Gather the packager facts] ***********************************************
ok: [34.228.208.5]
ok: [10.50.10.40]

TASK [Package status] **********************************************************
ok: [10.50.10.40] => (item=zip) => {
    "msg": "zip installed"
}
ok: [10.50.10.40] => (item=unzip) => {
    "msg": "unzip installed"
}
ok: [10.50.10.40] => (item=git) => {
    "msg": "git not installed"
}
ok: [10.50.10.40] => (item=python-pip) => {
    "msg": "python-pip not installed"
}
ok: [10.50.10.40] => (item=gcc) => {
    "msg": "gcc not installed"
}
ok: [34.228.208.5] => (item=zip) => {
    "msg": "zip installed"
}
ok: [34.228.208.5] => (item=unzip) => {
    "msg": "unzip installed"
}
ok: [34.228.208.5] => (item=git) => {
    "msg": "git not installed"
}
ok: [34.228.208.5] => (item=python-pip) => {
    "msg": "python-pip not installed"
}
ok: [34.228.208.5] => (item=gcc) => {
    "msg": "gcc not installed"
}

TASK [install the latest version of Uninstalled Packages] **********************
fatal: [10.50.10.40]: FAILED! => {"msg": "template error while templating string: expected token 'end of statement block', got 'ansible_facts'. String: {% if pkgs is undefined in ansible_facts.packages %}-{{ pkgs }}{% endif %}"}
fatal: [34.228.208.5]: FAILED! => {"msg": "template error while templating string: expected token 'end of statement block', got 'ansible_facts'. String: {% if pkgs is undefined in ansible_facts.packages %}-{{ pkgs }}{% endif %}"}

PLAY RECAP *********************************************************************
10.50.10.40                : ok=2    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   
34.228.208.5               : ok=2    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   
 

Как я могу получить пакеты, которые не установлены, только на основе моих pkgs переменных и фактов, собранных Ansible?

Ответ №1:

Вам не нужно проверять, установлен пакет или нет, прежде чем что-либо делать, это то state: present , для чего он предназначен:

present и installed просто обеспечит установку нужного пакета.

Источник: https://docs.ansible.com/ansible/latest/collections/ansible/builtin/yum_module.html#parameter-state

Таким образом, ваш игровой план должен быть таким же простым, как

 - name: Check Package installation
  hosts: "{{ exec_server }}"
  become: yes
  gather_facts: no
  
  tasks:
    - name: install the latest version of not installed Packages
      yum:
        name: "{{ pkgs }}"
        state: present 
 

Теперь, если вы хотите знать, что неверно в вашей конструкции, это if :

 {% if pkgs is undefined in ansible_facts.packages %}-{{ pkgs }}{% endif %}
 

Вы не можете запустить два теста для одной и той же переменной в одной и той же инструкции (то есть без or или and ).
В то время как здесь вы пытаетесь запустить in и is undefined тесты одновременно.

Что вы могли бы сделать, если хотите придерживаться этого маршрута, который является неоптимальным, как указано выше,-это использовать difference фильтр:

 - name: install the latest version of not installed Packages
  yum:
    name: "{{ pkgs | difference(ansible_facts.packages) }}"
    state: latest 
 

Комментарии:

1. Спасибо за быстрый ответ :). Я попробовал вышесказанное, и все пакеты были установлены, кроме python-pip. Нужно ли нам упоминать какой-либо другой модуль для установки python-pip ?

2. Отвечает ли это на ваш вопрос: access.redhat.com/solutions/1519803 ?

3. $ pip -V pip 8.1.2 из /usr/lib/python2.7/site-пакеты (python 2.7) Это то , что я вижу, когда проверяю, установлен ли pip или нет, Но когда я проверял то же самое через playbook, он показывал } ок: [34.228.208.5] => (элемент=python-pip) =>> { «msg»: «python-pip не установлен» }

4. Ну, это просто означает, что pip не был установлен с помощью пакета rpm, а не то, что он вообще не установлен.

5. Что это yum list installed | grep pip дает вам?