问题描述
在使用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
已定义时使用变量,否则使用一个空列表。
希望这些解决方案能帮助到你解决问题。如果还有其他问题,请随时提问。