Ansible:理解复合条件语句时

问题描述 投票:14回答:1

考虑下面这个简单的ansible剧本和相关的输出。为什么任务5被执行?这些任务是针对debian运行的。任务1按预期失败。那么,为什么和'ansible_lsb.major_release | int <14'一起使它成为真的呢?这是否与运算符优先级有关?

-JK

---
- name: These tests run against debian
  hosts: frontend001
  vars:
    - bcbio_dir: /mnt/bcbio
    - is_ubuntu: "'{{ansible_distribution}}' == 'Ubuntu'"
    - is_debian: "'{{ansible_distribution}}' == 'Debian'"
  tasks:
    - name: 1. Expect skip because test is_ubuntu
      debug: msg="ansible distribution - {{ansible_distribution}}, release - {{ansible_distribution_release}}, {{ ansible_lsb.major_release }}"
      when: is_ubuntu 

    - name: 2. Expect to print msg because test is_debian
      debug: msg="ansible distribution - {{ansible_distribution}}, release - {{ansible_distribution_release}}, {{ ansible_lsb.major_release }}"
      when: is_debian

    - name: 3. Expect to print msg because release 7 of wheezy
      debug: msg="ansible distribution - {{ansible_distribution}}, release - {{ansible_distribution_release}}, {{ ansible_lsb.major_release }}"
      when:  ansible_lsb.major_release|int < 14

    - name: 4. Expect to print msg because true and true is true
      debug: msg="ansible distribution - {{ansible_distribution}}, release - {{ansible_distribution_release}}, {{ ansible_lsb.major_release }}"
      when: is_debian and ansible_lsb.major_release|int < 14

    - name: 5. Expect to skip because false and true is false
      debug: msg="ansible distribution - {{ansible_distribution}}, release - {{ansible_distribution_release}}, {{ ansible_lsb.major_release }}"
      when: is_ubuntu and ansible_lsb.major_release|int < 14 


$ ansible-playbook -i ~/.elasticluster/storage/ansible-inventory.jkcluster  zbcbio.yml 

PLAY [These tests run against debian] ***************************************** 

GATHERING FACTS *************************************************************** 
ok: [frontend001]

TASK: [1. Expect skip because test is_ubuntu] ********************************* 
skipping: [frontend001]

TASK: [2. Expect to print msg because test is_debian] ************************* 
ok: [frontend001] => {
    "msg": "ansible distribution - Debian, release - wheezy, 7"
}

TASK: [3. Expect to print msg because release 7 of wheezy] ******************** 
ok: [frontend001] => {
    "msg": "ansible distribution - Debian, release - wheezy, 7"
}

TASK: [4. Expect to print msg because true and true is true] ****************** 
ok: [frontend001] => {
    "msg": "ansible distribution - Debian, release - wheezy, 7"
}

TASK: [5. Expect to skip because false and true is false] ********************* 
ok: [frontend001] => {
    "msg": "ansible distribution - Debian, release - wheezy, 7"
}

PLAY RECAP ******************************************************************** 
frontend001                : ok=5    changed=0    unreachable=0    failed=0   

编辑:如果有人在家里跟踪,请根据tedder42的答案列出更改。

1)改变了

- is_ubuntu: "'{{ansible_distribution}}' == 'Ubuntu'"

- is_ubuntu: "{{ansible_distribution == 'Ubuntu'}}"

2)改变

when: is_ubuntu and ansible_lsb.major_release|int < 14 

when: is_ubuntu|bool and ansible_lsb.major_release|int < 14 

那就做到了!

-JK

ansible ansible-playbook
1个回答
14
投票

TLDR:您的变量以字符串形式输出,未进行评估。使用jinja2修复评估,然后将var过滤为|bool

调试

你只缺少一件事来调试这个问题。这是我在本地OSX盒子上运行的内容:

- name: stackoverflow 26188055
  hosts: local
  vars:
    - bcbio_dir: /mnt/bcbio
    - is_ubuntu: "'{{ansible_distribution}}' == 'Ubuntu'"
    - is_debian: "'{{ansible_distribution}}' == 'Debian'"
  tasks:
    - debug: var=is_ubuntu
    - debug: var=is_debian
    - debug: msg="this shows the conditional passes even though it shouldnt"
      when: is_ubuntu and true

并输出:

TASK: [debug var=is_ubuntu] *************************************************** 
ok: [127.0.0.1] => {
    "is_ubuntu": "'MacOSX' == 'Ubuntu'"
}

TASK: [debug var=is_debian] *************************************************** 
ok: [127.0.0.1] => {
    "is_debian": "'MacOSX' == 'Debian'"
}

TASK: [debug msg="this shows the conditional passes even though it shouldnt"] *** 
ok: [127.0.0.1] => {
    "msg": "this shows the conditional passes even though it shouldnt"
}

评估

据我所知,你无法真正评估为布尔值。通常,这是通过展开变量(将其置于每个“when”)来完成的。但是,它可以实现,因为您可以将布尔值作为字符串,然后将其转换为bool as hinted on the Variables ansible page(搜索“布尔值”)。

- name: stackoverflow 26188055
  hosts: local
  vars:
    - bcbio_dir: /mnt/bcbio
    - is_ubuntu: "{{ansible_distribution == 'Ubuntu'}}"
    - is_debian: "{{ansible_distribution == 'Debian'}}"
  tasks:
    - debug: var=is_ubuntu
    - debug: var=is_debian
    - debug: msg="this shows the conditional passes even though it shouldnt"
      when: is_ubuntu|bool and true

这是输出。

TASK: [debug var=is_ubuntu] *************************************************** 
ok: [127.0.0.1] => {
    "is_ubuntu": "False"
}

TASK: [debug var=is_debian] *************************************************** 
ok: [127.0.0.1] => {
    "is_debian": "False"
}

TASK: [debug msg="this shows the conditional passes even though it shouldnt"] *** 
skipping: [127.0.0.1]

版本比较过滤器

请注意,您可能想要利用Ansible's version_compare filter。用法留给读者练习。

© www.soinside.com 2019 - 2024. All rights reserved.