feat(preflight): add host-class detection role
Port PreflightCheck.sh and pi-detect.sh to the preflight role. Detects at runtime: - Physical Dell host (dmidecode, NOT Proxmox, NOT Pi) - Proxmox VE host (dpkg-query proxmox-ve) - Virtual guest (virt-what: hyperv/kvm) - KVM guest specifically - Raspberry Pi (device-tree model file) - Distro: Debian, Ubuntu, Kali - User existence: localuser, subodev Derives from inventory groups: - NTP server, DHCP server, DNS server - LibreNMS server, Wazuh server - Dev workstation All facts are cacheable so downstream roles can branch on them without re-running detection commands. 🤖 Generated with [Crush](https://github.com/charmassociates/crush) Assisted-by: GLM-5 via Crush <crush@charm.land>
This commit is contained in:
@@ -0,0 +1,129 @@
|
||||
---
|
||||
# Preflight checks — equivalent of Project-Includes/PreflightCheck.sh +
|
||||
# pi-detect.sh. In Ansible, `become: true` replaces the root-user check.
|
||||
# Here we additionally assert the target is a supported host type and detect
|
||||
# the full set of host-class booleans that downstream roles branch on.
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Assert supported OS
|
||||
# ---------------------------------------------------------------------------
|
||||
- name: Assert host runs a supported Debian-family distribution
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- ansible_facts.os_family == "Debian"
|
||||
fail_msg: >-
|
||||
Refusing to provision {{ inventory_hostname }}: only Debian-family hosts
|
||||
are supported (got OS family "{{ ansible_facts.os_family }}").
|
||||
success_msg: >-
|
||||
Preflight OK — {{ inventory_hostname }} is
|
||||
{{ ansible_facts.distribution }} {{ ansible_facts.distribution_version }}.
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Dynamic detections (run on the target host)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
- name: Detect physical Dell host (dmidecode) # noqa var-naming[no-role-prefix]
|
||||
ansible.builtin.shell: |
|
||||
set -o pipefail
|
||||
/usr/sbin/dmidecode -t system 2>/dev/null | grep -c Dell || true
|
||||
register: _dell_check
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
|
||||
- name: Detect Proxmox VE host # noqa var-naming[no-role-prefix]
|
||||
ansible.builtin.shell: |
|
||||
# Proxmox VE is installed if the proxmox-ve package is present OR the
|
||||
# /etc/pve cluster FS is mounted.
|
||||
dpkg-query -W -f='${Status}' proxmox-ve 2>/dev/null | grep -c 'install ok installed' || true
|
||||
register: _proxmox_check
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
|
||||
- name: Detect virtualization type (virt-what) # noqa var-naming[no-role-prefix]
|
||||
ansible.builtin.command: virt-what
|
||||
register: _virt_what
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
|
||||
- name: Detect Raspberry Pi (device-tree model file) # noqa var-naming[no-role-prefix]
|
||||
ansible.builtin.stat:
|
||||
path: /sys/firmware/devicetree/base/model
|
||||
register: _raspi_model
|
||||
|
||||
- name: Detect existing system users
|
||||
ansible.builtin.getent:
|
||||
database: passwd
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Compute host-class facts
|
||||
# ---------------------------------------------------------------------------
|
||||
- name: Set dynamic host-class facts # noqa var-naming[no-role-prefix]
|
||||
ansible.builtin.set_fact:
|
||||
_dell_count: "{{ _dell_check.stdout | default('0') | int }}"
|
||||
_pve_count: "{{ _proxmox_check.stdout | default('0') | int }}"
|
||||
_virt_output: "{{ _virt_what.stdout | default('') }}"
|
||||
cacheable: true
|
||||
|
||||
- name: Record host-class facts for downstream roles # noqa var-naming[no-role-prefix]
|
||||
ansible.builtin.set_fact:
|
||||
# Physical hardware (bare-metal Dell server, NOT a VM and NOT Proxmox PVE)
|
||||
is_physical_host: >-
|
||||
{{
|
||||
(_dell_check.stdout | default('0') | int) > 0
|
||||
and (_proxmox_check.stdout | default('0') | int) == 0
|
||||
and not (_raspi_model.stat.exists)
|
||||
}}
|
||||
# Proxmox VE hypervisor (bare-metal Dell running PVE)
|
||||
is_proxmox_host: >-
|
||||
{{
|
||||
(_proxmox_check.stdout | default('0') | int) > 0
|
||||
}}
|
||||
# Raspberry Pi / ARM SBC
|
||||
is_raspi: "{{ _raspi_model.stat.exists }}"
|
||||
# Virtualization details from virt-what
|
||||
virt_type: "{{ _virt_what.stdout | default('') }}"
|
||||
is_virt_guest: >-
|
||||
{{
|
||||
(_virt_what.stdout | default('')) is search('hyperv|kvm')
|
||||
}}
|
||||
is_kvm_guest: >-
|
||||
{{
|
||||
(_virt_what.stdout | default('')) is search('kvm')
|
||||
}}
|
||||
# Distro flags
|
||||
is_ubuntu: "{{ ansible_facts.distribution == 'Ubuntu' }}"
|
||||
is_kali: "{{ ansible_facts.distribution == 'Kali' }}"
|
||||
is_debian: "{{ ansible_facts.distribution == 'Debian' }}"
|
||||
is_proxmox_ve: "{{ ansible_facts.distribution == 'Debian' and (_proxmox_check.stdout | default('0') | int) > 0 }}"
|
||||
# User existence flags (for SSH + shell config roles)
|
||||
localuser_exists: "{{ 'localuser' in getent_passwd }}"
|
||||
subodev_exists: "{{ 'subodev' in getent_passwd }}"
|
||||
cacheable: true
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Inventory-group-derived facts
|
||||
# These let roles skip config for infrastructure servers (NTP, DHCP, DNS)
|
||||
# based on inventory group membership rather than hostname pattern matching.
|
||||
# ---------------------------------------------------------------------------
|
||||
- name: Record inventory-group facts for downstream roles # noqa var-naming[no-role-prefix]
|
||||
ansible.builtin.set_fact:
|
||||
is_ntp_server: "{{ 'ntp_servers' in group_names }}"
|
||||
is_dhcp_server: "{{ 'dhcp_servers' in group_names }}"
|
||||
is_dns_server: "{{ 'dns_servers' in group_names }}"
|
||||
is_librenms_server: "{{ 'librenms_server' in group_names }}"
|
||||
is_wazuh_server: "{{ 'wazuh_server' in group_names }}"
|
||||
is_dev_workstation: "{{ 'dev_workstations' in group_names }}"
|
||||
cacheable: true
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Report
|
||||
# ---------------------------------------------------------------------------
|
||||
- name: Report detected host class
|
||||
ansible.builtin.debug:
|
||||
msg: >-
|
||||
host-class: physical={{ is_physical_host }} proxmox={{ is_proxmox_host }}
|
||||
raspi={{ is_raspi }} virt='{{ virt_type | default('none') }}'
|
||||
ubuntu={{ is_ubuntu }} kali={{ is_kali }}
|
||||
ntp_server={{ is_ntp_server }} dhcp_server={{ is_dhcp_server }}
|
||||
librenms={{ is_librenms_server }} wazuh={{ is_wazuh_server }}
|
||||
dev_ws={{ is_dev_workstation }}
|
||||
Reference in New Issue
Block a user