Неспособность: понимание составного условного выражения

Рассмотрим эту тривиальную загружаемую книгу и соответствующий результат ниже. Зачем Выполняется ли задача 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   

Edited: Список изменений, основанных на ответе tedder42 ниже, если кто-то отправляется домой.

1) Изменено

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

to

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

2) изменить

when: is_ubuntu and ansible_lsb.major_release|int < 14 

to

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

Вот и все!

-jk

Ответы

Ответ 1

TL;DR: ваша переменная выводится как строка, а не вычисляется. Исправьте оценку с помощью 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"
}

Оценка

Насколько я знаю, вы не можете оценить до логического. Как правило, это делается путем разворачивания переменной (размещение ее в каждом "когда" ). Тем не менее, это может быть выполнено, поскольку вы можете получить логическое значение в виде строки, а затем передать его в bool как указано на странице переменных, не подлежащей переходу (поиск "логическое значение" )).

- 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 version_compare. Использование остается в качестве упражнения для читателя.