如果列表为空,Ansible 如何跳过循环

ate*_*feh 4 variables yaml loops jinja2 ansible

我正在运行 Ansible 并尝试完成此任务。我已经将变量“docker_registries”的默认值定义为一个空列表:docker_registries: []我注意到如果列表为空,我在运行 ansible playbook 时会出错。这是我得到的错误:

致命:[***.cloudapp.azure.com]:失败!=> {"msg": "传递给 'loop' 的无效数据,它需要一个列表,取而代之的是:无。提示:如果您只传递了一个元素的列表/字典,请尝试将 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}}"
Run Code Online (Sandbox Code Playgroud)

我试图将循环更改为, loop: "{{ lookup(docker_registries, {'skip_missing': True})}}" 但出现错误

任务执行过程中发生异常。要查看完整的回溯,请使用 -vvv。错误是:AttributeError:'NoneType' 对象没有属性 'lower' 致命:[***.cloudapp.azure.com]:失败!=> {"msg": "模块执行期间意外失败。", "stdout": ""}

我对此很陌生。任何人都可以帮忙吗?

β.ε*_*.βε 9

您可以将该when语句iterableJinja 测试结合使用。
因为,好吧,如果你想循环你的变量,那么它应该是可迭代的。

- 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
Run Code Online (Sandbox Code Playgroud)

根据变量的内容,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 [] }}"
Run Code Online (Sandbox Code Playgroud)

还要注意,字符串在 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 [] }}"
Run Code Online (Sandbox Code Playgroud)