web-dev-qa-db-fra.com

Ansible - avec with_items et lorsque conditionnel à

J'ai un groupe de serveurs qui ont quatre disques physiques sur eux (/ dev/sda, sdb, sdc et sdd). sda a le système d'exploitation installé dessus.

J'ai besoin de formater chaque lecteur sauf sda. Je dois vérifier si chaque disque contient des données. Si c'est le cas, je ne devrais pas le formater.

# 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

Il y a clairement plus d'étapes impliquées dans le formatage de ces disques, mais cela échoue lors de la dernière tâche lors de la création de la table de partitions GPT.

Voici à quoi ça ressemble quand ça marche. Vous verrez que cela échoue à la dernière tâche:

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

Toute idée de comment vérifier le conditionnel base_secondary_partition_{{item}}.stat.exists? Je dois m'assurer que s'il y a des données sur le disque, il ne les formatera pas.

32
hfranco

Vous n'avez pas besoin d'enregistrer votre résultat avec le sel item. Lorsque vous enregistrez le résultat d’une boucle (par exemple, with_items) la valeur enregistrée contiendra une clé results contenant une liste de tous les résultats de la boucle. (Voir docs )

Au lieu de parcourir votre liste de périphériques d'origine, vous pouvez alors parcourir les résultats enregistrés de la première tâche:

- 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

La condition not item | skipped prend en charge les éléments filtrés dans la boucle d'origine (sda) ne seront pas traités.

Bien que cela puisse être une solution à votre problème, votre question est très intéressante. Il semble n'y avoir aucune fonctionnalité eval dans Jinja2. Bien que vous puissiez concaténer des chaînes, vous ne pouvez pas utiliser cette chaîne comme nom de variable pour obtenir sa valeur ...

51
udondan

Vos tâches peuvent être aussi simples que cela ...

- 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
6
yaegashi