Ansible register result result.stdout result.rc etc dict variable not found,如何使用until循环

Ansible register result result.stdout result.rc etc dict variable not found, how to use until loop

ansible/ansible-playbook 版本:2.1.2.0 / 2.2.0.0

我正在尝试使用 yum/apt 安装包,但由于安装包的存储库位于 packagecloud.io,有时我会收到一条错误消息(当我通过-vvv 而 运行 使用我的 ansible-playbook)。

[Errno 14] curl#56 - \"TCP connection reset by peer\"\nTrying other mirror. ...some ansible verbose text here.. [Errno 256] No more mirrors to try.

这种情况不会一直发生。如果我再次重新运行同一个剧本,它工作正常,所以失败(连接重置)是随机出现的。

为了克服这个问题,我想使用 Ansible 的 until 循环,我们必须将其与 register 变量一起使用。

所以,我通过参考 Ansible 文档创建了这个 playbook 操作,了解如何使用 until 循环 here,但是使用那个语法我得到一个 'dictionary' 错误说那个结果变量(已注册)字典没有任何名为 stdout 的键。然后我尝试使用 result.rc (关键字段),它在 CentOS 机器上工作但在 Ubuntu 14.x trusty vagrant 机器上失败 result.rc字典不存在错误:

- name: Install telegraf agent/collector (RedHat)
  yum:
    name: "{{ agent_collector }}"
    state: "installed"
  when: ( ansible_os_family == 'RedHat' and company_install_collector == true )
  register: result
  until: result.stdout.find("Installed:") != -1
  #The following works in CentOS/RedHat
  #until: result.rc == 0  

 - debug: msg="result (redhat) = {{ result }}"

或(更新我的问题,这很明显)

- name: Install Company Proxy (Ubuntu)
  apt:
    name: "{{ company_proxy_pkg }}"
    state: "installed"
  when: ( ansible_distribution == 'Ubuntu' and company_install_proxy == true )
  register: result
  until: result.rc == 0

 - debug: msg="result (ubuntu) = {{ result }}"

得到如下错误信息(result.stdout -- dict object' has no attribute 'stdout' in both RedHat/CentOS and Ubuntu but getting dict object has no attribute 'rc' 仅在 Ubuntu 服务器中):

fatal: [localhost]: FAILED! => {"failed": true, "msg": "The conditional check '(result.stdout.find(\"Installed:\") != -1)' failed. The error was: error while evaluating conditional ((result.stdout.find(\"Installed:\") != -1)): 'dict object' has no attribute 'stdout'"}

fatal: [localhost]: FAILED! => {
    "failed": true, 
    "msg": "The conditional check 'result.rc == 0' failed. The error was: error while evaluating conditional (result.rc == 0): 'dict object' has no attribute 'rc'"
}

为什么寄存器变量(result 在我的例子中)没有 stdoutrc dict/variables 而文档说那些存在,或者如果我可以在一个 OS 的 -vvv 详细输出中看到它们,但它没有显示在另一个 OS?

正确答案及发现:

  1. 在 CentOS 中,如果操作成功并且设置了注册变量 result,则用户可以看到这些 dict 变量,例如:result.rc 为 0,result.stdout = "something\nsomethingEsle\netc etc etc" and/or result.stdout_lines = "...同上..." 在某些情况下 result.results。如果操作失败,那么如果由于 connection reset 或其他原因而失败,那么在我使用 yum 模块的情况下,我看不到 result.stdout 被设置。在那种情况下,唯一可用于失败操作的字典变量是 result.rc != 0。因此,在 until 循环中,until: result.rc == 0 条件适用于 successful/failed 两种情况CentOS.

  2. 在Ubuntu中,如果apt模块动作成功,我得到result.stdout和result.stdout_lines 变量集但没有 result.rc dict 变量集。对于失败的操作,没有设置 result.stdout 或 result.stdout_lines 或 result.rc dict 变量。因此,在 Ubuntu 的情况下,我无法使用这些字典变量之一来使用 until 循环。

我能想到的唯一解决方法是,将 apt-get install <pacakge> 包装在脚本中并在 BASH 等中使用 until 循环来执行 Ansible 正在执行的操作。至少,这会更容易编码,如果退出代码不是 0,那么我可以使用 until

但是,我终于找到了一个解决方案,它在 Ubuntu 中适用于成功和失败的情况:

Jinja2 过滤器可能有帮助,即 when: result|failed 因此,如果我必须为失败条件使用注册变量 result,然后使用 until,我将使用它(与失败状态相反)即:

until: result|succeeded

好的是,上面的 until 语句对 CentOS 和 Ubuntu 以及 successful/failed 状态都有效。

不推荐使用测试作为过滤器。不要使用 result|succeeded,而是使用 result is succeeded。此功能将在 2.9 版本中删除。