Как я могу заставить Ansible выполнить оболочку script, если пакет (rpm) не установлен? Возможно ли каким-либо образом использовать модуль yum?
Как заставить Ansible выполнить оболочку script, если пакет не установлен
Ответ 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'