如果没有安装软件包,如何使Ansible执行一个shell脚本

如果没有安装(rpm)软件包,如何让Ansible执行一个shell脚本? 是否有可能利用百胜模块?

在这种情况下,我不认为yum模块会有所帮助。 目前有3个州:缺席,现在和最新。 因为听起来你不想实际安装或删除软件包(至less在这一点上),那么你需要通过两个手动步骤来完成。 第一个任务将检查包是否存在,然后第二个任务将根据第一个命令的输出调用一个命令。

如果使用“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命令也将退出,如果找不到软件包,那么rpm命令也会退出,所以另一种可能性是使用:

 when: rpm_check.rc == 1 

基于上面的布鲁斯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 

与此相关。

把所有东西放在一起,完整的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

你不应该使用dpkg -l package因为它不知道你的软件包是否已经被删除或者仍然安装。
相反,使用dpkg -s package可能会更好。

要检查包是否已安装:
shell: dpkg -s package | grep 'install ok installed' shell: dpkg -s package | grep 'install ok installed'
或者如果您不介意暂停或其他状态的软件包:
shell: dpkg -s package | grep 'installed' shell: dpkg -s package | grep 'installed'
安装时返回0,否则返回1。

(使用shell是非常重要的,因为我们使用的是pipe道)

如果软件包可以通过系统软件包pipe理器(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 

我发现使用shell或命令模块不是“ansiblic”。

我更喜欢使用yum模块和json_queryfilter来检查包是否已经安装。 例如httpd包:

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