Ansible 突然使用 svr4pkg 作为 yum 的后端

Ansible suddenly uses svr4pkg as a backend of yum

声明 YUM 任务如下:

---
- hosts: all
  vars:
  tasks:

  - name: install package
    yum:
        name: ntp
        state: present

运行 以下命令:

ansible-playbook test.yml -i localhost, --connection=local -vvvv

收到错误消息:

TASK [install package] ***************************************************************************************************************************************************
task path: /home/osuser/dod/test.yml:6
Using module file /usr/lib/python2.7/site-packages/ansible/modules/system/setup.py
<localhost> ESTABLISH LOCAL CONNECTION FOR USER: osuser
<localhost> EXEC /bin/sh -c '/usr/bin/python && sleep 0'
Running svr4pkg as the backend for the yum action plugin
Using module file /usr/lib/python2.7/site-packages/ansible/modules/packaging/os/svr4pkg.py
<localhost> EXEC /bin/sh -c '/usr/bin/python && sleep 0'
fatal: [localhost]: FAILED! => {
    "ansible_facts": {
        "pkg_mgr": "svr4pkg"
    },
    "changed": false,
    "invocation": {
        "module_args": {
            "category": false,
            "name": "ntp",
            "proxy": null,
            "response_file": null,
            "src": null,
            "state": "present",
            "zone": "all"
        }
    },
    "msg": "src is required when state=present",
    "name": "ntp"

在调试中注意以下消息:

Running svr4pkg as the backend for the yum action plugin

Ansible 决定使用“srv4pkg”模块(需要 src 参数)作为 yum 的后端。

解决方法: 在 yum 模块上设置 use_backend: yum 参数...如果可能的话! (我在实际使用中无法修改yaml文件)

运行 CentOS 7.6 上的 Ansible 2.7.15.. 安装了 yum 所以绝对没有理由 svr4pkg 作为后端(不是 supported/documented by yum 模块).

然而,由于它似乎被定义为 ansible_fact,我做了以下测试(结果被过滤):

ansible -i localhost, all -m setup -k
SUCCESS => {
    "ansible_facts": {
        "ansible_distribution": "CentOS",
        "ansible_distribution_file_parsed": true,
        "ansible_distribution_file_path": "/etc/redhat-release",
        "ansible_distribution_file_variety": "RedHat",
        "ansible_distribution_major_version": "7",
        "ansible_distribution_release": "Core",
        "ansible_distribution_version": "7.6.1810",
        "ansible_os_family": "RedHat",
        "ansible_pkg_mgr": "svr4pkg",
        "ansible_python_version": "2.7.5",
        "module_setup": true
    },
    "changed": false
}

任何关于原因的线索以及如何执行ansible_pkg_mgr

这个发行版似乎附带 yumsvr4pkg,如下所示:

$ ll /usr/bin/yum
-rwxr-xr-x. 1 root root 801 Nov  5  2018 /usr/bin/yum
$ ll /usr/sbin/pkgadd
-rwxr-xr-x. 1 root root 207342 Jul  2 16:12 /usr/sbin/pkgadd

所以最后一个可用的包管理器解析被保留并优先/usr/lib/python2.7/site-packages/ansible/module_utils/facts/system/pkg_mgr.py

# A list of dicts.  If there is a platform with more than one
# package manager, put the preferred one last.  If there is an
# ansible module, use that as the value for the 'name' key.
PKG_MGRS = [{'path': '/usr/bin/yum', 'name': 'yum'},
            {'path': '/usr/bin/dnf', 'name': 'dnf'},
            {'path': '/usr/bin/apt-get', 'name': 'apt'},
            {'path': '/usr/sbin/pkgadd', 'name': 'svr4pkg'},
            [...]

    def collect(self, module=None, collected_facts=None):
        facts_dict = {}
        collected_facts = collected_facts or {}

        pkg_mgr_name = 'unknown'
        for pkg in PKG_MGRS:
            if os.path.exists(pkg['path']):
                pkg_mgr_name = pkg['name']

        # Handle distro family defaults when more than one package manager is
        # installed, the ansible_fact entry should be the default package
        # manager provided by the distro.
        if collected_facts['ansible_os_family'] == "RedHat":
            if pkg_mgr_name not in ('yum', 'dnf'):
                pkg_mgr_name = self._check_rh_versions(pkg_mgr_name, collected_facts)

        [...]

        facts_dict['pkg_mgr'] = pkg_mgr_name
        return facts_dict

所以这似乎是 ansible 上的一个非托管案例。

但是,我仍然不知道如何执行正确的值!

已通过升级到 Ansible 2.8+ 修复。

当系统上有多个包管理器可用时,请参阅https://github.com/ansible/ansible/issues/49184