如何使用 Ansible 获取已安装的 YUM 包?

How can I get the installed YUM packages with Ansible?

我正在尝试获取所有已安装的 YUM packages on an RHEL 机器。我可以通过使用非幂等的 shell 命令轻松获得它,并且想改用 YUM 命令。

shell 命令工作正常:

- name: yum list packages
  shell: yum list installed > build_server_info.config

但是当我尝试使用 YUM 命令时,它只是执行,但没有给出任何结果:

- name: yum_command
  action: yum list=${pkg} list=available

那么,official Ansible documentation for the yum module 将列表描述为:

"Various (non-idempotent) commands for usage with /usr/bin/ansible and not playbooks."

所以你要找到一个幂等的 list 调用就不走运了。

如果您只想抑制 changed 输出,set the changed_when parameter to False

(此外,具有重复的 list 参数是可疑的。)

I can easily get it through using shell commands which is not idempotent

当您查询机器的当前状态时,您不能真正谈论幂等性。

"Idempontent"表示无论你运行某个任务多少次,任务都会保证机器处于desired状态。

当您查询当前状态时,您没有描述所需的状态。不管你做什么,用什么方法,"idempotent"这个词都不适用。


关于你的例子,它没有给你结果 - 你重复了两次相同的参数 list 并且任务应该失败(它没有,这看起来像一个 Ansible 怪癖)。

要获取已安装软件包的列表,您应该使用:

- name: yum_command 
  yum:
    list=installed
  register: yum_packages

- debug:
    var: yum_packages

它将描述每个包的字典列表保存到一个变量yum_packages

然后您可以使用 JSON Query Filter 获取单个包裹 (tar):

- debug: var=item
  with_items: "{{yum_packages|json_query(jsonquery)}}"
  vars:
    jsonquery: "results[?name=='tar']"

得到这样的结果:

"item": {
    "arch": "x86_64",
    "epoch": "2",
    "name": "tar",
    "nevra": "2:tar-1.26-31.el7.x86_64",
    "release": "31.el7",
    "repo": "installed",
    "version": "1.26",
    "yumstate": "installed"
}

或只有它的版本:

- debug: var=item
  with_items: "{{yum_packages|json_query(jsonquery)}}"
  vars:
    jsonquery: "results[?name=='tar'].version"
"item": "1.26"

从 Ansible 2.5 开始,您还可以使用 package_facts 模块:它将收集已安装包的列表作为 Ansible 事实。

来自 CPU 的示例:

- name: get the rpm package facts
  package_facts:
    manager: rpm

- name: show them
  debug: var=ansible_facts.packages

如果您的要求是只检查一个包,并且基于此您想要执行另一项任务,您可以使用 package_facts 模块 as

- name: install docker community edition in rhel8
  hosts: localhost
  connection: local

  tasks:
   - name: Gather the rpm package facts
     package_facts:
       manager: auto

   - name: check if docker-ce is already installed
     debug:
       var: ansible_facts.packages['docker-ce']


   - name: using command module to install docker-ce
     command: yum install docker-ce --nobest -y
     when: "'docker-ce' not in ansible_facts.packages"
     register: install_res

   - name: whether docker is installed now
     debug:
       var: install_res