fix(partitioning): resolve vmware disks by scsi target instead of the sdX letter
This commit is contained in:
@@ -538,6 +538,8 @@ When `hypervisor.type: vmware` uses the `vmware_tools` connection:
|
||||
|
||||
`system.disks[0]` is the OS disk (no `mount.path`). Additional entries define data disks.
|
||||
|
||||
On VMware, `device` is resolved on the target from the SCSI address instead: entry N is the disk at target N on the first SCSI controller (N+1 from index 7 on, since unit 7 is reserved). The kernel's `sdX` order is not stable between the install environment and the installed system, so a letter-derived path can point at another disk.
|
||||
|
||||
| Key | Type | Description |
|
||||
| ------------- | ------ | ------------------------------------------------------ |
|
||||
| `size` | number | Disk size in GB (required for virtual) |
|
||||
|
||||
61
roles/partitioning/tasks/_resolve_vmware_disks.yml
Normal file
61
roles/partitioning/tasks/_resolve_vmware_disks.yml
Normal file
@@ -0,0 +1,61 @@
|
||||
---
|
||||
# The virtualization role attaches system.disks to SCSI controller 0 in list order, and
|
||||
# vSphere never gives a disk unit 7 (the controller's own address). The kernel's sdX order
|
||||
# is not that order and differs between the install environment and the installed OS, so
|
||||
# a disk derived as /dev/sd<letter of its index> can be the wrong one. Resolve by target.
|
||||
- name: List disks with their SCSI address
|
||||
ansible.builtin.command: lsblk -dnpo NAME,TYPE,HCTL
|
||||
register: partitioning_vmware_lsblk
|
||||
changed_when: false
|
||||
|
||||
- name: Map SCSI targets to devices
|
||||
vars:
|
||||
_scsi: >-
|
||||
{%- set out = [] -%}
|
||||
{%- for line in partitioning_vmware_lsblk.stdout_lines -%}
|
||||
{%- set p = line.split() -%}
|
||||
{%- if (p | length) == 3 and p[1] == 'disk' and p[2] is match('^\d+:0:\d+:0$') -%}
|
||||
{%- set _ = out.append({'name': p[0], 'host': p[2].split(':')[0], 'target': p[2].split(':')[2]}) -%}
|
||||
{%- endif -%}
|
||||
{%- endfor -%}
|
||||
{{ out }}
|
||||
ansible.builtin.set_fact:
|
||||
partitioning_vmware_hosts: "{{ _scsi | map(attribute='host') | unique | list }}"
|
||||
partitioning_vmware_targets: "{{ _scsi | items2dict(key_name='target', value_name='name') }}"
|
||||
partitioning_vmware_target_count: "{{ _scsi | length }}"
|
||||
|
||||
- name: Assert the system disks sit on one SCSI controller with unique targets
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- partitioning_vmware_hosts | length == 1
|
||||
- partitioning_vmware_targets | length == partitioning_vmware_target_count | int
|
||||
fail_msg: >-
|
||||
Expected every disk on one SCSI controller with unique targets, got
|
||||
{{ partitioning_vmware_lsblk.stdout_lines | select('search', ' disk ') | list }}.
|
||||
quiet: true
|
||||
|
||||
- name: Assert each system disk has a device at its SCSI target
|
||||
vars:
|
||||
_target: "{{ (idx if idx < 7 else idx + 1) | string }}"
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- _target in partitioning_vmware_targets
|
||||
fail_msg: "system.disks[{{ idx }}] ({{ item.size }} GB) expects a disk at SCSI target {{ _target }}, none found."
|
||||
quiet: true
|
||||
loop: "{{ system_cfg.disks }}"
|
||||
loop_control:
|
||||
index_var: idx
|
||||
label: "{{ idx }}"
|
||||
|
||||
- name: Point system disks and install_drive at the resolved devices
|
||||
vars:
|
||||
_disks: >-
|
||||
{%- set out = [] -%}
|
||||
{%- for d in system_cfg.disks -%}
|
||||
{%- set dev = partitioning_vmware_targets[(loop.index0 if loop.index0 < 7 else loop.index0 + 1) | string] -%}
|
||||
{%- set _ = out.append(d | combine({'device': dev, 'partition': dev ~ '1'})) -%}
|
||||
{%- endfor -%}
|
||||
{{ out }}
|
||||
ansible.builtin.set_fact:
|
||||
system_cfg: "{{ system_cfg | combine({'disks': _disks}) }}"
|
||||
install_drive: "{{ _disks[0].device }}"
|
||||
@@ -1,4 +1,10 @@
|
||||
---
|
||||
- name: Resolve VMware disks by SCSI target
|
||||
when:
|
||||
- hypervisor_type == "vmware"
|
||||
- system_cfg.type == "virtual"
|
||||
ansible.builtin.include_tasks: _resolve_vmware_disks.yml
|
||||
|
||||
- name: Detect system sizing
|
||||
ansible.builtin.include_tasks: _detect_sizing.yml
|
||||
|
||||
|
||||
Reference in New Issue
Block a user