Files
Ansible-Bootstrap/roles/partitioning/tasks/main.yml

653 lines
22 KiB
YAML

---
- name: Detect system memory for swap sizing
when:
- swap_enabled | bool
- partitioning_vm_memory is not defined or (partitioning_vm_memory | float) <= 0
- vm_memory is not defined or (vm_memory | 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:
- install_type == "physical"
- partitioning_vm_size is not defined or (partitioning_vm_size | float) <= 0
- vm_size is not defined or (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
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: "{{ partitioning_layout }}"
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 }}"
- 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 | 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 | 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 | 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_enabled or item.lv not in ['home', 'var', 'var_log', 'var_log_audit']
- swap_enabled | bool or item.lv != 'swap'
vars:
partitioning_lvm_swap_target_gb: >-
{{
(
[
(partitioning_vm_memory_effective | float / 1024),
4
] | max | float
)
if swap_enabled | bool
else 0
}}
partitioning_lvm_swap_cap_gb: >-
{{
(
4
+ [
(partitioning_vm_size_effective | float) - 20,
0
] | max
)
if swap_enabled | bool
else 0
}}
partitioning_lvm_swap_target_effective_gb: >-
{{
(
[
partitioning_lvm_swap_target_gb,
partitioning_lvm_swap_cap_gb
] | min
)
if swap_enabled | bool
else 0
}}
partitioning_lvm_swap_max_gb: >-
{{
(
[
(
(partitioning_vm_size_effective | float)
- (partitioning_reserved_gb | float)
- (cis_enabled | ternary(7.5, 0))
- 4
),
0
] | max
)
if swap_enabled | bool
else 0
}}
partitioning_lvm_available_gb: >-
{{
(
(partitioning_vm_size_effective | float)
- (partitioning_reserved_gb | float)
- (cis_enabled | ternary(7.5, 0))
- partitioning_lvm_swap_target_effective_gb
) | float
}}
partitioning_lvm_home_gb: >-
{{
([([(((partitioning_vm_size_effective | float) - 20) * 0.1), 2] | max), 20] | min)
}}
partitioning_lvm_root_default_gb: >-
{{
[
(
((partitioning_lvm_available_gb | float) < 4)
| ternary(
4,
(
((partitioning_lvm_available_gb | float) > 12)
| ternary(
((partitioning_vm_size_effective | float) * 0.4)
| round(0, 'ceil'),
partitioning_lvm_available_gb
)
)
)
),
4
] | max
}}
partitioning_lvm_swap_gb: >-
{{
(
[
partitioning_lvm_swap_target_effective_gb,
partitioning_lvm_swap_max_gb
] | min | round(2, 'floor')
)
if swap_enabled | bool
else 0
}}
partitioning_lvm_root_full_gb: >-
{{
[
(
(partitioning_vm_size_effective | float)
- (partitioning_reserved_gb | float)
- (partitioning_lvm_swap_gb | float)
- (
(partitioning_lvm_home_gb | float) + 5.5
if 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: sys
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: "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 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 }}"
force: true
- name: Remove unsupported ext4 features from /boot
when:
- partitioning_separate_boot | bool
- partitioning_boot_fs_fstype == 'ext4'
- os | lower in ['almalinux', 'debian11', 'rhel8', 'rhel9', 'rocky']
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:
- filesystem != 'btrfs'
- swap_enabled | bool
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 /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
- 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 UUID for LVM root filesystem
when: filesystem != 'btrfs'
ansible.builtin.command: blkid -s UUID -o value /dev/sys/root
register: partitioning_uuid_root_result
changed_when: false
- name: Get UUID for LVM swap filesystem
when:
- filesystem != 'btrfs'
- swap_enabled | bool
ansible.builtin.command: blkid -s UUID -o value /dev/sys/swap
register: partitioning_uuid_swap_result
changed_when: false
- name: Get UUID for LVM home filesystem
when:
- filesystem != 'btrfs'
- cis_enabled
ansible.builtin.command: blkid -s UUID -o value /dev/sys/home
register: partitioning_uuid_home_result
changed_when: false
- name: Get UUID for LVM var filesystem
when:
- filesystem != 'btrfs'
- cis_enabled
ansible.builtin.command: blkid -s UUID -o value /dev/sys/var
register: partitioning_uuid_var_result
changed_when: false
- name: Get UUID for LVM var_log filesystem
when:
- filesystem != 'btrfs'
- cis_enabled
ansible.builtin.command: blkid -s UUID -o value /dev/sys/var_log
register: partitioning_uuid_var_log_result
changed_when: false
- name: Get UUID for LVM var_log_audit filesystem
when:
- filesystem != 'btrfs'
- cis_enabled
ansible.builtin.command: blkid -s UUID -o value /dev/sys/var_log_audit
register: partitioning_uuid_var_log_audit_result
changed_when: false
- name: Assign UUIDs to Variables
when: 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 swap_enabled | bool
else ''
}}
partitioning_uuid_home: >-
{{
partitioning_uuid_home_result.stdout_lines | default([])
if cis_enabled
else ''
}}
partitioning_uuid_var: >-
{{
partitioning_uuid_var_result.stdout_lines | default([])
if cis_enabled
else ''
}}
partitioning_uuid_var_log: >-
{{
partitioning_uuid_var_log_result.stdout_lines | default([])
if cis_enabled
else ''
}}
partitioning_uuid_var_log_audit: >-
{{
partitioning_uuid_var_log_audit_result.stdout_lines | default([])
if cis_enabled
else ''
}}
- name: Mount filesystems
block:
- name: Mount filesystems and subvolumes
when:
- >-
cis_enabled or (
not cis_enabled 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')
- swap_enabled | bool or item.path != '/swap'
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', 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 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 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 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 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 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(',')
}}
- 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: swap_enabled | bool
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