diff --git a/roles/partitioning/tasks/_create_filesystems.yml b/roles/partitioning/tasks/_create_filesystems.yml new file mode 100644 index 0000000..04e078e --- /dev/null +++ b/roles/partitioning/tasks/_create_filesystems.yml @@ -0,0 +1,146 @@ +--- +- 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 filesystem for /boot partition + when: partitioning_separate_boot | bool + community.general.filesystem: + dev: "{{ install_drive }}{{ partitioning_boot_fs_partition_suffix }}" + fstype: "{{ partitioning_boot_fs_fstype }}" + opts: "{{ '-m bigtime=0 -i nrext64=0,exchange=0 -n parent=0' if (is_rhel | bool and partitioning_boot_fs_fstype == 'xfs') else omit }}" + force: true + + - name: Remove unsupported ext4 features from /boot + when: + - partitioning_separate_boot | bool + - partitioning_boot_fs_fstype == 'ext4' + - os in ['almalinux', 'rocky', 'rhel'] or (os == 'debian' and (os_version | string) == '11') + ansible.builtin.command: >- + tune2fs -O "^orphan_file,^metadata_csum_seed" + "{{ install_drive }}{{ partitioning_boot_fs_partition_suffix }}" + register: partitioning_boot_ext4_tune_result + changed_when: partitioning_boot_ext4_tune_result.rc == 0 + + - name: Create swap filesystem + when: + - system_cfg.filesystem != 'btrfs' + - system_cfg.features.swap.enabled | bool + community.general.filesystem: + fstype: swap + dev: /dev/{{ partitioning_vg_name }}/swap + + - name: Create filesystem + ansible.builtin.include_tasks: "{{ system_cfg.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 + failed_when: partitioning_boot_uuid.rc != 0 or (partitioning_boot_uuid.stdout | trim | length) == 0 + + - name: Get UUID for /boot filesystem + when: partitioning_separate_boot | bool + ansible.builtin.command: >- + blkid -s UUID -o value '{{ install_drive }}{{ partitioning_boot_fs_partition_suffix }}' + register: partitioning_boot_fs_uuid + changed_when: false + failed_when: partitioning_boot_fs_uuid.rc != 0 or (partitioning_boot_fs_uuid.stdout | trim | length) == 0 + + - name: Get UUID for main filesystem + ansible.builtin.command: blkid -s UUID -o value '{{ partitioning_root_device }}' + register: partitioning_main_uuid + changed_when: false + failed_when: partitioning_main_uuid.rc != 0 or (partitioning_main_uuid.stdout | trim | length) == 0 + + - name: Get UUID for LVM root filesystem + when: system_cfg.filesystem != 'btrfs' + ansible.builtin.command: blkid -s UUID -o value /dev/{{ partitioning_vg_name }}/root + register: partitioning_uuid_root_result + changed_when: false + failed_when: partitioning_uuid_root_result.rc != 0 or (partitioning_uuid_root_result.stdout | trim | length) == 0 + + - name: Get UUID for LVM swap filesystem + when: + - system_cfg.filesystem != 'btrfs' + - system_cfg.features.swap.enabled | bool + ansible.builtin.command: blkid -s UUID -o value /dev/{{ partitioning_vg_name }}/swap + register: partitioning_uuid_swap_result + changed_when: false + failed_when: partitioning_uuid_swap_result.rc != 0 or (partitioning_uuid_swap_result.stdout | trim | length) == 0 + + - name: Get UUID for LVM home filesystem + when: + - system_cfg.filesystem != 'btrfs' + - system_cfg.features.cis.enabled + ansible.builtin.command: blkid -s UUID -o value /dev/{{ partitioning_vg_name }}/home + register: partitioning_uuid_home_result + changed_when: false + failed_when: partitioning_uuid_home_result.rc != 0 or (partitioning_uuid_home_result.stdout | trim | length) == 0 + + - name: Get UUID for LVM var filesystem + when: + - system_cfg.filesystem != 'btrfs' + - system_cfg.features.cis.enabled + ansible.builtin.command: blkid -s UUID -o value /dev/{{ partitioning_vg_name }}/var + register: partitioning_uuid_var_result + changed_when: false + failed_when: partitioning_uuid_var_result.rc != 0 or (partitioning_uuid_var_result.stdout | trim | length) == 0 + + - name: Get UUID for LVM var_log filesystem + when: + - system_cfg.filesystem != 'btrfs' + - system_cfg.features.cis.enabled + ansible.builtin.command: blkid -s UUID -o value /dev/{{ partitioning_vg_name }}/var_log + register: partitioning_uuid_var_log_result + changed_when: false + failed_when: partitioning_uuid_var_log_result.rc != 0 or (partitioning_uuid_var_log_result.stdout | trim | length) == 0 + + - name: Get UUID for LVM var_log_audit filesystem + when: + - system_cfg.filesystem != 'btrfs' + - system_cfg.features.cis.enabled + ansible.builtin.command: blkid -s UUID -o value /dev/{{ partitioning_vg_name }}/var_log_audit + register: partitioning_uuid_var_log_audit_result + changed_when: false + failed_when: partitioning_uuid_var_log_audit_result.rc != 0 or (partitioning_uuid_var_log_audit_result.stdout | trim | length) == 0 + + - name: Assign UUIDs to Variables + when: system_cfg.filesystem != 'btrfs' + ansible.builtin.set_fact: + partitioning_uuid_root: "{{ partitioning_uuid_root_result.stdout_lines | default([]) }}" + partitioning_uuid_swap: >- + {{ + partitioning_uuid_swap_result.stdout_lines | default([]) + if system_cfg.features.swap.enabled | bool + else [] + }} + partitioning_uuid_home: >- + {{ + partitioning_uuid_home_result.stdout_lines | default([]) + if system_cfg.features.cis.enabled + else [] + }} + partitioning_uuid_var: >- + {{ + partitioning_uuid_var_result.stdout_lines | default([]) + if system_cfg.features.cis.enabled + else [] + }} + partitioning_uuid_var_log: >- + {{ + partitioning_uuid_var_log_result.stdout_lines | default([]) + if system_cfg.features.cis.enabled + else [] + }} + partitioning_uuid_var_log_audit: >- + {{ + partitioning_uuid_var_log_audit_result.stdout_lines | default([]) + if system_cfg.features.cis.enabled + else [] + }} diff --git a/roles/partitioning/tasks/_create_lvm.yml b/roles/partitioning/tasks/_create_lvm.yml new file mode 100644 index 0000000..b3d7b86 --- /dev/null +++ b/roles/partitioning/tasks/_create_lvm.yml @@ -0,0 +1,192 @@ +--- +# LVM Sizing Algorithm +# ==================== +# Sizes are computed from disk_size_gb, memory_mb, and feature flags. +# +# Swap sizing: +# - RAM >= 16 GB → swap = RAM/2 (in GB) +# - RAM < 16 GB → swap = max(RAM_GB, 4) +# - Capped to: min(target, 4 + max(disk - overhead, 0)) +# - Further capped to: max available after subtracting reserved + CIS + extent reserve + 4 GB buffer +# +# Root sizing: +# - Full-disk mode (default): disk - reserved - swap - extent_reserve - (CIS volumes if enabled) +# - Partial mode: tiered — <4 GB available → 4 GB, 4-12 GB → all available, >12 GB → 40% of disk +# +# CIS volumes (only when CIS enabled): +# - /home: max(min(home_raw, home_max), home_min) where home_raw = (disk - overhead) * 10% +# - /var: 2 GB, /var/log: 2 GB, /var/log/audit: 1.5 GB +# +# Extent reserve: 10 extents * 4 MiB = ~0.04 GB (prevents VG overflow) + +- name: Create LVM logical volumes + when: system_cfg.filesystem != 'btrfs' + block: + - name: Create LVM volume group + community.general.lvg: + vg: "{{ partitioning_vg_name }}" + pvs: "{{ partitioning_root_device }}" + + - name: Create LVM logical volumes + when: + - system_cfg.features.cis.enabled or item.lv not in ['home', 'var', 'var_log', 'var_log_audit'] + - system_cfg.features.swap.enabled | bool or item.lv != 'swap' + vars: + partitioning_lvm_extent_reserve_count: 10 + partitioning_lvm_extent_size_mib: 4 + partitioning_lvm_extent_reserve_gb: >- + {{ + ( + (partitioning_lvm_extent_reserve_count | float) + * (partitioning_lvm_extent_size_mib | float) + / 1024 + ) | round(2, 'ceil') + }} + partitioning_lvm_swap_target_gb: >- + {{ + ( + ((partitioning_memory_mb | float / 1024) >= 16.0) + | ternary( + (partitioning_memory_mb | float / 2048), + [(partitioning_memory_mb | float / 1024), 4] | max | float + ) + ) + if system_cfg.features.swap.enabled | bool + else 0 + }} + partitioning_lvm_swap_cap_gb: >- + {{ + ( + 4 + + [ + (partitioning_disk_size_gb | float) - (partitioning_disk_overhead_gb | float), + 0 + ] | max + ) + if system_cfg.features.swap.enabled | bool + else 0 + }} + partitioning_lvm_swap_target_limited_gb: >- + {{ + ( + [ + partitioning_lvm_swap_target_gb, + partitioning_lvm_swap_cap_gb + ] | min + ) + if system_cfg.features.swap.enabled | bool + else 0 + }} + partitioning_lvm_swap_max_gb: >- + {{ + ( + [ + ( + (partitioning_disk_size_gb | float) + - (partitioning_reserved_gb | float) + - (system_cfg.features.cis.enabled | ternary(partitioning_cis_reserved_gb | float, 0)) + - partitioning_lvm_extent_reserve_gb + - 4 + ), + 0 + ] | max + ) + if system_cfg.features.swap.enabled | bool + else 0 + }} + partitioning_lvm_available_gb: >- + {{ + ( + (partitioning_disk_size_gb | float) + - (partitioning_reserved_gb | float) + - (system_cfg.features.cis.enabled | ternary(partitioning_cis_reserved_gb | float, 0)) + - partitioning_lvm_extent_reserve_gb + - partitioning_lvm_swap_target_limited_gb + ) | float + }} + partitioning_lvm_home_raw_gb: >- + {{ + ((partitioning_disk_size_gb | float) - (partitioning_disk_overhead_gb | float)) + * (partitioning_home_allocation_pct | float) + }} + partitioning_lvm_home_gb: >- + {{ + [ + [(partitioning_lvm_home_raw_gb | float), (partitioning_home_min_gb | float)] | max, + (partitioning_home_max_gb | float) + ] | min + }} + partitioning_lvm_root_default_gb: >- + {{ + [ + ( + ((partitioning_lvm_available_gb | float) < 4) + | ternary( + 4, + ( + ((partitioning_lvm_available_gb | float) > 12) + | ternary( + ((partitioning_disk_size_gb | float) * 0.4) + | round(0, 'ceil'), + partitioning_lvm_available_gb + ) + ) + ) + ), + 4 + ] | max + }} + partitioning_lvm_swap_gb: >- + {{ + ( + [ + partitioning_lvm_swap_target_limited_gb, + partitioning_lvm_swap_max_gb + ] | min | round(2, 'floor') + ) + if system_cfg.features.swap.enabled | bool + else 0 + }} + partitioning_lvm_root_full_gb: >- + {{ + [ + ( + (partitioning_disk_size_gb | float) + - (partitioning_reserved_gb | float) + - (partitioning_lvm_swap_gb | float) + - partitioning_lvm_extent_reserve_gb + - ( + (partitioning_lvm_home_gb | float) + + (partitioning_lvm_var_gb | float) + + (partitioning_lvm_var_log_gb | float) + + (partitioning_lvm_var_log_audit_gb | float) + if system_cfg.features.cis.enabled + else 0 + ) + ), + 4 + ] | max | round(2, 'floor') + }} + partitioning_lvm_root_gb: >- + {{ + partitioning_lvm_root_full_gb + if partitioning_use_full_disk | bool + else partitioning_lvm_root_default_gb + }} + community.general.lvol: + vg: "{{ partitioning_vg_name }}" + lv: "{{ item.lv }}" + size: "{{ item.size }}" + state: present + loop: + - lv: root + size: "{{ partitioning_lvm_root_gb | string + 'G' }}" + - lv: swap + size: "{{ partitioning_lvm_swap_gb | string + 'G' }}" + - lv: home + size: "{{ partitioning_lvm_home_gb | string + 'G' }}" + - { lv: var, size: "{{ partitioning_lvm_var_gb }}G" } + - { lv: var_log, size: "{{ partitioning_lvm_var_log_gb }}G" } + - { lv: var_log_audit, size: "{{ partitioning_lvm_var_log_audit_gb }}G" } + loop_control: + label: "{{ item.lv }}" diff --git a/roles/partitioning/tasks/_create_partitions.yml b/roles/partitioning/tasks/_create_partitions.yml new file mode 100644 index 0000000..a5e697a --- /dev/null +++ b/roles/partitioning/tasks/_create_partitions.yml @@ -0,0 +1,121 @@ +--- +- name: Partition install drive + block: + - name: Prepare partitions + block: + - name: Disable swap + ansible.builtin.command: swapoff -a + register: partitioning_swapoff_result + changed_when: partitioning_swapoff_result.rc == 0 + 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: "{{ partitioning_vg_name }}" + state: absent + force: true + failed_when: false + + - name: Close LUKS mapper + when: system_cfg.luks.enabled | bool + community.crypto.luks_device: + name: "{{ system_cfg.luks.mapper }}" + state: closed + failed_when: false + + - name: Remove LUKS mapper device + when: system_cfg.luks.enabled | bool + ansible.builtin.command: >- + dmsetup remove --force --retry {{ system_cfg.luks.mapper }} + register: partitioning_dmsetup_remove + changed_when: partitioning_dmsetup_remove.rc == 0 + failed_when: false + + - name: Remove LUKS signatures + when: system_cfg.luks.enabled | bool + community.crypto.luks_device: + device: "{{ partitioning_luks_device }}" + state: absent + failed_when: false + + - name: Wipe filesystem signatures + ansible.builtin.shell: >- + find /dev -wholename "{{ install_drive }}*" -exec wipefs --force --all {} \; + register: partitioning_wipefs_result + changed_when: partitioning_wipefs_result.rc == 0 + 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: "{{ partitioning_layout }}" + loop_control: + label: "{{ item.name }}" + 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: "{{ partitioning_layout }}" + loop_control: + label: "{{ item.name }}" + + - name: Settle partition table + ansible.builtin.command: "{{ item }}" + loop: + - "partprobe {{ install_drive }}" + - "udevadm settle" + register: partitioning_partprobe_settle + changed_when: false + failed_when: false diff --git a/roles/partitioning/tasks/_detect_sizing.yml b/roles/partitioning/tasks/_detect_sizing.yml new file mode 100644 index 0000000..cdba738 --- /dev/null +++ b/roles/partitioning/tasks/_detect_sizing.yml @@ -0,0 +1,38 @@ +--- +- name: Detect system memory for swap sizing + when: + - system_cfg.features.swap.enabled | bool + - partitioning_vm_memory is not defined or (partitioning_vm_memory | float) <= 0 + - (system_cfg.memory | default(0) | float) <= 0 + 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: Set partitioning vm_size for physical installs + when: + - system_cfg.type == "physical" + - partitioning_vm_size is not defined or (partitioning_vm_size | float) <= 0 + - install_drive | length > 0 + 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') + }} diff --git a/roles/partitioning/tasks/_mount.yml b/roles/partitioning/tasks/_mount.yml new file mode 100644 index 0000000..98ace57 --- /dev/null +++ b/roles/partitioning/tasks/_mount.yml @@ -0,0 +1,124 @@ +--- +- name: Mount filesystems + block: + - name: Mount filesystems and subvolumes + when: + - >- + system_cfg.features.cis.enabled or ( + not system_cfg.features.cis.enabled and ( + (system_cfg.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 system_cfg.filesystem != 'btrfs') + - system_cfg.features.swap.enabled | bool or item.path != '/swap' + ansible.posix.mount: + path: /mnt{{ item.path }} + src: "{{ 'UUID=' + (partitioning_main_uuid.stdout if system_cfg.filesystem == 'btrfs' else item.uuid) }}" + fstype: "{{ system_cfg.filesystem }}" + opts: "{{ item.opts }}" + state: mounted + loop: + # ssd: no-op on kernels 5.15+ (btrfs auto-detects); kept for older kernel compat + - path: "" + uuid: "{{ partitioning_uuid_root[0] | default(omit) }}" + opts: >- + {{ + 'defaults' + if system_cfg.filesystem != 'btrfs' + else [ + 'rw', 'relatime', partitioning_btrfs_compress_opt, 'ssd', 'space_cache=v2', + 'discard=async', 'subvol=@' + ] | reject('equalto', '') | join(',') + }} + - path: /swap + opts: >- + {{ + [ + 'rw', 'nosuid', 'nodev', 'relatime', partitioning_btrfs_compress_opt, 'ssd', + 'space_cache=v2', 'discard=async', 'subvol=@swap' + ] | reject('equalto', '') | join(',') + }} + - path: /home + uuid: "{{ partitioning_uuid_home[0] | default(omit) }}" + opts: >- + {{ + 'defaults,nosuid,nodev' + if system_cfg.filesystem != 'btrfs' + else [ + 'rw', 'nosuid', 'nodev', 'relatime', partitioning_btrfs_compress_opt, 'ssd', + 'space_cache=v2', 'discard=async', 'subvol=@home' + ] | reject('equalto', '') | join(',') + }} + - path: /var + uuid: "{{ partitioning_uuid_var[0] | default(omit) }}" + opts: >- + {{ + 'defaults,nosuid,nodev' + if system_cfg.filesystem != 'btrfs' + else [ + 'rw', 'nosuid', 'nodev', 'relatime', partitioning_btrfs_compress_opt, 'ssd', + 'space_cache=v2', 'discard=async', 'subvol=@var' + ] | reject('equalto', '') | join(',') + }} + - path: /var/log + uuid: "{{ partitioning_uuid_var_log[0] | default(omit) }}" + opts: >- + {{ + 'defaults,nosuid,nodev,noexec' + if system_cfg.filesystem != 'btrfs' + else [ + 'rw', 'nosuid', 'nodev', 'noexec', 'relatime', partitioning_btrfs_compress_opt, + 'ssd', 'space_cache=v2', 'discard=async', 'subvol=@var_log' + ] | reject('equalto', '') | join(',') + }} + - path: /var/cache/pacman/pkg + uuid: "{{ partitioning_uuid_root | default([]) | first | default(omit) }}" + opts: >- + {{ + 'defaults,nosuid,nodev,noexec' + if system_cfg.filesystem != 'btrfs' + else [ + 'rw', 'nosuid', 'nodev', 'noexec', 'relatime', partitioning_btrfs_compress_opt, + 'ssd', 'space_cache=v2', 'discard=async', 'subvol=@pkg' + ] | reject('equalto', '') | join(',') + }} + - path: /var/log/audit + uuid: "{{ partitioning_uuid_var_log_audit[0] | default(omit) }}" + opts: >- + {{ + 'defaults,nosuid,nodev,noexec' + if system_cfg.filesystem != 'btrfs' + else [ + 'rw', 'nosuid', 'nodev', 'noexec', 'relatime', partitioning_btrfs_compress_opt, + 'ssd', 'space_cache=v2', 'discard=async', 'subvol=@var_log_audit' + ] | reject('equalto', '') | join(',') + }} + loop_control: + label: "{{ item.path }}" + + - name: Mount /boot filesystem + when: partitioning_separate_boot | bool + ansible.posix.mount: + path: /mnt/boot + src: "UUID={{ partitioning_boot_fs_uuid.stdout }}" + fstype: "{{ partitioning_boot_fs_fstype }}" + opts: defaults + state: mounted + + - name: Mount boot filesystem + ansible.posix.mount: + path: "/mnt{{ partitioning_efi_mountpoint }}" + src: UUID={{ partitioning_boot_uuid.stdout }} + fstype: vfat + state: mounted + + - name: Activate swap + when: system_cfg.features.swap.enabled | bool + vars: + partitioning_swap_cmd: >- + {{ 'swapon /mnt/swap/swapfile' if system_cfg.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 diff --git a/roles/partitioning/tasks/_setup_luks.yml b/roles/partitioning/tasks/_setup_luks.yml new file mode 100644 index 0000000..6bc2dca --- /dev/null +++ b/roles/partitioning/tasks/_setup_luks.yml @@ -0,0 +1,92 @@ +--- +- name: Configure LUKS encryption + when: system_cfg.luks.enabled | bool + block: + - name: Validate LUKS passphrase + ansible.builtin.assert: + that: + - (system_cfg.luks.passphrase | string | length) > 0 + fail_msg: system.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: "{{ system_cfg.luks.type }}" + cipher: "{{ system_cfg.luks.cipher }}" + hash: "{{ system_cfg.luks.hash }}" + keysize: "{{ system_cfg.luks.bits }}" + pbkdf: + algorithm: "{{ system_cfg.luks.pbkdf }}" + iteration_time: "{{ (system_cfg.luks.iter | float) / 1000 }}" + passphrase: "{{ system_cfg.luks.passphrase | string }}" + register: partitioning_luks_format_result + no_log: true + + - name: Force-close LUKS mapper + community.crypto.luks_device: + name: "{{ system_cfg.luks.mapper }}" + state: closed + failed_when: false + + - name: Force-remove LUKS mapper device + ansible.builtin.command: >- + dmsetup remove --force --retry {{ system_cfg.luks.mapper }} + 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: "{{ system_cfg.luks.mapper }}" + passphrase: "{{ system_cfg.luks.passphrase | string }}" + allow_discards: "{{ 'discard' in (system_cfg.luks.options | lower) }}" + register: partitioning_luks_open_result + no_log: true + rescue: + - name: Force-close stale LUKS mapper + community.crypto.luks_device: + name: "{{ system_cfg.luks.mapper }}" + state: closed + failed_when: false + + - name: Force-remove stale LUKS mapper device + ansible.builtin.command: >- + dmsetup remove --force --retry {{ system_cfg.luks.mapper }} + 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: "{{ system_cfg.luks.mapper }}" + passphrase: "{{ system_cfg.luks.passphrase | string }}" + allow_discards: "{{ 'discard' in (system_cfg.luks.options | 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 }}" diff --git a/roles/partitioning/tasks/main.yml b/roles/partitioning/tasks/main.yml index 867caee..d134b8e 100644 --- a/roles/partitioning/tasks/main.yml +++ b/roles/partitioning/tasks/main.yml @@ -1,696 +1,21 @@ --- -- name: Detect system memory for swap sizing - when: - - system_cfg.features.swap.enabled | bool - - partitioning_vm_memory is not defined or (partitioning_vm_memory | float) <= 0 - - (system_cfg.memory | default(0) | float) <= 0 - 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: Detect system sizing + ansible.builtin.include_tasks: _detect_sizing.yml - - name: Set partitioning vm memory default - ansible.builtin.set_fact: - partitioning_vm_memory: "{{ (partitioning_memtotal_mb.stdout | default('4096') | int) | float }}" +- name: Create partitions + ansible.builtin.include_tasks: _create_partitions.yml -- name: Set partitioning vm_size for physical installs - when: - - system_cfg.type == "physical" - - partitioning_vm_size is not defined or (partitioning_vm_size | float) <= 0 - - install_drive | length > 0 - 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 - register: partitioning_swapoff_result - changed_when: partitioning_swapoff_result.rc == 0 - 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: "{{ partitioning_vg_name }}" - state: absent - force: true - failed_when: false - - - name: Close LUKS mapper - when: system_cfg.luks.enabled | bool - community.crypto.luks_device: - name: "{{ system_cfg.luks.mapper }}" - state: closed - failed_when: false - - - name: Remove LUKS mapper device - when: system_cfg.luks.enabled | bool - ansible.builtin.command: >- - dmsetup remove --force --retry {{ system_cfg.luks.mapper }} - register: partitioning_dmsetup_remove - changed_when: partitioning_dmsetup_remove.rc == 0 - failed_when: false - - - name: Remove LUKS signatures - when: system_cfg.luks.enabled | bool - community.crypto.luks_device: - device: "{{ partitioning_luks_device }}" - state: absent - failed_when: false - - - name: Wipe filesystem signatures - ansible.builtin.shell: >- - find /dev -wholename "{{ install_drive }}*" -exec wipefs --force --all {} \; - register: partitioning_wipefs_result - changed_when: partitioning_wipefs_result.rc == 0 - 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: "{{ partitioning_layout }}" - loop_control: - label: "{{ item.name }}" - 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: "{{ partitioning_layout }}" - loop_control: - label: "{{ item.name }}" - - - 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: system_cfg.luks.enabled | bool - block: - - name: Validate LUKS passphrase - ansible.builtin.assert: - that: - - (system_cfg.luks.passphrase | string | length) > 0 - fail_msg: system.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: "{{ system_cfg.luks.type }}" - cipher: "{{ system_cfg.luks.cipher }}" - hash: "{{ system_cfg.luks.hash }}" - keysize: "{{ system_cfg.luks.bits }}" - pbkdf: - algorithm: "{{ system_cfg.luks.pbkdf }}" - iteration_time: "{{ (system_cfg.luks.iter | float) / 1000 }}" - passphrase: "{{ system_cfg.luks.passphrase | string }}" - register: partitioning_luks_format_result - no_log: true - - - name: Force-close LUKS mapper - community.crypto.luks_device: - name: "{{ system_cfg.luks.mapper }}" - state: closed - failed_when: false - - - name: Force-remove LUKS mapper device - ansible.builtin.command: >- - dmsetup remove --force --retry {{ system_cfg.luks.mapper }} - 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: "{{ system_cfg.luks.mapper }}" - passphrase: "{{ system_cfg.luks.passphrase | string }}" - allow_discards: "{{ 'discard' in (system_cfg.luks.options | lower) }}" - register: partitioning_luks_open_result - no_log: true - rescue: - - name: Force-close stale LUKS mapper - community.crypto.luks_device: - name: "{{ system_cfg.luks.mapper }}" - state: closed - failed_when: false - - - name: Force-remove stale LUKS mapper device - ansible.builtin.command: >- - dmsetup remove --force --retry {{ system_cfg.luks.mapper }} - 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: "{{ system_cfg.luks.mapper }}" - passphrase: "{{ system_cfg.luks.passphrase | string }}" - allow_discards: "{{ 'discard' in (system_cfg.luks.options | 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: Setup LUKS encryption + ansible.builtin.include_tasks: _setup_luks.yml - name: Create LVM logical volumes - when: system_cfg.filesystem != 'btrfs' - block: - - name: Create LVM volume group - community.general.lvg: - vg: "{{ partitioning_vg_name }}" - pvs: "{{ partitioning_root_device }}" + ansible.builtin.include_tasks: _create_lvm.yml - - name: Create LVM logical volumes - when: - - system_cfg.features.cis.enabled or item.lv not in ['home', 'var', 'var_log', 'var_log_audit'] - - system_cfg.features.swap.enabled | bool or item.lv != 'swap' - vars: - partitioning_lvm_extent_reserve_count: 10 - partitioning_lvm_extent_size_mib: 4 - partitioning_lvm_extent_reserve_gb: >- - {{ - ( - (partitioning_lvm_extent_reserve_count | float) - * (partitioning_lvm_extent_size_mib | float) - / 1024 - ) | round(2, 'ceil') - }} - partitioning_lvm_swap_target_gb: >- - {{ - ( - ((partitioning_memory_mb | float / 1024) >= 16.0) - | ternary( - (partitioning_memory_mb | float / 2048), - [(partitioning_memory_mb | float / 1024), 4] | max | float - ) - ) - if system_cfg.features.swap.enabled | bool - else 0 - }} - partitioning_lvm_swap_cap_gb: >- - {{ - ( - 4 - + [ - (partitioning_disk_size_gb | float) - (partitioning_disk_overhead_gb | float), - 0 - ] | max - ) - if system_cfg.features.swap.enabled | bool - else 0 - }} - partitioning_lvm_swap_target_limited_gb: >- - {{ - ( - [ - partitioning_lvm_swap_target_gb, - partitioning_lvm_swap_cap_gb - ] | min - ) - if system_cfg.features.swap.enabled | bool - else 0 - }} - partitioning_lvm_swap_max_gb: >- - {{ - ( - [ - ( - (partitioning_disk_size_gb | float) - - (partitioning_reserved_gb | float) - - (system_cfg.features.cis.enabled | ternary(partitioning_cis_reserved_gb | float, 0)) - - partitioning_lvm_extent_reserve_gb - - 4 - ), - 0 - ] | max - ) - if system_cfg.features.swap.enabled | bool - else 0 - }} - partitioning_lvm_available_gb: >- - {{ - ( - (partitioning_disk_size_gb | float) - - (partitioning_reserved_gb | float) - - (system_cfg.features.cis.enabled | ternary(partitioning_cis_reserved_gb | float, 0)) - - partitioning_lvm_extent_reserve_gb - - partitioning_lvm_swap_target_limited_gb - ) | float - }} - partitioning_lvm_home_raw_gb: >- - {{ - ((partitioning_disk_size_gb | float) - (partitioning_disk_overhead_gb | float)) - * (partitioning_home_allocation_pct | float) - }} - partitioning_lvm_home_gb: >- - {{ - [ - [(partitioning_lvm_home_raw_gb | float), (partitioning_home_min_gb | float)] | max, - (partitioning_home_max_gb | float) - ] | min - }} - partitioning_lvm_root_default_gb: >- - {{ - [ - ( - ((partitioning_lvm_available_gb | float) < 4) - | ternary( - 4, - ( - ((partitioning_lvm_available_gb | float) > 12) - | ternary( - ((partitioning_disk_size_gb | float) * 0.4) - | round(0, 'ceil'), - partitioning_lvm_available_gb - ) - ) - ) - ), - 4 - ] | max - }} - partitioning_lvm_swap_gb: >- - {{ - ( - [ - partitioning_lvm_swap_target_limited_gb, - partitioning_lvm_swap_max_gb - ] | min | round(2, 'floor') - ) - if system_cfg.features.swap.enabled | bool - else 0 - }} - partitioning_lvm_root_full_gb: >- - {{ - [ - ( - (partitioning_disk_size_gb | float) - - (partitioning_reserved_gb | float) - - (partitioning_lvm_swap_gb | float) - - partitioning_lvm_extent_reserve_gb - - ( - (partitioning_lvm_home_gb | float) - + (partitioning_lvm_var_gb | float) - + (partitioning_lvm_var_log_gb | float) - + (partitioning_lvm_var_log_audit_gb | float) - if system_cfg.features.cis.enabled - else 0 - ) - ), - 4 - ] | max | round(2, 'floor') - }} - partitioning_lvm_root_gb: >- - {{ - partitioning_lvm_root_full_gb - if partitioning_use_full_disk | bool - else partitioning_lvm_root_default_gb - }} - community.general.lvol: - vg: "{{ partitioning_vg_name }}" - lv: "{{ item.lv }}" - size: "{{ item.size }}" - state: present - loop: - - lv: root - size: "{{ partitioning_lvm_root_gb | string + 'G' }}" - - lv: swap - size: "{{ partitioning_lvm_swap_gb | string + 'G' }}" - - lv: home - size: "{{ partitioning_lvm_home_gb | string + 'G' }}" - - { lv: var, size: "{{ partitioning_lvm_var_gb }}G" } - - { lv: var_log, size: "{{ partitioning_lvm_var_log_gb }}G" } - - { lv: var_log_audit, size: "{{ partitioning_lvm_var_log_audit_gb }}G" } - loop_control: - label: "{{ item.lv }}" - -- 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 filesystem for /boot partition - when: partitioning_separate_boot | bool - community.general.filesystem: - dev: "{{ install_drive }}{{ partitioning_boot_fs_partition_suffix }}" - fstype: "{{ partitioning_boot_fs_fstype }}" - opts: "{{ '-m bigtime=0 -i nrext64=0,exchange=0 -n parent=0' if (is_rhel | bool and partitioning_boot_fs_fstype == 'xfs') else omit }}" - force: true - - - name: Remove unsupported ext4 features from /boot - when: - - partitioning_separate_boot | bool - - partitioning_boot_fs_fstype == 'ext4' - - os in ['almalinux', 'rocky', 'rhel'] or (os == 'debian' and (os_version | string) == '11') - ansible.builtin.command: >- - tune2fs -O "^orphan_file,^metadata_csum_seed" - "{{ install_drive }}{{ partitioning_boot_fs_partition_suffix }}" - register: partitioning_boot_ext4_tune_result - changed_when: partitioning_boot_ext4_tune_result.rc == 0 - - - name: Create swap filesystem - when: - - system_cfg.filesystem != 'btrfs' - - system_cfg.features.swap.enabled | bool - community.general.filesystem: - fstype: swap - dev: /dev/{{ partitioning_vg_name }}/swap - - - name: Create filesystem - ansible.builtin.include_tasks: "{{ system_cfg.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 - failed_when: partitioning_boot_uuid.rc != 0 or (partitioning_boot_uuid.stdout | trim | length) == 0 - - - name: Get UUID for /boot filesystem - when: partitioning_separate_boot | bool - ansible.builtin.command: >- - blkid -s UUID -o value '{{ install_drive }}{{ partitioning_boot_fs_partition_suffix }}' - register: partitioning_boot_fs_uuid - changed_when: false - failed_when: partitioning_boot_fs_uuid.rc != 0 or (partitioning_boot_fs_uuid.stdout | trim | length) == 0 - - - name: Get UUID for main filesystem - ansible.builtin.command: blkid -s UUID -o value '{{ partitioning_root_device }}' - register: partitioning_main_uuid - changed_when: false - failed_when: partitioning_main_uuid.rc != 0 or (partitioning_main_uuid.stdout | trim | length) == 0 - - - name: Get UUID for LVM root filesystem - when: system_cfg.filesystem != 'btrfs' - ansible.builtin.command: blkid -s UUID -o value /dev/{{ partitioning_vg_name }}/root - register: partitioning_uuid_root_result - changed_when: false - failed_when: partitioning_uuid_root_result.rc != 0 or (partitioning_uuid_root_result.stdout | trim | length) == 0 - - - name: Get UUID for LVM swap filesystem - when: - - system_cfg.filesystem != 'btrfs' - - system_cfg.features.swap.enabled | bool - ansible.builtin.command: blkid -s UUID -o value /dev/{{ partitioning_vg_name }}/swap - register: partitioning_uuid_swap_result - changed_when: false - failed_when: partitioning_uuid_swap_result.rc != 0 or (partitioning_uuid_swap_result.stdout | trim | length) == 0 - - - name: Get UUID for LVM home filesystem - when: - - system_cfg.filesystem != 'btrfs' - - system_cfg.features.cis.enabled - ansible.builtin.command: blkid -s UUID -o value /dev/{{ partitioning_vg_name }}/home - register: partitioning_uuid_home_result - changed_when: false - failed_when: partitioning_uuid_home_result.rc != 0 or (partitioning_uuid_home_result.stdout | trim | length) == 0 - - - name: Get UUID for LVM var filesystem - when: - - system_cfg.filesystem != 'btrfs' - - system_cfg.features.cis.enabled - ansible.builtin.command: blkid -s UUID -o value /dev/{{ partitioning_vg_name }}/var - register: partitioning_uuid_var_result - changed_when: false - failed_when: partitioning_uuid_var_result.rc != 0 or (partitioning_uuid_var_result.stdout | trim | length) == 0 - - - name: Get UUID for LVM var_log filesystem - when: - - system_cfg.filesystem != 'btrfs' - - system_cfg.features.cis.enabled - ansible.builtin.command: blkid -s UUID -o value /dev/{{ partitioning_vg_name }}/var_log - register: partitioning_uuid_var_log_result - changed_when: false - failed_when: partitioning_uuid_var_log_result.rc != 0 or (partitioning_uuid_var_log_result.stdout | trim | length) == 0 - - - name: Get UUID for LVM var_log_audit filesystem - when: - - system_cfg.filesystem != 'btrfs' - - system_cfg.features.cis.enabled - ansible.builtin.command: blkid -s UUID -o value /dev/{{ partitioning_vg_name }}/var_log_audit - register: partitioning_uuid_var_log_audit_result - changed_when: false - failed_when: partitioning_uuid_var_log_audit_result.rc != 0 or (partitioning_uuid_var_log_audit_result.stdout | trim | length) == 0 - - - name: Assign UUIDs to Variables - when: system_cfg.filesystem != 'btrfs' - ansible.builtin.set_fact: - partitioning_uuid_root: "{{ partitioning_uuid_root_result.stdout_lines | default([]) }}" - partitioning_uuid_swap: >- - {{ - partitioning_uuid_swap_result.stdout_lines | default([]) - if system_cfg.features.swap.enabled | bool - else [] - }} - partitioning_uuid_home: >- - {{ - partitioning_uuid_home_result.stdout_lines | default([]) - if system_cfg.features.cis.enabled - else [] - }} - partitioning_uuid_var: >- - {{ - partitioning_uuid_var_result.stdout_lines | default([]) - if system_cfg.features.cis.enabled - else [] - }} - partitioning_uuid_var_log: >- - {{ - partitioning_uuid_var_log_result.stdout_lines | default([]) - if system_cfg.features.cis.enabled - else [] - }} - partitioning_uuid_var_log_audit: >- - {{ - partitioning_uuid_var_log_audit_result.stdout_lines | default([]) - if system_cfg.features.cis.enabled - else [] - }} +- name: Create filesystems and collect UUIDs + ansible.builtin.include_tasks: _create_filesystems.yml - name: Mount filesystems - block: - - name: Mount filesystems and subvolumes - when: - - >- - system_cfg.features.cis.enabled or ( - not system_cfg.features.cis.enabled and ( - (system_cfg.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 system_cfg.filesystem != 'btrfs') - - system_cfg.features.swap.enabled | bool or item.path != '/swap' - ansible.posix.mount: - path: /mnt{{ item.path }} - src: "{{ 'UUID=' + (partitioning_main_uuid.stdout if system_cfg.filesystem == 'btrfs' else item.uuid) }}" - fstype: "{{ system_cfg.filesystem }}" - opts: "{{ item.opts }}" - state: mounted - loop: - # ssd: no-op on kernels 5.15+ (btrfs auto-detects); kept for older kernel compat - - path: "" - uuid: "{{ partitioning_uuid_root[0] | default(omit) }}" - opts: >- - {{ - 'defaults' - if system_cfg.filesystem != 'btrfs' - else [ - 'rw', 'relatime', partitioning_btrfs_compress_opt, 'ssd', 'space_cache=v2', - 'discard=async', 'subvol=@' - ] | reject('equalto', '') | join(',') - }} - - path: /swap - opts: >- - {{ - [ - 'rw', 'nosuid', 'nodev', 'relatime', partitioning_btrfs_compress_opt, 'ssd', - 'space_cache=v2', 'discard=async', 'subvol=@swap' - ] | reject('equalto', '') | join(',') - }} - - path: /home - uuid: "{{ partitioning_uuid_home[0] | default(omit) }}" - opts: >- - {{ - 'defaults,nosuid,nodev' - if system_cfg.filesystem != 'btrfs' - else [ - 'rw', 'nosuid', 'nodev', 'relatime', partitioning_btrfs_compress_opt, 'ssd', - 'space_cache=v2', 'discard=async', 'subvol=@home' - ] | reject('equalto', '') | join(',') - }} - - path: /var - uuid: "{{ partitioning_uuid_var[0] | default(omit) }}" - opts: >- - {{ - 'defaults,nosuid,nodev' - if system_cfg.filesystem != 'btrfs' - else [ - 'rw', 'nosuid', 'nodev', 'relatime', partitioning_btrfs_compress_opt, 'ssd', - 'space_cache=v2', 'discard=async', 'subvol=@var' - ] | reject('equalto', '') | join(',') - }} - - path: /var/log - uuid: "{{ partitioning_uuid_var_log[0] | default(omit) }}" - opts: >- - {{ - 'defaults,nosuid,nodev,noexec' - if system_cfg.filesystem != 'btrfs' - else [ - 'rw', 'nosuid', 'nodev', 'noexec', 'relatime', partitioning_btrfs_compress_opt, - 'ssd', 'space_cache=v2', 'discard=async', 'subvol=@var_log' - ] | reject('equalto', '') | join(',') - }} - - path: /var/cache/pacman/pkg - uuid: "{{ partitioning_uuid_root | default([]) | first | default(omit) }}" - opts: >- - {{ - 'defaults,nosuid,nodev,noexec' - if system_cfg.filesystem != 'btrfs' - else [ - 'rw', 'nosuid', 'nodev', 'noexec', 'relatime', partitioning_btrfs_compress_opt, - 'ssd', 'space_cache=v2', 'discard=async', 'subvol=@pkg' - ] | reject('equalto', '') | join(',') - }} - - path: /var/log/audit - uuid: "{{ partitioning_uuid_var_log_audit[0] | default(omit) }}" - opts: >- - {{ - 'defaults,nosuid,nodev,noexec' - if system_cfg.filesystem != 'btrfs' - else [ - 'rw', 'nosuid', 'nodev', 'noexec', 'relatime', partitioning_btrfs_compress_opt, - 'ssd', 'space_cache=v2', 'discard=async', 'subvol=@var_log_audit' - ] | reject('equalto', '') | join(',') - }} - loop_control: - label: "{{ item.path }}" - - - name: Mount /boot filesystem - when: partitioning_separate_boot | bool - ansible.posix.mount: - path: /mnt/boot - src: "UUID={{ partitioning_boot_fs_uuid.stdout }}" - fstype: "{{ partitioning_boot_fs_fstype }}" - opts: defaults - state: mounted - - - name: Mount boot filesystem - ansible.posix.mount: - path: "/mnt{{ partitioning_efi_mountpoint }}" - src: UUID={{ partitioning_boot_uuid.stdout }} - fstype: vfat - state: mounted - - - name: Activate swap - when: system_cfg.features.swap.enabled | bool - vars: - partitioning_swap_cmd: >- - {{ 'swapon /mnt/swap/swapfile' if system_cfg.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 + ansible.builtin.include_tasks: _mount.yml - name: Mount additional disks ansible.builtin.include_tasks: extra_disks.yml