【问题标题】:Ansible - using with_items and when conditional toAnsible - 使用 with_items 和条件时
【发布时间】:2015-08-25 21:37:14
【问题描述】:

我有一堆服务器,上面有四个物理驱动器(/dev/sda、sdb、sdc 和 sdd)。 sda 上安装了操作系统。

我需要格式化除 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 吗?我需要确保如果驱动器上有数据,它不会格式化它。

【问题讨论】:

    标签: ansible


    【解决方案1】:

    您无需使用item salt 注册您的结果。当您注册循环的结果(例如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 功能。虽然您可以连接字符串,但您不能将该字符串用作变量名来获取其值...

    【讨论】:

    • 第二个任务你应该使用{{item.item}}
    • 太棒了!这应该在ansible示例中。
    • not item | skipped 在更新的 ansible 版本中会出现错误。我不知道您是否可以在过滤表达式上运行类似 not 的函数,并且仅在实际跳过时才定义跳过。无论如何,我最终做了item.skipped is not defined or item.skipped == false
    • 在 Ansible >= v2.2 中,您需要使用 with_items: "{{ device_stat.results }}" 才能使其工作。
    • not item | skipped 给出此警告“[弃用警告]:不推荐使用测试作为过滤器。使用 result|skipped 代替 result is skipped。此功能将在版本 2.9 中删除。弃用警告可以通过在 ansible.cfg 中设置 deprecation_warnings=False 来禁用。”这应该是更易读的item is not skipped
    【解决方案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
    

    【讨论】:

      猜你喜欢
      • 2015-09-17
      • 2015-06-06
      • 2018-02-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多