Ansible寄存器结果result.stoutout result.rc等dict变量未找到,如何使用直到循环

时间:2016-12-28 04:05:54

标签: ansible stdout ansible-playbook ansible-2.x

ansible / ansible-playbook version: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 doc来创建这个playbook动作,了解如何使用until循环here,但是使用该语法我得到一个'字典'错误,说明结果变量(已注册) dict没有任何名为 stdout 的键。然后我尝试使用result.rc(关键字段),它在CentOS机器上运行但在Ubuntu 14.x可信赖的流浪汉机器上失败,结果如下.rc dict not present错误:

- 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对象'在RedHat / CentOS和Ubuntu中没有属性'stdout',但是获取dict对象仅在Ubuntu服务器中没有属性'rc'):

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'"
}

为什么注册变量(在我的情况下结果)没有stdoutrc dict /变量,当文档说存在或我可以看到它们时在一个操作系统的-vvv详细输出中,但它没有显示在另一个操作系统上?

2 个答案:

答案 0 :(得分:2)

正确答案和调查结果:

  1. 在CentOS中,如果操作成功并且设置了注册变量结果,则用户可以看到这些dict变量,例如:result.rc为0,result.stdout ="某些东西\ nsomethingEsle \ netc等等"和/或result.stdout_lines =" ......与上述相同......"和结果。在某些情况下的结果。如果操作失败,那么我无法看到result.stdout在我的情况下设置为使用yum模块,如果由于connection reset或其他原因导致失败。在这种情况下,可用于失败操作的唯一dict变量是result.rc!= 0.因此,在until循环中,until: result.rc == 0条件适用于CentOS的成功/失败情况。

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

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

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

    Jinja2过滤器可能有用when: result|failed因此,如果我必须使用注册变量result来表示失败状态,然后使用until,我会使用它(与失败状态相反)即:as

    until: result|succeeded
    

    好处是,上面的语句将适用于CentOS和Ubuntu以及成功/失败状态。

答案 1 :(得分:2)

不建议将测试用作过滤器。不要使用result|succeeded,而要使用result is succeeded。此功能将在2.9版中删除。