Ansible / Jinja2 意外的模板类型错误

45次阅读
没有评论

问题描述

在使用Ansible和Jinja2时遇到了一个问题。他尝试从一个或多个异步任务中获取一个字典,然后根据其id将其收集为一个列表,并使用async_status在生成的id列表上运行等待任务。但是他遇到了一个”Unexpected templating type error”错误,错误信息是”Jinja “sync_do_list() takes 1 positional argument but 2 were given”。他已经尝试了很多方法,但是无法解决这个问题。
以下是他的代码:

loop: "{{ (task_variable.results|default({}, true)) | selectattr('ansible_job_id') | map(attribute='ansible_job_id') | list([]) }}"

其中一些等待任务会将多个test_variables相加,如果有多个异步任务需要完成才能继续执行。一些生成task_variables的任务被包装在whens中,因此可能永远不会生成一个变量,这就是为什么我要使用这样的循环来处理它们的原因。
代码在我的工作笔记本上,所以很难将其复制过来,但这是唯一真正重要的部分,希望能得到帮助,谢谢。
编辑:
为了解决这个错误,我不得不将list([])更改为list
然而,最终结果已经改变为:

loop: "{{ [task1, task2, task3, task4] | selectattr('results', 'defined') | map(attribute='results') | selectattr('ansible_job_id', 'defined') | map(attribute='ansible_job_id') | list }}"

其中任何一个任务都可以为空或未定义,并且它们将被正确过滤,但即使只检查一个任务,它们也必须保持为列表。
通过将结果传递给async_status,可以避免通过when语句等来检查哪些是定义的和哪些是未定义的。

解决方案

请注意以下操作注意版本差异及修改前做好备份。

方案1

根据用户提供的代码,我们可以看到问题出在list([])这一部分。将其更改为list即可解决这个特定的错误。
以下是修改后的代码:

loop: "{{ (task_variable.results|default({}, true)) | selectattr('ansible_job_id') | map(attribute='ansible_job_id') | list }}"

方案2

根据用户提供的最终代码,我们可以看到他将list([])更改为了list,并且对代码进行了一些其他的修改。这个修改后的代码可以正确地过滤掉未定义的任务,并将结果作为列表传递给async_status
以下是修改后的代码:

loop: "{{ [task1, task2, task3, task4] | selectattr('results', 'defined') | map(attribute='results') | selectattr('ansible_job_id', 'defined') | map(attribute='ansible_job_id') | list }}"

请注意,这个代码中的task1, task2, task3, task4应该替换为实际的任务变量。

方案3

如果你仍然遇到问题,可能是因为变量未定义。你可以在使用变量之前添加一个条件判断,以确保变量已定义。以下是一个示例:

loop: "{{ (task_variable.results|default({}, true)) | selectattr('ansible_job_id') | map(attribute='ansible_job_id') | list if task_variable.results is defined else [] }}"

这个代码将在task_variable.results已定义时使用变量,否则使用一个空列表。
希望这些解决方案能帮助到你解决问题。如果还有其他问题,请随时提问。

正文完