Compare commits
81
Commits
master
..
332dfeb6f1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
332dfeb6f1 | ||
|
|
19029bdc8b | ||
|
|
9c4a86c0ec | ||
|
|
723f0516da | ||
|
|
975384661e | ||
|
|
ad25bec9fd | ||
|
|
6240217318 | ||
|
|
1c00ec9370 | ||
|
|
371d5a0acd | ||
|
|
41ccf2a5b9 | ||
|
|
8f9cfe3b2f | ||
|
|
6a75237197 | ||
|
|
b04aad12fb | ||
|
|
4fff9f8d80 | ||
|
|
7f12a0f3d8 | ||
|
|
ceb2237bbb | ||
|
|
477c8379c4 | ||
|
|
579c499c02 | ||
|
|
89e366d0f0 | ||
|
|
6fe843355e | ||
|
|
441876fab9 | ||
|
|
00acd4d200 | ||
|
|
d922efd2e4 | ||
|
|
939c5c741f | ||
|
|
2c35409519 | ||
|
|
d2a19cfd5c | ||
|
|
44f5adc682 | ||
|
|
0185797af9 | ||
|
|
e0ecf628cd | ||
|
|
37df881daa | ||
|
|
55b21eae5d | ||
|
|
b1e938b7f0 | ||
|
|
c843f5289b | ||
|
|
9757ed3785 | ||
|
|
876e90ce2b | ||
|
|
7c44cb1ff0 | ||
|
|
5d0630a386 | ||
|
|
3eaf918a53 | ||
|
|
382e82ff85 | ||
|
|
db7dc53bd7 | ||
|
|
7d45f25a7e | ||
|
|
3880b8f41e | ||
|
|
dc3c4a901f | ||
|
|
6bfaa0aa2b | ||
|
|
5dc0424acb | ||
|
|
c12332a853 | ||
|
|
5ace4577a2 | ||
|
|
c0ff01ef40 | ||
|
|
57417514e3 | ||
|
|
0928588c1f | ||
|
|
6d622f2db4 | ||
|
|
b11d65a6f3 | ||
|
|
3623fc292c | ||
|
|
dfca7ec94b | ||
|
|
e8be84bf49 | ||
|
|
322cc0b1ce | ||
|
|
4b38754f8b | ||
|
|
a6bc7ffe04 | ||
|
|
c529e71ebc | ||
|
|
cb46de2b6d | ||
|
|
9169117b25 | ||
|
|
6c94c519fb | ||
|
|
efd96a42b8 | ||
|
|
68661c3cca | ||
|
|
1db20c7ac0 | ||
|
|
7b155b427b | ||
|
|
ca8721e98f | ||
|
|
cdb2559d8f | ||
|
|
443f6623df | ||
|
|
6cf418fe00 | ||
|
|
47ec5fe621 | ||
|
|
240f945cce | ||
|
|
663a04556f | ||
|
|
6febd1acf1 | ||
|
|
008187860c | ||
|
|
cd1be6b5e1 | ||
|
|
15be6149fd | ||
|
|
ca29ad200d | ||
|
|
8079099cee | ||
|
|
9e79185b07 | ||
|
|
b88bf2860f |
@@ -538,8 +538,6 @@ When `hypervisor.type: vmware` uses the `vmware_tools` connection:
|
|||||||
|
|
||||||
`system.disks[0]` is the OS disk (no `mount.path`). Additional entries define data disks.
|
`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 |
|
| Key | Type | Description |
|
||||||
| ------------- | ------ | ------------------------------------------------------ |
|
| ------------- | ------ | ------------------------------------------------------ |
|
||||||
| `size` | number | Disk size in GB (required for virtual) |
|
| `size` | number | Disk size in GB (required for virtual) |
|
||||||
|
|||||||
@@ -206,7 +206,6 @@ bootstrap_debian:
|
|||||||
- openssh-server
|
- openssh-server
|
||||||
- python3
|
- python3
|
||||||
- xfsprogs
|
- xfsprogs
|
||||||
- xz-utils
|
|
||||||
extra:
|
extra:
|
||||||
- bat
|
- bat
|
||||||
- curl
|
- curl
|
||||||
@@ -259,7 +258,6 @@ bootstrap_ubuntu:
|
|||||||
- openssh-server
|
- openssh-server
|
||||||
- python3
|
- python3
|
||||||
- xfsprogs
|
- xfsprogs
|
||||||
- xz-utils
|
|
||||||
extra:
|
extra:
|
||||||
- bash-completion
|
- bash-completion
|
||||||
- bat
|
- bat
|
||||||
|
|||||||
@@ -12,21 +12,6 @@
|
|||||||
and 'No such file or directory' not in (_firewall_enable.stderr | default(''))
|
and 'No such file or directory' not in (_firewall_enable.stderr | default(''))
|
||||||
and 'does not exist' not in (_firewall_enable.stderr | default(''))
|
and 'does not exist' not in (_firewall_enable.stderr | default(''))
|
||||||
|
|
||||||
# Distro base sets ship the daemon preset-enabled (RHEL @core pulls firewalld in),
|
|
||||||
# so opting out has to disable the unit, not merely skip enabling it.
|
|
||||||
- name: Disable the firewall daemon in the install chroot
|
|
||||||
when:
|
|
||||||
- firewall_phase == 'install'
|
|
||||||
- _configuration_platform.init_system == 'systemd'
|
|
||||||
- not system_cfg.features.firewall.enabled | bool
|
|
||||||
ansible.builtin.command: "{{ chroot_command }} systemctl disable {{ system_cfg.features.firewall.backend }}"
|
|
||||||
register: _firewall_disable
|
|
||||||
changed_when: "'Removed' in (_firewall_disable.stderr | default(''))"
|
|
||||||
failed_when: >-
|
|
||||||
_firewall_disable.rc != 0
|
|
||||||
and 'No such file or directory' not in (_firewall_disable.stderr | default(''))
|
|
||||||
and 'does not exist' not in (_firewall_disable.stderr | default(''))
|
|
||||||
|
|
||||||
# ufw's CLI needs a running kernel and is a no-op in the chroot (leaves ENABLED=no),
|
# ufw's CLI needs a running kernel and is a no-op in the chroot (leaves ENABLED=no),
|
||||||
# so its activation and SSH rule are applied here, after reboot.
|
# so its activation and SSH rule are applied here, after reboot.
|
||||||
- name: Allow SSH through ufw before enabling
|
- name: Allow SSH through ufw before enabling
|
||||||
|
|||||||
@@ -43,14 +43,11 @@
|
|||||||
}}
|
}}
|
||||||
grub_root_flags: >-
|
grub_root_flags: >-
|
||||||
{{ ['rootflags=subvol=@'] if system_cfg.filesystem == 'btrfs' else [] }}
|
{{ ['rootflags=subvol=@'] if system_cfg.filesystem == 'btrfs' else [] }}
|
||||||
grub_selinux_args: >-
|
|
||||||
{{ [] if system_cfg.features.selinux.enabled | bool else ['selinux=0'] }}
|
|
||||||
# String-concat (not list-concat like grub_kernel_cmdline_base below): ansible-lint's
|
# String-concat (not list-concat like grub_kernel_cmdline_base below): ansible-lint's
|
||||||
# jinja render trips on list+list when grub_lvm_args leads the expression here.
|
# jinja render trips on list+list when grub_lvm_args leads the expression here.
|
||||||
grub_cmdline_linux_base: >-
|
grub_cmdline_linux_base: >-
|
||||||
{{
|
{{
|
||||||
((grub_lvm_args | join(' ')) ~ ' ' ~ (grub_selinux_args | join(' ')) ~ ' '
|
((grub_lvm_args | join(' ')) ~ ' ' ~ (_hardware_profile_kernel_params | default([]) | join(' '))) | trim
|
||||||
~ (_hardware_profile_kernel_params | default([]) | join(' '))) | trim
|
|
||||||
}}
|
}}
|
||||||
grub_kernel_cmdline_base: >-
|
grub_kernel_cmdline_base: >-
|
||||||
{{
|
{{
|
||||||
@@ -60,7 +57,6 @@
|
|||||||
+ ['ro']
|
+ ['ro']
|
||||||
+ grub_lvm_args
|
+ grub_lvm_args
|
||||||
+ grub_root_flags
|
+ grub_root_flags
|
||||||
+ grub_selinux_args
|
|
||||||
+ (_hardware_profile_kernel_params | default([]))
|
+ (_hardware_profile_kernel_params | default([]))
|
||||||
)
|
)
|
||||||
| join(' ')
|
| join(' ')
|
||||||
|
|||||||
@@ -22,12 +22,10 @@
|
|||||||
mode: "0644"
|
mode: "0644"
|
||||||
|
|
||||||
# Fedora: setfiles segfaults during bootstrap chroot relabeling, so SELinux
|
# Fedora: setfiles segfaults during bootstrap chroot relabeling, so SELinux
|
||||||
# is left permissive and expected to relabel on first boot. Opting out writes
|
# is left permissive and expected to relabel on first boot.
|
||||||
# disabled here and selinux=0 on the kernel cmdline (grub.yml), the only form
|
- name: Disable SELinux
|
||||||
# EL9 honours.
|
|
||||||
- name: Set the SELinux mode
|
|
||||||
when: os == "fedora" or not system_cfg.features.selinux.enabled | bool
|
when: os == "fedora" or not system_cfg.features.selinux.enabled | bool
|
||||||
ansible.builtin.lineinfile:
|
ansible.builtin.lineinfile:
|
||||||
path: /mnt/etc/selinux/config
|
path: /mnt/etc/selinux/config
|
||||||
regexp: ^SELINUX=
|
regexp: ^SELINUX=
|
||||||
line: "SELINUX={{ 'permissive' if system_cfg.features.selinux.enabled | bool else 'disabled' }}"
|
line: SELINUX=permissive
|
||||||
|
|||||||
@@ -94,7 +94,6 @@
|
|||||||
|
|
||||||
- name: Set install_drive from primary disk
|
- name: Set install_drive from primary disk
|
||||||
when:
|
when:
|
||||||
- install_drive is not defined
|
|
||||||
- system_disks_cfg | length > 0
|
- system_disks_cfg | length > 0
|
||||||
- system_disks_cfg[0].device | string | length > 0
|
- system_disks_cfg[0].device | string | length > 0
|
||||||
ansible.builtin.set_fact:
|
ansible.builtin.set_fact:
|
||||||
|
|||||||
@@ -35,12 +35,10 @@
|
|||||||
}, recursive=True)
|
}, recursive=True)
|
||||||
}}
|
}}
|
||||||
|
|
||||||
# Keyed on os, not hostname: inventories set hostname themselves, and doing so
|
|
||||||
# would otherwise skip enrichment and leave os undefined for validation.
|
|
||||||
- name: Check if pre-computed system_cfg needs enrichment
|
- name: Check if pre-computed system_cfg needs enrichment
|
||||||
when: system_cfg is defined
|
when: system_cfg is defined
|
||||||
ansible.builtin.set_fact:
|
ansible.builtin.set_fact:
|
||||||
_bootstrap_needs_enrichment: "{{ os is not defined }}"
|
_bootstrap_needs_enrichment: "{{ hostname is not defined }}"
|
||||||
|
|
||||||
- name: Merge pre-computed system_cfg with bootstrap system_defaults
|
- name: Merge pre-computed system_cfg with bootstrap system_defaults
|
||||||
when:
|
when:
|
||||||
@@ -81,7 +79,9 @@
|
|||||||
os_version: "{{ system_cfg.version | default('') | string }}"
|
os_version: "{{ system_cfg.version | default('') | string }}"
|
||||||
|
|
||||||
- name: Normalize disk configuration (pre-computed system_cfg)
|
- name: Normalize disk configuration (pre-computed system_cfg)
|
||||||
when: system_cfg is defined
|
when:
|
||||||
|
- system_cfg is defined
|
||||||
|
- install_drive is not defined
|
||||||
ansible.builtin.include_tasks: _normalize_disks.yml
|
ansible.builtin.include_tasks: _normalize_disks.yml
|
||||||
|
|
||||||
# Runs on every path before validation, so an empty firewall.backend / content.source
|
# Runs on every path before validation, so an empty firewall.backend / content.source
|
||||||
|
|||||||
@@ -317,7 +317,7 @@
|
|||||||
_autologin: "{{ system_cfg.features.desktop.autologin | default(false) }}"
|
_autologin: "{{ system_cfg.features.desktop.autologin | default(false) }}"
|
||||||
ansible.builtin.assert:
|
ansible.builtin.assert:
|
||||||
that:
|
that:
|
||||||
- _autologin is boolean and not _autologin or (_autologin is string and _autologin | length > 0 and _autologin in system_cfg.users | map(attribute='name'))
|
- _autologin is boolean and not _autologin or (_autologin is string and _autologin | length > 0 and _autologin in system_cfg.users)
|
||||||
fail_msg: >-
|
fail_msg: >-
|
||||||
desktop.autologin must be false or a username string present in
|
desktop.autologin must be false or a username string present in
|
||||||
system.users; got '{{ _autologin }}'. Bool true is not accepted - the
|
system.users; got '{{ _autologin }}'. Bool true is not accepted - the
|
||||||
@@ -355,12 +355,14 @@
|
|||||||
|
|
||||||
- name: Validate at least one user with a password is defined
|
- name: Validate at least one user with a password is defined
|
||||||
vars:
|
vars:
|
||||||
_pw_users: "{{ system_cfg.users | selectattr('password', 'defined') | map(attribute='password') | map('string') | reject('equalto', '') | list }}"
|
_pw_users: "{{ system_cfg.users | dict2items | selectattr('value.password', 'defined') | list }}"
|
||||||
ansible.builtin.assert:
|
ansible.builtin.assert:
|
||||||
that:
|
that:
|
||||||
- system_cfg.users | default([]) | length > 0
|
- system_cfg.users | default({}) | length > 0
|
||||||
- _pw_users | length > 0
|
- _pw_users | length > 0
|
||||||
fail_msg: "At least one user with a non-empty password must be defined in system.users."
|
- _pw_users[0].key | string | length > 0
|
||||||
|
- _pw_users[0].value.password | string | length > 0
|
||||||
|
fail_msg: "At least one user with a password must be defined in system.users."
|
||||||
quiet: true
|
quiet: true
|
||||||
no_log: true
|
no_log: true
|
||||||
|
|
||||||
|
|||||||
@@ -1,61 +0,0 @@
|
|||||||
---
|
|
||||||
# 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,10 +1,4 @@
|
|||||||
---
|
---
|
||||||
- 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
|
- name: Detect system sizing
|
||||||
ansible.builtin.include_tasks: _detect_sizing.yml
|
ansible.builtin.include_tasks: _detect_sizing.yml
|
||||||
|
|
||||||
|
|||||||
@@ -50,9 +50,6 @@
|
|||||||
esxi_hostname: "{{ hypervisor_cfg.node }}"
|
esxi_hostname: "{{ hypervisor_cfg.node }}"
|
||||||
register: system_check_esxi
|
register: system_check_esxi
|
||||||
delegate_facts: true
|
delegate_facts: true
|
||||||
until: system_check_esxi.ansible_facts is defined
|
|
||||||
retries: 3
|
|
||||||
delay: 10
|
|
||||||
failed_when: false
|
failed_when: false
|
||||||
changed_when: false
|
changed_when: false
|
||||||
no_log: true
|
no_log: true
|
||||||
@@ -87,9 +84,6 @@
|
|||||||
community.vmware.vmware_datastore_info:
|
community.vmware.vmware_datastore_info:
|
||||||
cluster: "{{ hypervisor_cfg.cluster }}"
|
cluster: "{{ hypervisor_cfg.cluster }}"
|
||||||
register: system_check_cluster
|
register: system_check_cluster
|
||||||
until: system_check_cluster.datastores is defined
|
|
||||||
retries: 3
|
|
||||||
delay: 10
|
|
||||||
failed_when: false
|
failed_when: false
|
||||||
changed_when: false
|
changed_when: false
|
||||||
no_log: true
|
no_log: true
|
||||||
@@ -138,10 +132,6 @@
|
|||||||
path: "{{ item.path }}"
|
path: "{{ item.path }}"
|
||||||
state: file
|
state: file
|
||||||
register: system_check_media_files
|
register: system_check_media_files
|
||||||
# A missing file fails with status 404; a dropped vCenter connection fails with status None.
|
|
||||||
until: system_check_media_files is not failed or system_check_media_files.status is not none
|
|
||||||
retries: 3
|
|
||||||
delay: 10
|
|
||||||
failed_when: false
|
failed_when: false
|
||||||
changed_when: false
|
changed_when: false
|
||||||
loop: "{{ system_check_datastores_needed | rejectattr('source', 'equalto', 'hypervisor.storage') | list }}"
|
loop: "{{ system_check_datastores_needed | rejectattr('source', 'equalto', 'hypervisor.storage') | list }}"
|
||||||
|
|||||||
@@ -82,11 +82,6 @@
|
|||||||
name: "{{ hostname }}"
|
name: "{{ hostname }}"
|
||||||
folder: "{{ system_cfg.path if system_cfg.path | length > 0 else omit }}"
|
folder: "{{ system_cfg.path if system_cfg.path | length > 0 else omit }}"
|
||||||
register: system_check_vmware_check_result
|
register: system_check_vmware_check_result
|
||||||
until: >-
|
|
||||||
not system_check_vmware_check_result.failed
|
|
||||||
or (system_check_vmware_check_result.msg is search('non-existing VM'))
|
|
||||||
retries: 3
|
|
||||||
delay: 10
|
|
||||||
failed_when: false
|
failed_when: false
|
||||||
changed_when: false
|
changed_when: false
|
||||||
no_log: true
|
no_log: true
|
||||||
|
|||||||
Reference in New Issue
Block a user