2015-08-25 2 views
19

У меня есть группа серверов, на которых есть четыре физических диска (/ dev/sda, sdb, sdc и sdd). На нем установлена ​​ОС.Ansible - using with_items и при условии

Мне нужно отформатировать каждый диск, кроме sda. Мне нужно проверить, есть ли у каждого диска данные на нем. Если это так, я не должен отформатировать его.

# This will get all physical disks (sda, sdb, sdc, etc) and assign them to disk_var 
- name: Get disks 
    set_fact: disk_var="{{hostvars[inventory_hostname]["ansible_devices"].keys()|list}}" 

- name: Check if the disk is partitioned and also ignore sda 
    stat: path=/dev/{{item}}1 
    with_items: disk_var 
    when: item != 'sda' 
    register: base_secondary_partition_{{item}} 

- name: Create GPT partition table 
    command: /sbin/parted -s /dev/{{item}} mklabel gpt 
    with_items: disk_var 
    when: item != 'sda' and base_secondary_partition_{{item}}.stat.exists == false 

В форматировании этих дисков явно больше шагов, но при последней задаче при создании таблицы разделов GPT не удается выполнить последнюю задачу.

Вот как он выглядит, когда он работает. Вы увидите, что она не в последнюю задачу:

TASK: [role | Get disks] ****************************************************** 
ok: [server1.com] 

TASK: [role | Check if the disk is partitioned] ******************************* 
skipping: [server1.com] => (item=sda) 
ok: [server1.com] => (item=sdd) 
ok: [server1.com] => (item=sdb) 
ok: [server1.com] => (item=sdc) 

TASK: [role | Create GPT partition table] ************************************* 
fatal: [server1.com] => error while evaluating conditional: base_secondary_partition_sdd.stat.exists == false 

FATAL: all hosts have already failed -- aborting 

Любая идея, как я могу проверить условную ? Мне нужно убедиться, что если есть данные на диске, он не будет форматировать его.

ответ

35

Вам не нужно регистрировать результат с помощью соли item. Когда вы регистрируете результат цикла (например, with_items), зарегистрированное значение будет содержать ключ results, который содержит список всех результатов цикла. (См docs)

Вместо цикла по первоначальному списку устройств, вы можете перебирает зарегистрированные результаты первой задачи, тогда:

- name: Check if the disk is partitioned and also ignore sda 
    stat: path=/dev/{{item}}1 
    with_items: disk_var 
    when: item != 'sda' 
    register: device_stat 

- name: Create GPT partition table 
    command: /sbin/parted -s /dev/{{ item.item }} mklabel gpt 
    with_items: device_stat.results 
    when: 
    - not item | skipped 
    - item.stat.exists == false 

Условия not item | skipped заботится о том, что элементы, которые были отфильтрованы в исходный цикл (sda) не будет обрабатываться.

Хотя это может быть решением вашей проблемы, ваш вопрос очень интересный. В Jinja2 нет функции eval. В то время как вы можете конкатенации строк, вы не можете использовать эту строку в качестве имени переменной, чтобы получить его значение ...

+2

Вы должны использовать '{{ item.item}} 'для второй задачи. – yaegashi

+0

Правильно, спасибо за определение! :) – udondan

+0

Отлично! Это должно быть в недоступных примерах. – onnimonni

4

Ваши задачи могут быть столь же просто, как это ...

- stat: 
    path: /dev/{{item}}1 
    with_items: ansible_devices.keys() 
    when: item != 'sda' 
    register: stats 
- command: /sbin/parted -s /dev/{{item.item}} mklabel gpt 
    with_items: stats.results 
    when: item.stat | default(false) and item.stat.exists 
Смежные вопросы