Невозможно - использовать with_items и при условии

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

Мне нужно отформатировать каждый диск, кроме 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

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

Ответы

Ответ 1

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

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

- 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 not item | skipped заботится о том, чтобы элементы, отфильтрованные в исходном цикле (sda), не обрабатывались.

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

Ответ 2

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

- 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