如果没有安装(rpm)软件包,如何让Ansible执行shell脚本?是否有可能利用yum模块?
答案 0 :(得分:65)
我不认为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
所以你的ansible任务看起来像这样:
- 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
答案 1 :(得分:28)
基于上面的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
答案 2 :(得分:23)
与此相关。
将所有内容放在一起,完成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仍然没有内置支持进行简单的软件包更新,请参阅例:https://github.com/ansible/ansible/issues/10856
答案 3 :(得分:19)
如果软件包可以通过系统软件包管理器(yum,apt等)本身安装,那么你可以使用ansible的检查模式标志来注册安装状态,而无需实际安装软件包。
- 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
答案 4 :(得分:9)
您不应该使用dpkg -l package
,因为它不知道您的包裹是否已被移除或仍然安装。
相反,使用dpkg -s package
可能更好。
检查包装是否已安装:
- shell: dpkg -s package | grep 'install ok installed'
或者如果您不介意保留包裹或其他状态:
- shell: dpkg -s package | grep 'installed'
安装时返回0,否则返回1.
(因为我们使用管道|
)
答案 5 :(得分:9)
从Ansible 2.5开始,您可以使用package_facts模块:
- name: Gather package facts
package_facts:
manager: auto
- name: Debug if package is present
debug:
msg: 'yes, mypackage is present'
when: '"mypackage" in ansible_facts.packages'
- name: Debug if package is absent
debug:
msg: 'no, mypackage is absent'
when: '"mypackage" not in ansible_facts.packages'
注意:您需要在目标上安装apt / rpm的python绑定,例如python-apt
代表Debian。
答案 6 :(得分:1)
我发现使用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'