У меня определен этот playbook:
---
- hosts: "{{ target }}"
tasks:
- name: buildout test
my_buildout:
cfg: "{
'/home/oerp/tmp':
{
'childs': {
'{{ custom_name }}': {
'rules': [
(
(),
('cmd', [('touch', {{ get_path('test.txt') }})])
)
]
}
}
}
}"
Запуск моей playbook с: 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 }}
isпеременная ansible, где {{ get_path('test.txt') }}
, является выражением Jinja2.
Я попытался избежать двойных фигурных скобок для выражения jinja2, например: '{{' get_path('test.txt') '}}'
, но он выдает тот же результат. Так что, похоже, он все еще видит это как переменную типа ANSIBLE. Я также не могу удалить перенос двойных кавычек для dict (тип аргумента cfg
равен dict
), потому что тогда игнорируемые переменные игнорируются, и он использует буквальное значение (например, {{ custom_name }}
, без замены на фактическое значение)
PS ansible 2.8.5.post0
python version = 3.6.7 (default, Mar 29 2019, 10:38:28) [GCC 5.4.0 20160609]
ОБНОВЛЕНИЕ 1
После того, как значение cfg
будет обработано ansible и передано модулю в качестве аргумента, ожидается, чтовыглядит следующим образом:
{
'/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. get_path
не является переменной типа. Это выражение становится переменным (вызов метода), когда модуль my_buildout
получает обработанный cfg
в качестве аргумента.
По этой причине {{ get_path('test.txt') }}
следует рассматривать как простую строку с помощью ansible и без преобразованиянеобходимо (например, {{ ansible_ignore_this }}
). И чтобы прояснить это, не все cfg
является выражением дзиндзя. Только ('touch', {{ get_path('test.txt') }})
эта часть отображается jinja (когда модуль получает целое cfg
, он перебирает этот кортеж и пытается отобразить строки: "touch"
, а затем "{{ get_path('test.txt') }}"
.
Если модуль my_buildout
получит аргумент cfg
напрямую (без использования ansible playbook или чего-либо еще) и будет выглядеть как в первом примере в UPDATE 1 , тогда он будет работать как шарм.