获取ansible中已安装软件包列表和所需软件包列表之间的差异列表

获取ansible中已安装软件包列表和所需软件包列表之间的差异列表,ansible,Ansible,(请参阅下面的更新2了解我的最后一句话)。 我想让ansible通过比较已安装的软件包和所需软件包的列表来生成缺失软件包的列表。(丢失的包列表将被传递给yum进行安装。)似乎可以使用包事实和“差异”过滤器的某种组合来实现这一点,但我无法想出正确的语法 例如,以下提供了有关已安装软件包的信息: - name: get the rpm package facts package_facts: - name: show them debug: var=ansible_facts.pa

(请参阅下面的更新2了解我的最后一句话)。

我想让ansible通过比较已安装的软件包和所需软件包的列表来生成缺失软件包的列表。(丢失的包列表将被传递给yum进行安装。)似乎可以使用包事实和“差异”过滤器的某种组合来实现这一点,但我无法想出正确的语法

例如,以下提供了有关已安装软件包的信息:

 - name: get the rpm package facts
   package_facts:

 - name: show them
   debug: var=ansible_facts.packages
列表可以这样比较:

- name: Find difference of two lists
  gather_facts: no
  hosts: localhost
  vars:
      missing: "{{ input1|difference(input2) }}"
      input1:
      - john
      - mary
      input2:
      - john
      - alice
  tasks:
    - name: 'Print them out'
      debug: var=missing
如何将这两种技术结合在一起,形成一个列表,供yum以后使用

更新

Zigarn下面的回答让我非常接近我想要的(警告是“set_fact:”而不是“set_facts:”和“package:”而不是“packages:”)。以下是我正在尝试的:

 - name: Retrieve the installed packages
  package_facts:

- name: Get only list of name of installed packages
  set_fact:
     installed_packages: "{{ ansible_facts.packages.keys() }}"

- name: Specify list of desired packages
  set_fact:
    desired_packages:
      - emacs
      - antiword
      - gimp
      - junk
      - otherstuff
- name: Compute missing packages
  set_fact:
    missing_packages: "{{ desired_packages | difference (installed_packages) }}"

- name: Print list of missing packages
  debug: var=missing_packages

- name: Print list of installed packages
  debug: var=installed_packages

- name: Install missing packages
  ignore_errors: yes
  yum:
    skip_broken: yes
    name: "{{ item }}"
    state: present
  loop: "{{ missing_packages }}"
这确实试图安装丢失的软件包,但“emacs”是个奇怪的例外,它目前没有安装,但ansible也没有将其放入丢失的软件包列表中。这可能只是这个特殊的包的一些奇怪之处,所以我将继续并标记zigarn的帖子作为答案,但继续研究这个问题

关于我这样做的原因,有两个原因:首先,我使用循环和列表,而不是一次将所有软件包传递给yum,因为我希望避免所需软件包列表中的键入错误或存储库中不存在的命名软件包导致yum无法安装任何列出的软件包。在这些情况下,“skip_break”没有帮助。第二,我安装了很多软件包(数千个),而百胜的速度非常慢,因此将列表缩小到缺少的软件包可以节省一个小时的计算机更新时间

更新2

在对此进行了一段时间的实验之后,我决定我不确定我是否理解ansible_facts.packages返回的数据结构以及“差异”对它的解释方式,因此我现在将坚持以下内容

- name: Get list of installed packages without arch
  command: "rpm -q --qf '%{NAME}\n' -a"
  args:
      warn: false
  register: installed_packages_noarch

- name: Get list of installed packages with arch
  command: "rpm -q --qf '%{NAME}.%{ARCH}\n' -a"
  args:
      warn: false
  register: installed_packages_arch

- name: Combine the lists of packages with and without arch
  set_fact:
    installed_packages: "{{ installed_packages_noarch.stdout_lines + installed_packages_arch.stdout_lines }}"

- name: Install missing packages
  ignore_errors: yes
  yum:
    skip_broken: yes
    state: present
    name: "{{ item }}"
  loop: "{{ desired_packages | difference (installed_packages) }}"
  vars:
    desired_packages:
      - emacs
      - gimp
      - somethingelse
      - anotherthing

请注意,我已经退回到只使用rpm来获取已安装软件包的列表,实际上我让它生成两个列表并将它们组合起来:一个裸软件包名称列表和一个packagename.architecture列表。这允许我在需要安装多个体系结构的包的情况下,在所需包列表中指定libsomething.i686或libother.x86_64之类的内容。

首先,您需要知道,您不需要将缺少的包列表计算为
模块(或特定于平台的模块
yum
apt
,…)是幂等的,无论如何都会检查自己缺少的软件包以安装它们

但是,如果你需要它的另一个目的,这里是如何做到这一点

package\u facts
正在填充
ansible\u facts.packages
变量,并在

如果要将其与包名称的简单列表进行比较,只需使用包的键即可。然后,您可以获得两个列表之间的差异:

-name:检索已安装的软件包
一揽子事实:
-名称:仅获取已安装软件包的名称列表
设定事实:
已安装的_包:“{{ansible_facts.packages.keys()}”
-名称:计算缺少的包
设定事实:
缺少软件包:{{package_list_you_want}差异(已安装的软件包)}
-名称:安装缺少的软件包
包裹:
名称:“{{missing_packages}}”
国家:现在

谢谢。这似乎(至少几乎)帮我找到了我需要去的地方。请参阅我在原始帖子上的更新。你能添加已安装软件包列表的输出吗?(尝试理解为什么跳过emacs)在很多包上循环可能比给出一个长列表还要慢,因为这意味着每个包都要进行SSH往返安装。有数千个已安装的包,所以我不会全部列出,而是列出包含字符串“emacs”的包关于往返时间,这不是问题,因为这些都是在本地运行的,而不是通过ssh运行的。