我定义了这本剧本:
---
- hosts: "{{ target }}"
tasks:
- name: buildout test
my_buildout:
cfg: "{
'/home/oerp/tmp':
{
'childs': {
'{{ custom_name }}': {
'rules': [
(
(),
('cmd', [('touch', {{ get_path('test.txt') }})])
)
]
}
}
}
}"
通过以下方式运行我的剧本:ansible-playbook --extra-vars "target=local_stage" --connection=local /home/oerp/src/ansible-playbooks/buildout_test.yml -v
给出此错误:
fatal: [stage-my-odoo]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'get_path' is undefined\n\nThe error appears to be in '/home/oerp/src/ansible-playbooks/buildout_test.yml': line 4, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n tasks:\n - name: buildout test\n ^ here\n"}
现在{{ custom_name }}
是一个变量,其中{{ get_path('test.txt') }}
是Jinja2表达式。
我尝试为jinja2表达式转义双花括号,例如:'{{' get_path('test.txt') '}}'
,但它给出了相同的输出。因此看起来它仍然将其视为ansible变量。我也无法删除dict(cfg
参数类型为dict
)的双引号,因为然后ansible变量将被忽略,并且它使用文字值(如{{ custom_name }}
,而不能替换为实际值)
P.S。 ansible 2.8.5.post0
python version = 3.6.7 (default, Mar 29 2019, 10:38:28) [GCC 5.4.0 20160609]
更新1
由ansible渲染cfg
值并将其作为参数传递给模块后,它应该看起来像这样:
{
'/home/oerp/tmp':
{
'childs': {
'my_child_dirname': {
'rules': [
(
(),
('cmd', [('touch', "{{ get_path('test.txt') }}")])
)
]
}
}
}
}
然后,当模块接收到该值时,它会进一步由jinja2呈现(特别是rules
部分的项。在这种情况下,是touch
命令参数`)。看起来像这样:
{
'/home/oerp/tmp':
{
'childs': {
'my_child_dirname': {
'rules': [
(
(),
('cmd', [('touch', '/home/oerp/tmp/my_child_dirname/test.txt')])
)
]
}
}
}
}
Ansible仅应呈现{{ custom_name }}
,其中{{ get_path('test.txt') }}
应该保留为文字字符串,稍后由我的模块处理。
更新2
看起来似乎是什么问题,我会尽力弄清楚问题出在哪里。
在cfg
参数中,有两个变量。 custom_name
和get_path
。第一个是正常的ansible变量。应该将其视为一体,并用ansible替换为值。 get_path
不是变量。一旦my_buildout
模块接收到呈现的cfg
作为参数,它就是一个变为变量(调用方法)的表达式。
由于这个原因,{{ get_path('test.txt') }}
应该被ansible视为简单字符串,并且不需要转换(例如{{ ansible_ignore_this }}
)。
而且要明确一点,不是整个cfg
就是Jinja表达式。仅('touch', {{ get_path('test.txt') }})
这部分由jinja渲染(当模块接收到整个cfg
时,它将遍历该元组并尝试渲染字符串:"touch"
,然后渲染"{{ get_path('test.txt') }}"
。
如果my_buildout
模块将直接接收cfg
参数(而不使用ansible剧本或其他方法),并且看起来像 UPDATE 1 中的第一个示例中的,就像魅力一样。
答案 0 :(得分:0)
已更新新问题内容
由于cfg
必须是dict
,因此对于该内容使用字符串文字是没有意义的-换句话说,您不想要jinja2小胡子表达式,您想要在变量 处使用变量:
- name: buildout test
my_buildout:
cfg: >-
{{
{
'/home/oerp/tmp': {
'childs': {
custom_name: {
'rules': [
(
(),
('cmd', [('touch', get_path('test.txt') )])
)
]
}
}
}
}
}}