首页 > 解决方案 > 为什么 include_role 一次处理一个主机?

问题描述

我创建了一个辅助角色来从源代码构建软件包。但是,当我尝试将它包含在一个循环中时——循环遍历描述包的字典。它有效,但是,当我从另一个角色的任务中包含它时:

- name: Build packages
  include_role:
    name: native-package
  loop: "{{ srcpkgs | dict2items }}"
  loop_control:
    loop_var: package
    label: "{{ package.key }}"
  when: srcpkgs is defined

srcpkg是一个描述包的散列。包入口的一个例子是:

srcpkgs:
  python:
    ver:    "3.7.0"
    sha:    "0382996d1ee6aafe59763426cf0139ffebe36984474d0ec4126dd1c40a8b3549"
    url:    "https://www.python.org/ftp/python/%%ver%%/Python-%%ver%%.tar.xz"
    confargs: >-
      --without-pymalloc
      --disable-ipv6
      --with-system-expat
      --enable-optimizations
      --with-lto
      --prefix={{ prefix }}
      --with-openssl={{ prefix }}
      --with-ssl-default-suites=openssl
    alltarg:    profile-opt
    env:
      - 'GITTAG="echo builtFor={{ inventory_hostname }}"'

我看到,它一次应用于一台机器,而不是并行应用于所有机器(forks设置为11),这会导致它花费不必要的长时间:

TASK [include_role : native-package] 
TASK [native-package : Create tmpdir]
ok: [host1]
TASK [native-package : Download package]
ok: [host1]
TASK [native-package : Extract]
ok: [host1]
... more tasks on host1 ...
TASK [native-package : Create tmpdir]
ok: [host2]
....

我希望输出是:

TASK [include_role : native-package] 
TASK [native-package : Create tmpdir]
ok: [host1]
ok: [host2]
... more hosts ...
ok: [hostN]
TASK [native-package : Download package]
ok: [host1]
ok: [host1]
... more hosts ...
ok: [hostN]
... more tasks ...

此外,我指定的标签没有出现在任何地方,而且我不知道在特定迭代中正在构建哪个包......

我如何改善上述情况?

(这里使用 ansible-2.6.2 和 Python-3.6.6。)

更新:问题似乎是由inventory_hostname字典中的引用触发的。实际上,如果我删除其中提到主机名的部分(从而使所有主机的条目都相同?),包含的角色将按我的预期执行。这似乎是一个错误,我会尝试提交一个...

标签: ansibleansible-2.x

解决方案


好的,这是一个已知问题——至少从 Ansible-2.4 开始。

当字典被循环 - 或迭代的任何其他方面 - 是host-specific时,它就会发生。例如,当它包含对 的引用时inventory_hostname


推荐阅读