diff --git a/ansible/roles/wipe-disks/library/blockdevice_info.py b/ansible/roles/wipe-disks/library/blockdevice_info.py new file mode 100644 index 000000000..4a109283f --- /dev/null +++ b/ansible/roles/wipe-disks/library/blockdevice_info.py @@ -0,0 +1,74 @@ +#!/usr/bin/python3 + +DOCUMENTATION = ''' +--- +module: blockdevice_info +short_description: Returns information about block devices +version_added: "N/A" +description: + - "Returns information about block devices" +author: + - Will Szumski +''' + +EXAMPLES = ''' +- name: Retrieve information about block devices + blockdevice_info: + become: true + register: result +''' + +RETURN = ''' +umounted: + description: A list of all umounted block devices. + type: list + returned: always +''' + +import json + +from ansible.module_utils.basic import AnsibleModule + +def _has_mounts(device): + if device["mountpoint"]: + return True + for child in device.get("children", []): + if _has_mounts(child): + return True + return False + +def unmounted(module, lsblk): + result = [] + for device in lsblk.get("blockdevices", []): + if not _has_mounts(device) and device["type"] == 'disk': + result.append(device["name"]) + return result + +def run_module(): + # The module takes no argumnets. + module_args = dict() + + result = dict( + changed=False, + unmounted=[] + ) + + module = AnsibleModule( + argument_spec=module_args, + supports_check_mode=True + ) + + _rc, stdout, _stderr = module.run_command("lsblk -J") + lsblk = json.loads(stdout) + + result['unmounted'] = unmounted(module, lsblk) + + module.exit_json(**result) + + +def main(): + run_module() + + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/ansible/roles/wipe-disks/tasks/main.yml b/ansible/roles/wipe-disks/tasks/main.yml index e88177a7f..def075ca3 100644 --- a/ansible/roles/wipe-disks/tasks/main.yml +++ b/ansible/roles/wipe-disks/tasks/main.yml @@ -14,13 +14,9 @@ update_cache: "{{ True if ansible_facts.os_family == 'Debian' else omit }}" become: True -- name: Check for unmounted block devices - shell: > - lsblk -i -o NAME,MOUNTPOINT | awk \ - '/^ *[|`]-/ && NF > 1 { mounts[master_dev] = mounts[master_dev] $2 " " } - /^(nvme|sd|vd)/ && NF == 1 { master_dev = $1; mounts[master_dev] = "" } - END { for (dev in mounts) if (mounts[dev] == "") print dev }' - register: unmounted_devices +- name: Gather blockdevice facts + blockdevice_info: + register: block_devices changed_when: False - name: Ensure that all unmounted block devices have LVM state removed @@ -45,12 +41,12 @@ fi pvremove -yff /dev/{{ item }} fi - with_items: "{{ unmounted_devices.stdout_lines }}" + with_items: "{{ block_devices.unmounted }}" become: True - name: Ensure that all unmounted block devices have filesystems wiped command: "wipefs -f /dev/{{ item }}" - with_items: "{{ unmounted_devices.stdout_lines }}" + with_items: "{{ block_devices.unmounted }}" become: True # The command can fail in some cases which are valid, so ignore the # result. @@ -58,5 +54,5 @@ - name: Ensure that all unmounted block device headers are zeroed command: "dd if=/dev/zero of=/dev/{{ item }} bs=1M count=100" - with_items: "{{ unmounted_devices.stdout_lines }}" + with_items: "{{ block_devices.unmounted }}" become: True diff --git a/releasenotes/notes/fix-issue-with-wipefs-destroying-mounted-filesystems-77cdfda91689d7d1.yaml b/releasenotes/notes/fix-issue-with-wipefs-destroying-mounted-filesystems-77cdfda91689d7d1.yaml new file mode 100644 index 000000000..22aaa3442 --- /dev/null +++ b/releasenotes/notes/fix-issue-with-wipefs-destroying-mounted-filesystems-77cdfda91689d7d1.yaml @@ -0,0 +1,6 @@ +--- +fixes: + - | + Fixes an issue where a host configure with ``--wipe-disks`` would + wipe block devices that were mounted. See `story + 2010367 `__ for details.