我正在运行 Ansible,并尝试让这项任务发挥作用。我已将变量“docker_registries”的默认值定义为空列表:
docker_registries: []
我注意到,如果列表为空,运行 ansible playbook 时会出现错误。这是我得到的错误:
致命:[***.cloudapp.azure.com]:失败! => {“msg”:“传递给“循环”的数据无效,它需要一个列表,取而代之的是:无。提示:如果您传递了仅包含一个元素的列表/字典,请尝试将wantlist=True添加到您的查找调用中或使用 q/query 而不是查找。"}
我试图添加一个条件,即如果“docker_registries”为空,则任务将继续,而不会引发错误。 这是此任务的代码:
- name: Log into additional docker registries, when required
command: docker login -u {{item.username}} -p {{item.password}} {{item.server}}
become: true
loop: "{{docker_registries}}"
我尝试将循环更改为
loop: "{{ lookup(docker_registries, {'skip_missing': True})}}"
但我收到错误
任务执行过程中出现异常。想要看完整的 回溯,使用 -vvv。错误是:AttributeError:'NoneType'对象 没有属性“较低”致命: [***.cloudapp.azure.com]:失败! => {“msg”:“模块执行期间意外失败。”,“stdout”:“”}
我对此还很陌生。有人可以帮忙吗?
when
语句 与 iterable
Jinja 测试结合使用。- name: Log into additional docker registries, when required
command: docker login -u {{ item.username }} -p {{ item.password }} {{ item.server }}
become: true
loop: "{{ docker_registries }}"
when: docker_registries is iterable
根据变量的内容,when条件仍然无法解决问题,因为将首先考虑传递给
loop
的数据的有效性。
现在,您可以在循环声明本身中使用条件表达式来解决这个问题:
- name: Log into additional docker registries, when required
command: docker login -u {{ item.username }} -p {{ item.password }} {{ item.server }}
become: true
loop: "{{ docker_registries if docker_registries is iterable else [] }}"
还要注意,Python 中的字符串是可迭代的,简单地说,它们是字符列表。
所以你可能想去:
- name: Log into additional docker registries, when required
command: docker login -u {{ item.username }} -p {{ item.password }} {{ item.server }}
become: true
loop: "{{ docker_registries if docker_registries is iterable and docker_registries is not string else [] }}"
谢谢大家。我的 group_vars 文件中有一行,我已注释掉所有 docker_registries 用户名和密码等,但我没有注释
docker_registries:
行本身。这就是为什么我得到 None 而不是空列表。
Ansible 和 Jinja 有一些令人惊讶的行为:
loop
表达式在when
条件之前进行计算,所以这没有帮助。
{{ none | default('something') }}
评估为无。
{{ none | default('something', true) }}
评估为“某物”。
考虑到这一点,解决方案就很简单了:
- name: Log into additional docker registries, when required
command: docker login -u {{item.username}} -p {{item.password}} {{item.server}}
become: true
loop: "{{ docker_registries | default([], true) }}"
还有:
{{ '' is iterable }}
返回 true,因此如果可能的话,您还必须检查字符串。