【问题标题】:Ansible - Using or conditional in when:Ansible - 在以下情况下使用或有条件:
【发布时间】:2018-06-02 14:55:14
【问题描述】:

我在 tasks/main.yml

中有以下代码
---
- name: Check if service exists.
  shell: "systemctl status {{ service }}"
  ignore_errors: yes
  register: service_exists

- name: Enable service and start if it exists.
  systemd:
    name: "{{ service }}"
    state: started
    enabled: true
  when: "could not be found" not in service_exists.stderr' or '"Failed to get properties" not in service_exists.stderr' or '"not-found" not in service_exists.stderr'

我在 configure-services.yml

中有以下代码
---
- hosts: localhost
  become: true
  gather_facts: yes
  tasks:
    - include: tasks/main.yml
      with_items: "{{ services }}"
      loop_control:
        loop_var: service

但是在运行 playbook 时出现以下错误。

fatal: [localhost]: FAILED! => {"reason": "Syntax Error while loading YAML.\n  did not find expected key\n\nThe error appears to have been in '/home/adambirds/Development/ansible-playbooks/system-services/tasks/main.yml': line 12, column 11, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n    enabled: true\n  when:''\"could not be found\" not in service_exists.stderr' or '\"Failed to get properties\" not in service_exists.stderr' or '\"not-found\" not in service_exists.stderr''\n          ^ here\nWe could be wrong, but this one looks like it might be an issue with\nunbalanced quotes.  If starting a value with a quote, make sure the\nline ends with the same set of quotes.  For instance this arbitrary\nexample:\n\n    foo: \"bad\" \"wolf\"\n\nCould be written as:\n\n    foo: '\"bad\" \"wolf\"'\n"}

我认为问题在于我的 when: 语句,我的目标是在 service_exists.stderr 中未出现以下任何内容时运行该任务:

could not be found
Failed to get properties
not-found

在使用下面@tinita 的建议并将 tasks/main.yml 更改为以下内容后:

---
- name: Check if service exists.
  shell: "systemctl status {{ service }}"
  ignore_errors: yes
  register: service_exists

- name: Enable service and start if it exists.
  systemd:
    name: "{{ service }}"
    state: started
    enabled: true
  when: >
    "could not be found" not in service_exists.stderr
    or "Failed to get properties" not in service_exists.stderr
    or "not-found" not in service_exists.stderr

运行 playbook 时出现以下错误:

TASK [Check if service exists.] ***************************************************************************************************************************************************************
fatal: [localhost]: FAILED! => {"changed": true, "cmd": "systemctl status mariadb.service", "delta": "0:00:00.004881", "end": "2018-06-02 16:28:18.849473", "msg": "non-zero return code", "rc": 4, "start": "2018-06-02 16:28:18.844592", "stderr": "Unit mariadb.service could not be found.", "stderr_lines": ["Unit mariadb.service could not be found."], "stdout": "", "stdout_lines": []}
...ignoring

TASK [Enable service and start if it exists.] *************************************************************************************************************************************************
fatal: [localhost]: FAILED! => {"changed": false, "msg": "Could not find the requested service mariadb.service: host"}
        to retry, use: --limit @/home/adambirds/Development/ansible-playbooks/system-services/configure-services.retry

PLAY RECAP ************************************************************************************************************************************************************************************
localhost                  : ok=20   changed=1    unreachable=0    failed=1

【问题讨论】:

  • 错字。您的引号不匹配,并且引号中有 ' or '。此外,如果您以 " 开头,则必须引用整个表达式。

标签: ansible conditional yaml ansible-tower ansible-awx


【解决方案1】:

如果您的值以引号开头,那是 YAML 引号,但您希望引号成为 jinja 表达式的一部分:

when: "could not be found" not in service_exists.stderr' or '"Failed to get properties" not in service_exists.stderr' or '"not-found" not in service_exists.stderr'

所以该行是无效的 YAML,因为您必须引用整个值。 当您的值带有混合引号时,最好使用 YAML 块标量。

我认为这应该做你想要的:

when: >
  "could not be found" not in service_exists.stderr
  or "Failed to get properties" not in service_exists.stderr
  or "not-found" not in service_exists.stderr

这是一个所谓的“折叠块标量”。这些线只是折叠在一起形成一条线。您也可以在这里使用 Literal Block Scalar,它保留换行符,因为我相信换行符在 Jinja 表达式中并不重要。

您可以看到表达式中不需要单引号,因此另一种解决方案是使用单引号作为 YAML 引号:

when: '
  "could not be found" not in service_exists.stderr
  or "Failed to get properties" not in service_exists.stderr
  or "not-found" not in service_exists.stderr'

虽然我更喜欢块标量,因为我根本不需要关心引用。

您可能想阅读我关于 YAML 引用的文章: http://blogs.perl.org/users/tinita/2018/03/strings-in-yaml---to-quote-or-not-to-quote.html

它很长,但应该涵盖几乎所有你需要知道的情况。

【讨论】:

  • 感谢您,折叠块标量修复了该错误,但它不正确匹配,请参阅运行手册的日志。我将编辑我的附加帖子。
  • 原始问题已使用新日志进行了编辑。
  • 我修正了你的语法错误,而不是你的逻辑错误。我向您解释了两种引用方式,但我什至没有得到支持?
【解决方案2】:

通过将 when: 语句更改为以下内容,实际上修复了错误:

when: not ("could not be found" in service_exists.stderr or "not-found" in service_exists.stderr or "Failed to get properties" in service_exists.stderr)

【讨论】:

    猜你喜欢
    • 2014-08-03
    • 1970-01-01
    • 2020-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-23
    • 2013-01-10
    相关资源
    最近更新 更多