如何使用Ansible识别安装了操作系统的硬盘分区
Ansible校验/dev/sda未安装操作系统的正确Playbook实现
原写法存在的问题
- 遍历所有sd前缀磁盘,导致安装了系统的/dev/sdb被误判触发失败
- 系统存在性判断逻辑错误:
item.value.partitions is search('ubuntu*')是对分区字典对象做字符串匹配,永远不会生效 - 无分区磁盘的校验逻辑缺失:当分区长度为0时,
item.value.partitions | length != 0条件不成立,直接跳过了无分区场景的校验
场景疑问解答
你提到的无分区安装操作系统的场景确实存在,可以直接将整块块设备格式化后挂载为系统根目录等核心路径,不需要创建分区表,仅在非常规部署场景下出现,常规安装OS都会创建对应分区。
正确实现方案
首先明确校验规则:仅校验/dev/sda,只要检测到sda上有系统核心路径挂载就报错,否则任务通过,完全覆盖你要求的两类合法场景:
- /dev/sda无分区且未安装OS
- /dev/sda有分区但所有分区均未安装OS
Playbook代码
- name: 校验/dev/sda无操作系统部署 hosts: 你的目标主机组 gather_facts: yes tasks: - name: 提取/dev/sda的分区绝对路径列表 set_fact: sda_partitions: "{{ ansible_devices.sda.partitions | dict2items | map(attribute='key') | map('regex_replace', '^', '/dev/') | list }}" when: "'sda' in ansible_devices" - name: 校验/dev/sda未安装操作系统 fail: msg: "/dev/sda 上存在已安装的操作系统,不符合要求" when: - "'sda' in ansible_devices" - > # 情况1:整块sda无分区,直接被挂载为系统核心路径 (ansible_devices.sda.partitions | length == 0 and ansible_mounts | selectattr('device', 'equalto', '/dev/sda') | selectattr('mount', 'in', ['/', '/boot', '/boot/efi', '/usr']) | list | length > 0) or # 情况2:sda存在分区,任意分区被挂载为系统核心路径 (ansible_devices.sda.partitions | length > 0 and sda_partitions | intersect(ansible_mounts | selectattr('mount', 'in', ['/', '/boot', '/boot/efi', '/usr']) | map(attribute='device') | list) | list | length > 0)
逻辑说明
- 仅针对/dev/sda做校验,不会影响系统所在的/dev/sdb
- 覆盖了无分区直接装系统的极端场景和有分区装系统的常规场景
- 系统存在性通过是否挂载了系统核心路径判断,比匹配操作系统名称更准确,兼容所有Linux发行版的检测
内容的提问来源于stack exchange,提问作者hago
相关产品推荐
相关产品推荐

