Подтвердить что ты не робот

Как заставить Ansible выполнить оболочку script, если пакет не установлен

Как я могу заставить Ansible выполнить оболочку script, если пакет (rpm) не установлен? Возможно ли каким-либо образом использовать модуль yum?

4b9b3361

Ответ 1

Я не думаю, что модуль yum помог бы в этом случае. В настоящее время он имеет 3 состояния: отсутствует, настоящее и последнее. Поскольку это звучит так, как будто вы не хотите устанавливать или удалять пакет (по крайней мере, на данный момент), вам нужно сделать это двумя способами. Первая задача будет проверять, существует ли пакет, тогда вторая задача будет вызывать команду, основанную на выходе первой команды.

Если вы используете "rpm -q", чтобы проверить, существует ли пакет, вывод будет выглядеть так: для пакета, который существует:

# rpm -q httpd
httpd-2.2.15-15.el6.centos.1.x86_64

и так, если пакет не существует:

# rpm -q httpdfoo
package httpdfoo is not installed

Таким образом, ваши важные задачи будут выглядеть примерно так:

- name: Check if foo.rpm is installed
  command: rpm -q foo.rpm
  register: rpm_check

- name: Execute script if foo.rpm is not installed
  command: somescript
  when: rpm_check.stdout.find('is not installed') != -1

Команда rpm также выйдет с 0, если пакет существует, или 1, если пакет не найден, поэтому можно использовать следующую возможность:

when: rpm_check.rc == 1

Ответ 2

На основании вышеизложенного Bruce P аналогичный подход для файлов apt/deb -

- name: Check if foo is installed
  command: dpkg-query -l foo
  register: deb_check

- name: Execute script if foo is not installed
  command: somescript
  when: deb_check.stdout.find('no packages found') != -1

Ответ 3

Относительно этого.

Собираем все вместе, полный playbook для Debian (Ubuntu), который обновляет пакет, только если он уже установлен:

---
- name: Update package only if already installed (Debian)
  hosts: all
  sudo: yes
  tasks:
    - name: Check if Package is installed
      shell: dpkg-query -W -f='${Status}' {{ package }} | grep 'install ok installed'
      register: is_installed
      failed_when: no
      changed_when: no

    - name: Update Package only if installed
      apt:
        name: {{ package }}
        state: latest
        update_cache: yes
      when: is_installed.rc == 0

Уныло Ansible по-прежнему не имеет встроенной поддержки для простого обновления пакета, см. ex: https://github.com/ansible/ansible/issues/10856

Ответ 4

Вы не должны использовать dpkg -l package, потому что он не знает, был ли ваш пакет удален или все еще установлен.
Вместо этого, вероятно, лучше использовать dpkg -s package.

Чтобы проверить, установлен ли пакет:
- shell: dpkg -s package | grep 'install ok installed'
или если вы не против приостановленного пакета или других состояний:
- shell: dpkg -s package | grep 'installed'
Это возвращает 0 при установке и 1, если нет.

(Важно использовать оболочку, поскольку мы используем трубку |)

Ответ 5

Если пакет можно установить с помощью диспетчера системных пакетов (yum, apt и т.д.), вы можете использовать флаг режима проверки для регистрации статуса установки без фактической установки пакета.

- name: check if package is installed
  package:
    name: mypackage
    state: present
  check_mode: true
  register: mypackage_check

- name: run script if package installed
  shell: myscript.sh
  when: not mypackage_check.changed 

Ответ 6

Я нахожу, что использование shell или командного модуля не является "ansiblic".

Я предпочитаю использовать модуль yum и json_query фильтр, чтобы проверить, установлен ли пакет. Например. Пакет httpd:

    - yum:
        list: httpd
      register: apache_service

    - assert:
        that:
          - "'installed' in apache_service|json_query('results[*].yumstate')"
      msg: 'httpd is not installed'