如何使用 Ansible 收集有关磁盘的信息

How to gather facts about disks using Ansible

我正在尝试编写一个 Ansible 剧本,它将识别 RHEL 机器上新添加的磁盘。计划是 运行 剧本并在创建新磁盘之前及时缓存磁盘。创建新磁盘后,相同的剧本将再次 运行 并计算磁盘创建前后的差异。

例如,lsblk最初returns如下:

NAME              SIZE  TYPE
sda               100G  disk
├─sda1              1G  part
└─sda2             99G  part
  ├─rhel-root      50G  lvm
  ├─rhel-swap     7.9G  lvm
  └─rhel-home    41.1G  lvm
sr0              1024M  rom

添加8个新磁盘后,lsblk returns:

NAME              SIZE  TYPE
sda               100G  disk
├─sda1              1G  part
└─sda2             99G  part
  ├─rhel-root      50G  lvm
  ├─rhel-swap     7.9G  lvm
  └─rhel-home    41.1G  lvm
sdb              18.6G  disk
sdc              18.6G  disk
sdd              18.6G  disk
sde              18.6G  disk
sdf              18.6G  disk
sdg              18.6G  disk
sdh              18.6G  disk
sdi              18.6G  disk
sr0              1024M  rom

理想情况下,我将能够收集以下形式的初始磁盘列表:

['sda']

并在创建磁盘后收集另一个形式的磁盘列表:

['sda', 'sdb', 'sdc', 'sdd', 'sde', 'sdf', 'sdg', 'sdh', 'sdi']

计算两个列表之间的差异将得出:

['sdb', 'sdc', 'sdd', 'sde', 'sdf', 'sdg', 'sdh', 'sdi']

这是8个新创建的磁盘。

我尽量避免使用 shellcommand 模块调用。

此信息是通过 ansible 的 fact gathering 机制自动收集的。

参见 Variables discovered from systems: Facts

例如:

#!/usr/bin/env ansible-playbook
- name: Lets look at some disks
  hosts: localhost
  become: false
  gather_facts: true
  tasks:
  - name: Output disk information
    debug:
      var: hostvars[inventory_hostname].ansible_devices

如果我们改为在 setup module 上使用 gather_subset 配置,我们可以加快事实收集速度,并且只收集有关系统硬件的信息。

然后我们可以将它与 python keys() 方法和 jinja2 list 过滤器结合起来以产生您想要的输出。

#!/usr/bin/env ansible-playbook
- name: Lets look at some disks
  hosts: localhost
  become: false
  gather_facts: false
  tasks:
  - name: Collect only facts about hardware
    setup:
      gather_subset:
      - hardware

  - name: Output disks
    debug:
      var: hostvars[inventory_hostname].ansible_devices.keys() | list

也可以使用 [defaults] 部分中的 gather_subset 键配置在 ansible 配置文件 ansible.cfg 中收集哪些事实。

编辑: 如果你想过滤掉各种磁盘类型,最简单的方法是使用 map('regex_search', '*search string*') 来提取你想要的值。您可以通过 select('string').

删除空值

例如,磁盘格式为 sd*:

#!/usr/bin/env ansible-playbook
- name: Lets look at some disks
  hosts: localhost
  become: false
  gather_facts: false
  tasks:
  - name: Collect only facts about hardware
    setup:
      gather_subset:
      - hardware

  - name: Output disks
    debug:
      var: hostvars[inventory_hostname].ansible_devices.keys() | map('regex_search', 'sd.*') | select('string') | list

添加任何磁盘后尝试此命令,您可以看到更改:

for d in /sys/class/scsi_device/* ; do echo 1 > $d/device/rescan; done
- name: Check disk size
  debug:
    msg: "{{ ansible_devices[item].size }}"
  loop: "{{ ansible_devices.keys()|list }}"