--- - name: Set partitioning defaults ansible.builtin.set_fact: partitioning_luks_enabled: "{{ partitioning_luks_enabled | default(luks_enabled | default(false)) | bool }}" partitioning_luks_mapper_name: "{{ partitioning_luks_mapper_name | default(luks_mapper_name | default('SYSTEM_DECRYPTED')) }}" partitioning_luks_type: "{{ partitioning_luks_type | default(luks_type | default('luks2')) }}" partitioning_luks_cipher: "{{ partitioning_luks_cipher | default(luks_cipher | default('aes-xts-plain64')) }}" partitioning_luks_hash: "{{ partitioning_luks_hash | default(luks_hash | default('sha512')) }}" partitioning_luks_iter_time: "{{ partitioning_luks_iter_time | default(luks_iter_time | default(4000)) }}" partitioning_luks_key_size: "{{ partitioning_luks_key_size | default(luks_key_size | default(512)) }}" partitioning_luks_pbkdf: "{{ partitioning_luks_pbkdf | default(luks_pbkdf | default('argon2id')) }}" partitioning_luks_use_urandom: "{{ partitioning_luks_use_urandom | default(luks_use_urandom | default(true)) | bool }}" partitioning_luks_verify_passphrase: "{{ partitioning_luks_verify_passphrase | default(luks_verify_passphrase | default(true)) | bool }}" partitioning_luks_auto_decrypt: "{{ partitioning_luks_auto_decrypt | default(luks_auto_decrypt | default(true)) | bool }}" partitioning_luks_auto_decrypt_method: "{{ partitioning_luks_auto_decrypt_method | default(luks_auto_decrypt_method | default('tpm2')) }}" partitioning_luks_tpm2_device: "{{ partitioning_luks_tpm2_device | default(luks_tpm2_device | default('auto')) }}" partitioning_luks_tpm2_pcrs: "{{ partitioning_luks_tpm2_pcrs | default(luks_tpm2_pcrs | default('')) }}" partitioning_luks_keyfile_size: "{{ partitioning_luks_keyfile_size | default(luks_keyfile_size | default(64)) }}" partitioning_luks_options: "{{ partitioning_luks_options | default(luks_options | default('discard,tries=3')) }}" partitioning_luks_device: >- {{ install_drive ~ (partitioning_main_partition_suffix | string) }} - name: Set partitioning root device ansible.builtin.set_fact: partitioning_root_device: >- {{ '/dev/mapper/' + partitioning_luks_mapper_name if partitioning_luks_enabled | bool else install_drive ~ (partitioning_main_partition_suffix | string) }} - name: Set partitioning vm_size from input when: vm_size is defined or partitioning_vm_size is defined ansible.builtin.set_fact: partitioning_vm_size: "{{ (partitioning_vm_size | default(vm_size)) | float }}" - name: Set partitioning vm memory from input when: vm_memory is defined or partitioning_vm_memory is defined ansible.builtin.set_fact: partitioning_vm_memory: "{{ (partitioning_vm_memory | default(vm_memory)) | float }}" - name: Detect system memory for swap sizing when: partitioning_vm_memory is not defined block: - name: Read system memory ansible.builtin.command: awk '/MemTotal/ {print int($2/1024)}' /proc/meminfo register: partitioning_memtotal_mb changed_when: false failed_when: false - name: Set partitioning vm memory default ansible.builtin.set_fact: partitioning_vm_memory: "{{ (partitioning_memtotal_mb.stdout | default('4096') | int) | float }}" - name: Calculate swap size ansible.builtin.set_fact: partitioning_swap_size_gb: >- {{ ((partitioning_vm_memory | float / 1024) >= 16.0) | ternary( (partitioning_vm_memory | float / 2048) | int, [partitioning_vm_memory | float / 1024, 4.0] | max | int ) }} - name: Set partitioning vm_size for physical installs when: - install_type == "physical" - partitioning_vm_size is not defined - install_drive is defined block: - name: Detect install drive size ansible.builtin.command: "lsblk -b -dn -o SIZE {{ install_drive }}" register: partitioning_disk_size_bytes changed_when: false - name: Set partitioning vm_size from install drive size when: - partitioning_disk_size_bytes.stdout is defined - (partitioning_disk_size_bytes.stdout | trim | length) > 0 ansible.builtin.set_fact: partitioning_vm_size: >- {{ (partitioning_disk_size_bytes.stdout | trim | int / 1024 / 1024 / 1024) | round(2, 'floor') }} - name: Partition install drive block: - name: Prepare partitions block: - name: Disable swap ansible.builtin.command: swapoff -a changed_when: false failed_when: false - name: Find mounts under /mnt ansible.builtin.command: findmnt -R /mnt -n -o TARGET register: partitioning_mounted_paths changed_when: false failed_when: false - name: Unmount /mnt mounts when: partitioning_mounted_paths.stdout_lines | length > 0 ansible.posix.mount: path: "{{ item }}" state: unmounted loop: "{{ partitioning_mounted_paths.stdout_lines | reverse }}" loop_control: label: "{{ item }}" failed_when: false - name: Remove LVM volume group community.general.lvg: vg: sys state: absent force: true failed_when: false - name: Close LUKS mapper when: partitioning_luks_enabled | bool community.crypto.luks_device: name: "{{ partitioning_luks_mapper_name }}" state: closed failed_when: false - name: Remove LUKS mapper device when: partitioning_luks_enabled | bool ansible.builtin.command: >- dmsetup remove --force --retry {{ partitioning_luks_mapper_name }} register: partitioning_dmsetup_remove changed_when: partitioning_dmsetup_remove.rc == 0 failed_when: false - name: Remove LUKS signatures when: partitioning_luks_enabled | bool community.crypto.luks_device: device: "{{ partitioning_luks_device }}" state: absent failed_when: false - name: Wipe filesystem signatures ansible.builtin.command: >- find /dev -wholename "{{ install_drive }}*" -exec wipefs --force --all {} \; register: partitioning_wipefs_result changed_when: false failed_when: false - name: Refresh kernel partition table ansible.builtin.command: "{{ item }}" loop: - "partprobe {{ install_drive }}" - "blockdev --rereadpt {{ install_drive }}" - "udevadm settle" register: partitioning_partprobe_result changed_when: false failed_when: false - name: Define partitions block: - name: Create partition layout community.general.parted: device: "{{ install_drive }}" label: gpt number: "{{ item.number }}" part_end: "{{ item.part_end | default(omit) }}" part_start: "{{ item.part_start | default(omit) }}" name: "{{ item.name }}" flags: "{{ item.flags | default(omit) }}" state: present loop: - {number: 1, part_end: 500MiB, name: boot, flags: [boot, esp]} - {number: 2, part_start: 500MiB, name: root} rescue: - name: Refresh kernel partition table after failure ansible.builtin.command: "{{ item }}" loop: - "partprobe {{ install_drive }}" - "blockdev --rereadpt {{ install_drive }}" - "udevadm settle" register: partitioning_partprobe_retry changed_when: false failed_when: false - name: Retry partition layout community.general.parted: device: "{{ install_drive }}" label: gpt number: "{{ item.number }}" part_end: "{{ item.part_end | default(omit) }}" part_start: "{{ item.part_start | default(omit) }}" name: "{{ item.name }}" flags: "{{ item.flags | default(omit) }}" state: present loop: - {number: 1, part_end: 500MiB, name: boot, flags: [boot, esp]} - {number: 2, part_start: 500MiB, name: root} - name: Settle partition table ansible.builtin.command: "{{ item }}" loop: - "partprobe {{ install_drive }}" - "udevadm settle" register: partitioning_partprobe_settle changed_when: false failed_when: false - name: Configure LUKS encryption when: partitioning_luks_enabled | bool vars: partitioning_luks_passphrase_effective: >- {{ (partitioning_luks_passphrase | default(luks_passphrase | default(''))) | string }} block: - name: Validate LUKS passphrase ansible.builtin.assert: that: - partitioning_luks_passphrase_effective | length > 0 fail_msg: luks_passphrase (or partitioning_luks_passphrase) must be set when LUKS is enabled. no_log: true - name: Ensure LUKS container exists community.crypto.luks_device: device: "{{ partitioning_luks_device }}" state: present type: "{{ partitioning_luks_type }}" cipher: "{{ partitioning_luks_cipher }}" hash: "{{ partitioning_luks_hash }}" keysize: "{{ partitioning_luks_key_size }}" pbkdf: algorithm: "{{ partitioning_luks_pbkdf }}" iteration_time: "{{ (partitioning_luks_iter_time | float) / 1000 }}" passphrase: "{{ partitioning_luks_passphrase_effective }}" register: partitioning_luks_format_result no_log: true - name: Force-close LUKS mapper community.crypto.luks_device: name: "{{ partitioning_luks_mapper_name }}" state: closed failed_when: false - name: Force-remove LUKS mapper device ansible.builtin.command: >- dmsetup remove --force --retry {{ partitioning_luks_mapper_name }} register: partitioning_dmsetup_remove_after_format changed_when: partitioning_dmsetup_remove_after_format.rc == 0 failed_when: false - name: Settle udev after removing LUKS mapper ansible.builtin.command: udevadm settle changed_when: false failed_when: false - name: Ensure LUKS mapper is opened block: - name: Open LUKS device community.crypto.luks_device: device: "{{ partitioning_luks_device }}" state: opened name: "{{ partitioning_luks_mapper_name }}" passphrase: "{{ partitioning_luks_passphrase_effective }}" allow_discards: "{{ 'discard' in (partitioning_luks_options | default('') | lower) }}" register: partitioning_luks_open_result no_log: true rescue: - name: Force-close stale LUKS mapper community.crypto.luks_device: name: "{{ partitioning_luks_mapper_name }}" state: closed failed_when: false - name: Force-remove stale LUKS mapper device ansible.builtin.command: >- dmsetup remove --force --retry {{ partitioning_luks_mapper_name }} register: partitioning_dmsetup_remove_retry changed_when: partitioning_dmsetup_remove_retry.rc == 0 failed_when: false - name: Settle udev after removing stale LUKS mapper ansible.builtin.command: udevadm settle changed_when: false failed_when: false - name: Retry opening LUKS device community.crypto.luks_device: device: "{{ partitioning_luks_device }}" state: opened name: "{{ partitioning_luks_mapper_name }}" passphrase: "{{ partitioning_luks_passphrase_effective }}" allow_discards: "{{ 'discard' in (partitioning_luks_options | default('') | lower) }}" register: partitioning_luks_open_retry no_log: true - name: Get LUKS UUID ansible.builtin.command: "cryptsetup luksUUID {{ partitioning_luks_device }}" register: partitioning_luks_uuid_result changed_when: false - name: Store LUKS UUID ansible.builtin.set_fact: partitioning_luks_uuid: "{{ partitioning_luks_uuid_result.stdout | trim }}" - name: Create LVM logical volumes when: filesystem != 'btrfs' block: - name: Create LVM volume group community.general.lvg: vg: sys pvs: "{{ partitioning_root_device }}" - name: Create LVM logical volumes when: cis | bool or item.lv not in ['home', 'var', 'var_log', 'var_log_audit'] community.general.lvol: vg: sys lv: "{{ item.lv }}" size: "{{ item.size }}" state: present loop: - lv: root size: >- {{ [(((((partitioning_vm_size | float) - 0.5 - ((cis | bool) | ternary(7.5, 0)) - (((partitioning_vm_memory | float / 1024) > 16.0) | ternary(((partitioning_vm_memory | float / 2048) | int), (partitioning_vm_memory | float / 1024)))) < 4) | ternary(4,((((partitioning_vm_size | float) - 0.5 - ((cis | bool) | ternary(7.5, 0)) - (((partitioning_vm_memory | float / 1024) > 16.0) | ternary( ((partitioning_vm_memory | float / 2048) | int), (partitioning_vm_memory | float / 1024) ))) > 12) | ternary(((partitioning_vm_size | float) * 0.4) | round(0, 'ceil'),((partitioning_vm_size | float) - 0.5 - ((cis | bool) | ternary(7.5, 0)) - (((partitioning_vm_memory | float / 1024) > 16.0) | ternary(((partitioning_vm_memory | float / 2048) | int), (partitioning_vm_memory | float / 1024))))))))), 4 ] | max | string + 'G' }} - lv: swap size: >- {{ ((((partitioning_vm_size | float) - 0.5 - ((cis | bool) | ternary(7.5, 0))) - (((partitioning_vm_memory | float / 1024) > 16.0) | ternary(((partitioning_vm_memory | float / 2048) | int), (partitioning_vm_memory | float / 1024)))) < 4) | ternary((((partitioning_vm_size | float) - 0.5 - ((cis | bool) | ternary(7.5, 0))) - 4), (((partitioning_vm_memory | float / 1024) > 16.0) | ternary(((partitioning_vm_memory | float / 2048) | int), (partitioning_vm_memory | float / 1024)))) | string + 'G' }} - lv: home size: "{{ ([([(((partitioning_vm_size | float) - 20) * 0.1), 2] | max), 20] | min) | string + 'G' }}" - {lv: var, size: "2G"} - {lv: var_log, size: "2G"} - {lv: var_log_audit, size: "1.5G"} - name: Create filesystems block: - name: Create FAT32 filesystem in boot partition community.general.filesystem: dev: "{{ install_drive }}{{ partitioning_boot_partition_suffix }}" fstype: vfat opts: -F32 -n BOOT force: true - name: Create swap filesystem when: filesystem != 'btrfs' community.general.filesystem: fstype: swap dev: /dev/sys/swap - name: Create filesystem ansible.builtin.include_tasks: "{{ filesystem }}.yml" - name: Get UUID for boot filesystem ansible.builtin.command: blkid -s UUID -o value '{{ install_drive }}{{ partitioning_boot_partition_suffix }}' register: partitioning_boot_uuid changed_when: false - name: Get UUID for main filesystem ansible.builtin.command: blkid -s UUID -o value '{{ partitioning_root_device }}' register: partitioning_main_uuid changed_when: false - name: Get UUIDs for LVM filesystems when: filesystem != 'btrfs' and (cis | bool or item not in ['home', 'var', 'var_log', 'var_log_audit']) ansible.builtin.command: blkid -s UUID -o value /dev/sys/{{ item }} loop: - root - swap - home - var - var_log - var_log_audit register: partitioning_uuid_result changed_when: false - name: Assign UUIDs to Variables when: filesystem != 'btrfs' ansible.builtin.set_fact: partitioning_uuid_root: "{{ partitioning_uuid_result.results[0].stdout_lines }}" partitioning_uuid_swap: "{{ partitioning_uuid_result.results[1].stdout_lines }}" partitioning_uuid_home: "{{ partitioning_uuid_result.results[2].stdout_lines if cis | bool else '' }}" partitioning_uuid_var: "{{ partitioning_uuid_result.results[3].stdout_lines if cis | bool else '' }}" partitioning_uuid_var_log: "{{ partitioning_uuid_result.results[4].stdout_lines if cis | bool else '' }}" partitioning_uuid_var_log_audit: "{{ partitioning_uuid_result.results[5].stdout_lines if cis | bool else '' }}" - name: Mount filesystems block: - name: Mount filesystems and subvolumes when: - >- cis | bool or ( not cis and ( (filesystem == 'btrfs' and item.path in ['/home', '/var/log', '/var/cache/pacman/pkg']) or (item.path not in ['/home', '/var', '/var/log', '/var/log/audit', '/var/cache/pacman/pkg']) ) ) - >- not (item.path in ['/swap', '/var/cache/pacman/pkg'] and filesystem != 'btrfs') ansible.posix.mount: path: /mnt{{ item.path }} src: "{{ 'UUID=' + (partitioning_main_uuid.stdout if filesystem == 'btrfs' else item.uuid) }}" fstype: "{{ filesystem }}" opts: "{{ item.opts }}" state: mounted loop: - path: "" uuid: "{{ partitioning_uuid_root[0] | default(omit) }}" opts: >- {{ 'defaults' if filesystem != 'btrfs' else [ 'rw', 'relatime', 'compress=zstd:15', 'ssd', 'space_cache=v2', 'discard=async', 'subvol=@' ] | join(',') }} - path: /swap opts: >- {{ [ 'rw', 'nosuid', 'nodev', 'relatime', 'compress=zstd:15', 'ssd', 'space_cache=v2', 'discard=async', 'subvol=@swap' ] | join(',') }} - path: /home uuid: "{{ partitioning_uuid_home[0] | default(omit) }}" opts: >- {{ 'defaults,nosuid,nodev' if filesystem != 'btrfs' else [ 'rw', 'nosuid', 'nodev', 'relatime', 'compress=zstd:15', 'ssd', 'space_cache=v2', 'discard=async', 'subvol=@home' ] | join(',') }} - path: /var uuid: "{{ partitioning_uuid_var[0] | default(omit) }}" opts: >- {{ 'defaults,nosuid,nodev' if filesystem != 'btrfs' else [ 'rw', 'nosuid', 'nodev', 'relatime', 'compress=zstd:15', 'ssd', 'space_cache=v2', 'discard=async', 'subvol=@var' ] | join(',') }} - path: /var/log uuid: "{{ partitioning_uuid_var_log[0] | default(omit) }}" opts: >- {{ 'defaults,nosuid,nodev,noexec' if filesystem != 'btrfs' else [ 'rw', 'nosuid', 'nodev', 'noexec', 'relatime', 'compress=zstd:15', 'ssd', 'space_cache=v2', 'discard=async', 'subvol=@var_log' ] | join(',') }} - path: /var/cache/pacman/pkg uuid: "{{ partitioning_uuid_root | default([]) | first | default(omit) }}" opts: >- {{ 'defaults,nosuid,nodev,noexec' if filesystem != 'btrfs' else [ 'rw', 'nosuid', 'nodev', 'noexec', 'relatime', 'compress=zstd:15', 'ssd', 'space_cache=v2', 'discard=async', 'subvol=@pkg' ] | join(',') }} - path: /var/log/audit uuid: "{{ partitioning_uuid_var_log_audit[0] | default(omit) }}" opts: >- {{ 'defaults,nosuid,nodev,noexec' if filesystem != 'btrfs' else [ 'rw', 'nosuid', 'nodev', 'noexec', 'relatime', 'compress=zstd:15', 'ssd', 'space_cache=v2', 'discard=async', 'subvol=@var_log_audit' ] | join(',') }} - name: Mount boot filesystem ansible.posix.mount: path: "{{ '/mnt/boot/efi' if os | lower in ['rhel8', 'ubuntu', 'ubuntu-lts'] else '/mnt/boot' }}" src: UUID={{ partitioning_boot_uuid.stdout }} fstype: vfat state: mounted - name: Activate swap vars: partitioning_swap_cmd: >- {{ 'swapon /mnt/swap/swapfile' if filesystem == 'btrfs' else 'swapon -U ' + partitioning_uuid_swap[0] }} ansible.builtin.command: "{{ partitioning_swap_cmd }}" register: partitioning_swap_activate_result changed_when: partitioning_swap_activate_result.rc == 0