当 Ansible 遇到 if
block ,以及 if
条件涉及groups
变量,它似乎在评估 if
之前扩展了 block 的内容健康)状况。这会导致 if
的 undefined variable 错误。条件否则会防止。
为什么会出现错误?是预期的行为,还是错误?
我已将行为减少到最小的测试用例。
库存.yml
group1:
group2:
hosts:
localhost:
vars:
foo: "{{ groups.group1[0] }}"
预期的
一个空字符串,因为在这两种情况下
if
条件为假$ ansible -i inventory.yml group2 -mdebug -amsg="{% if false %}{{ foo }}{% endif %}"
localhost | SUCCESS => {
"msg": ""
}
$ ansible -i inventory.yml group2 -mdebug -amsg="{% if groups.group1 %}{{ foo }}{% endif %}"
localhost | SUCCESS => {
"msg": ""
}
实际的
当
if
条件涉及groups
变量,foo
被评估,导致 undefined variable 消息$ ansible -i inventory.yml group2 -mdebug -amsg="{% if false %}{{ foo }}{% endif %}"
localhost | SUCCESS => {
"msg": ""
}
$ ansible -i inventory.yml group2 -mdebug -amsg="{% if groups.group1 %}{{ foo }}{% endif %}"
localhost | FAILED! => {
"msg": "The task includes an option with an undefined variable. The error was: list object has no element 0"
}
我正在使用 Ansible 2.7.9。
最佳答案
Ansible 根据 Jinja 的请求从它传递给 Jinja 的神奇上下文字典中按需扩展模板化键,但是 Jinja 在任何处理开始之前提前绑定(bind)模板引用的任何名称。
Jinja 期望上下文产生一个具体值或等价于 KeyError
(“未定义”IIRC),Ansible OTOH 使用这个时刻递归调用 Jinja 以构建传递给原始模板调用的值。正是在此递归调用中,您的错误正在发生。
查看类似模板的原始 Jinja 源代码可能会有所帮助(使用 jinja2.Environment().compile(..., raw=True)
准备:
from __future__ import division
from jinja2.runtime import LoopContext, TemplateReference, Macro, Markup, TemplateRuntimeError, missing, concat, escape, markup_join, unicode_join, to_string, identity, TemplateNotFound, Namespace
name = None
def root(context, missing=missing, environment=environment):
resolve = context.resolve_or_missing
undefined = environment.undefined
if 0: yield None
l_0_foo = resolve('foo')
l_0_groups = resolve('groups')
pass
if environment.getattr((undefined(name='groups') if l_0_groups is missing else l_0_groups), 'group1'):
pass
yield to_string((undefined(name='foo') if l_0_foo is missing else l_0_foo))
blocks = {}
debug_info = '1=12'
注意对
resolve()
的调用在任何条件评估发生之前完成。它在 resolve()
内Ansible 尝试递归地扩展您的 foo
多变的。应该可以进行调整,以便
foo
仅在 Jinja 尝试将其转换为字符串(或类似字符串)时才会扩展,因此我建议提交上游错误。
关于ansible - 为什么 Ansible 会评估这个变量,即使是在一个 false if block 内?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55651731/