使用 ansible 收集软件包版本

使用 ansible 收集软件包版本

嗨朋友们,希望你们一切都好。

我得到了这个需要通过 ansible 完成的非常基本的任务,但我被变量寄存器困住了:

我需要用 ansible 收集一些软件包版本并显示如下输出:

主机有‘此软件:版本’

以下是剧情:

---
    - name: Collect All Package Versions
      hosts: all
      become: yes
      tasks:
        - name: Update APT package cache
          apt:
            update_cache: yes
          become: yes
    
        - name: Collect Package Versions
          shell: dpkg-query -f '${binary:Package}\t${Version}\n' -W "{{ item }}"
          with_items:
            - firefox
            - libwebp6
            - thunderbird
          register: package_versions
    
        - name: Display Package Versions
          debug:
            var: package_versions.stdout_lines

当我执行它时我收到此消息:

"package_versions.stdout_lines": "VARIABLE IS NOT DEFINED!"

我知道变量注册存在问题,但我需要一点提示。

谢谢 ;)

答案1

使用模块包装事实. 您将在变量中获得已安装软件包的字典ansible_facts.packages。 例如,

    - package_facts:
    - debug:
        msg: "{{ ansible_facts.packages[item]|
                 map(attribute='version') }}"
      loop:
        - firefox
        - libwebp6
        - thunderbird
      when: ansible_facts.packages[item] is defined

在 Ubuntu 中

ok: [localhost] => (item=firefox) => 
  msg:
  - 88.0.1+build1-0ubuntu0.20.04.2
ok: [localhost] => (item=libwebp6) => 
  msg:
  - 0.6.1-2
ok: [localhost] => (item=thunderbird) => 
  msg:
  - 1:78.8.1+build1-0ubuntu0.20.04.1

由于可能会安装多个版本的软件包,因此结果为列表。如果您想获取前几项,请添加过滤器第一的到管道

    - debug:
        msg: "{{ ansible_facts.packages[item]|
                 map(attribute='version')|first }}"
      ...

如果你将软件包列表放入变量中。例如,

  packages: [firefox, libwebp6, thunderbird]

你可以声明字典软件包版本

  package_versions: "{{ dict(packages|
                             zip(packages|
                                 map('extract', ansible_facts.packages)|
                                 map('map', attribute='version'))) }}"

给出

  package_versions:
    firefox:
    - 88.0.1+build1-0ubuntu0.20.04.2
    libwebp6:
    - 0.6.1-2
    thunderbird:
    - 1:78.8.1+build1-0ubuntu0.20.04.1

完整测试剧本的示例

- hosts: localhost

  vars:

    packages: [firefox, libwebp6, thunderbird]

    package_versions: "{{ dict(packages|
                               zip(packages|
                                   map('extract', ansible_facts.packages)|
                                   map('map', attribute='version'))) }}"

  tasks:

    - package_facts:

    - debug:
        msg: "{{ ansible_facts.packages[item]|
                 map(attribute='version')|first }}"
      loop:
        - firefox
        - libwebp6
        - thunderbird
      when: ansible_facts.packages[item] is defined

    - debug:
        var: package_versions

相关内容