feat: uniform system.content source schema across installers and repositories
This commit is contained in:
23
README.md
23
README.md
@@ -172,7 +172,7 @@ Top-level variables outside `system`/`hypervisor`.
|
||||
| `memory` | int | `0` | Memory in MiB (required for virtual) |
|
||||
| `balloon` | int | `0` | Balloon memory in MiB (Proxmox) |
|
||||
| `path` | string | -- | Hypervisor folder/path (falls back to `hypervisor.folder`) |
|
||||
| `mirror` | string | per-distro default | Override package mirror (Debian/Ubuntu) |
|
||||
| `content` | dict | see below | Package content source (mirror/DVD/Satellite, family-resolved) |
|
||||
| `packages` | list | `[]` | Additional packages installed post-reboot |
|
||||
| `network` | dict | see below | Network configuration |
|
||||
| `disks` | list | `[]` | Disk layout (see [Multi-Disk Schema](#46-multi-disk-schema)) |
|
||||
@@ -181,6 +181,25 @@ Top-level variables outside `system`/`hypervisor`.
|
||||
| `luks` | dict | see below | Encryption settings |
|
||||
| `features` | dict | see below | Feature toggles |
|
||||
|
||||
#### `system.content`
|
||||
|
||||
Uniform package content source, family-resolved. `source: ''` defaults to `dvd` on EL and `mirror` on Debian/Ubuntu/Arch. Satellite values come from inventory/vault only, never committed code.
|
||||
|
||||
| Key | Type | Default | Description |
|
||||
| -------------------------- | ------ | -------------- | ----------------------------------------------------------------- |
|
||||
| `source` | string | family default | `dvd`, `mirror`, `satellite`, or `none` |
|
||||
| `url` | string | family default | Mirror URL / EL `.repo` baseurl |
|
||||
| `proxy` | string | -- | `http://host:port` content proxy (dnf/apt/pacman) |
|
||||
| `gpgcheck` | bool | `true` | Repository GPG checking |
|
||||
| `satellite.host` | string | -- | EL Katello/Satellite hostname |
|
||||
| `satellite.ip` | string | -- | Optional `/etc/hosts` entry when DNS does not resolve the host |
|
||||
| `satellite.org` | string | -- | Organization label |
|
||||
| `satellite.activation_key` | string | -- | Activation key |
|
||||
| `satellite.ca_url` | string | derived | Katello CA RPM URL (default `https://<host>/pub/katello-ca-consumer-latest.noarch.rpm`) |
|
||||
| `satellite.service_level` | string | -- | syspurpose service level |
|
||||
| `satellite.environment` | string | -- | Lifecycle environment |
|
||||
| `satellite.install` | bool | `false` | `false`: base from DVD/mirror then register; `true`: install from Satellite |
|
||||
|
||||
#### `system.network`
|
||||
|
||||
| Key | Type | Default | Description |
|
||||
@@ -281,8 +300,6 @@ The bootstrap auto-switches to dracut when `method: tpm2` is set. Override via `
|
||||
| `banner.sudo` | bool | `true` | Sudo banner |
|
||||
| `chroot.tool` | string | `arch-chroot` | `arch-chroot`, `chroot`, or `systemd-nspawn` |
|
||||
| `initramfs.generator` | string | auto-detected | Override initramfs generator (see below) |
|
||||
| `rhel_repo.source` | string | `iso` | RHEL post-install repo source: `iso`, `satellite`, or `none` |
|
||||
| `rhel_repo.url` | string | -- | Satellite/custom repo URL when `source: satellite` |
|
||||
| `secure_boot.enabled` | bool | `false` | Enable Secure Boot (Arch via sbctl, others via shim) |
|
||||
| `secure_boot.method` | string | -- | Arch only: `sbctl` (default) or `uki` |
|
||||
| `desktop.*` | dict | see below | Desktop environment settings (see [4.2.5](#425-systemfeaturesdesktop)) |
|
||||
|
||||
@@ -1,9 +1,4 @@
|
||||
---
|
||||
- name: Refresh Arch keyring in the live environment
|
||||
ansible.builtin.command: pacman -Sy --noconfirm archlinux-keyring
|
||||
register: bootstrap_arch_keyring
|
||||
changed_when: bootstrap_arch_keyring.rc == 0
|
||||
|
||||
- name: Bootstrap ArchLinux
|
||||
vars:
|
||||
_config: "{{ lookup('vars', bootstrap_var_key) }}"
|
||||
@@ -13,7 +8,44 @@
|
||||
| reject('equalto', '')
|
||||
| list
|
||||
}}
|
||||
ansible.builtin.command: >-
|
||||
pacstrap /mnt {{ bootstrap_archlinux_packages | join(' ') }}
|
||||
register: bootstrap_result
|
||||
changed_when: bootstrap_result.rc == 0
|
||||
block:
|
||||
- name: Notify that mirror mode falls back to the public mirrorlist
|
||||
when:
|
||||
- system_cfg.content.source == 'mirror'
|
||||
- system_cfg.content.url | length == 0
|
||||
ansible.builtin.debug:
|
||||
msg: >-
|
||||
content.source is 'mirror' but content.url is empty: keeping the live
|
||||
ISO public mirrorlist (refreshed by reflector). Set content.url to pin
|
||||
a specific mirror.
|
||||
|
||||
- name: Point pacman at the content mirror
|
||||
when: system_cfg.content.url | length > 0
|
||||
ansible.builtin.copy:
|
||||
dest: /etc/pacman.d/mirrorlist
|
||||
content: "Server = {{ system_cfg.content.url }}/$repo/os/$arch\n"
|
||||
mode: "0644"
|
||||
|
||||
- name: Refresh Arch keyring in the live environment
|
||||
ansible.builtin.command: pacman -Sy --noconfirm archlinux-keyring
|
||||
environment:
|
||||
http_proxy: "{{ system_cfg.content.proxy }}"
|
||||
https_proxy: "{{ system_cfg.content.proxy }}"
|
||||
register: bootstrap_arch_keyring
|
||||
changed_when: bootstrap_arch_keyring.rc == 0
|
||||
|
||||
- name: Install Arch base system
|
||||
ansible.builtin.command: >-
|
||||
pacstrap /mnt {{ bootstrap_archlinux_packages | join(' ') }}
|
||||
environment:
|
||||
http_proxy: "{{ system_cfg.content.proxy }}"
|
||||
https_proxy: "{{ system_cfg.content.proxy }}"
|
||||
register: bootstrap_result
|
||||
changed_when: bootstrap_result.rc == 0
|
||||
|
||||
- name: Persist the content mirror in the installed system
|
||||
when: system_cfg.content.url | length > 0
|
||||
ansible.builtin.copy:
|
||||
dest: /mnt/etc/pacman.d/mirrorlist
|
||||
content: "Server = {{ system_cfg.content.url }}/$repo/os/$arch\n"
|
||||
mode: "0644"
|
||||
|
||||
@@ -43,7 +43,10 @@
|
||||
debootstrap --keyring=/usr/share/keyrings/debian-archive-keyring.gpg
|
||||
--include={{ bootstrap_debian_base_csv }}
|
||||
{{ bootstrap_debian_release }} /mnt
|
||||
{{ system_cfg.mirror | default('http://deb.debian.org/debian', true) }}
|
||||
{{ system_cfg.content.url }}
|
||||
environment:
|
||||
http_proxy: "{{ system_cfg.content.proxy }}"
|
||||
https_proxy: "{{ system_cfg.content.proxy }}"
|
||||
register: bootstrap_debian_base_result
|
||||
changed_when: bootstrap_debian_base_result.rc == 0
|
||||
|
||||
@@ -60,6 +63,10 @@
|
||||
Acquire::Retries "3";
|
||||
Acquire::http::Pipeline-Depth "10";
|
||||
APT::Install-Recommends "false";
|
||||
{% if system_cfg.content.proxy | length > 0 %}
|
||||
Acquire::http::Proxy "{{ system_cfg.content.proxy }}";
|
||||
Acquire::https::Proxy "{{ system_cfg.content.proxy }}";
|
||||
{% endif %}
|
||||
mode: "0644"
|
||||
|
||||
- name: Update package lists
|
||||
|
||||
@@ -24,12 +24,14 @@
|
||||
- "'grub2-common' not in (bootstrap_result.stderr | default(''))"
|
||||
|
||||
- name: Ensure chroot RHEL DVD directory exists
|
||||
when: system_cfg.content.source != 'mirror'
|
||||
ansible.builtin.file:
|
||||
path: /mnt/usr/local/install/redhat/dvd
|
||||
state: directory
|
||||
mode: "0755"
|
||||
|
||||
- name: Bind mount RHEL DVD into chroot
|
||||
when: system_cfg.content.source != 'mirror'
|
||||
ansible.posix.mount:
|
||||
src: /usr/local/install/redhat/dvd
|
||||
path: /mnt/usr/local/install/redhat/dvd
|
||||
|
||||
@@ -42,7 +42,10 @@
|
||||
--keyring=/usr/share/keyrings/ubuntu-archive-keyring.gpg
|
||||
--include={{ bootstrap_ubuntu_base_csv }}
|
||||
{{ bootstrap_ubuntu_release }} /mnt
|
||||
{{ system_cfg.mirror | default('http://archive.ubuntu.com/ubuntu', true) }}
|
||||
{{ system_cfg.content.url }}
|
||||
environment:
|
||||
http_proxy: "{{ system_cfg.content.proxy }}"
|
||||
https_proxy: "{{ system_cfg.content.proxy }}"
|
||||
register: bootstrap_ubuntu_base_result
|
||||
changed_when: bootstrap_ubuntu_base_result.rc == 0
|
||||
|
||||
@@ -59,6 +62,10 @@
|
||||
Acquire::Retries "3";
|
||||
Acquire::http::Pipeline-Depth "10";
|
||||
APT::Install-Recommends "false";
|
||||
{% if system_cfg.content.proxy | length > 0 %}
|
||||
Acquire::http::Proxy "{{ system_cfg.content.proxy }}";
|
||||
Acquire::https::Proxy "{{ system_cfg.content.proxy }}";
|
||||
{% endif %}
|
||||
mode: "0644"
|
||||
|
||||
- name: Update package lists
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Managed by Ansible.
|
||||
{% set release = bootstrap_debian_release %}
|
||||
{% set mirror = system_cfg.mirror | default('http://deb.debian.org/debian', true) %}
|
||||
{% set mirror = system_cfg.content.url | default('http://deb.debian.org/debian', true) %}
|
||||
{% set components = 'main contrib non-free non-free-firmware' %}
|
||||
|
||||
deb {{ mirror }} {{ release }} {{ components }}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Managed by Ansible.
|
||||
{% set release = bootstrap_ubuntu_release %}
|
||||
{% set mirror = system_cfg.mirror %}
|
||||
{% set mirror = system_cfg.content.url %}
|
||||
{% set components = 'main restricted universe multiverse' %}
|
||||
|
||||
deb {{ mirror }} {{ release }} {{ components }}
|
||||
|
||||
@@ -314,7 +314,6 @@ bootstrap_archlinux:
|
||||
- nfs-utils
|
||||
- ppp
|
||||
- python
|
||||
- reflector
|
||||
- rsync
|
||||
- sudo
|
||||
- tldr
|
||||
@@ -327,5 +326,6 @@ bootstrap_archlinux:
|
||||
(['openssh'] if system_cfg.features.ssh.enabled | bool else [])
|
||||
+ (['iptables-nft'] if system_cfg.features.firewall.toolkit == 'nftables' and system_cfg.features.firewall.enabled | bool else [])
|
||||
+ (['sbctl'] if system_cfg.features.secure_boot.enabled | bool else [])
|
||||
+ (['reflector'] if system_cfg.content.url | length == 0 else [])
|
||||
+ (bootstrap_common_conditional | reject('equalto', 'nftables') | list)
|
||||
}}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
loop: >-
|
||||
{{
|
||||
['ide0', 'ide2']
|
||||
+ (['ide1'] if not (os == 'rhel' and system_cfg.features.rhel_repo.source == 'iso') else [])
|
||||
+ (['ide1'] if not (os == 'rhel' and system_cfg.content.source == 'dvd') else [])
|
||||
}}
|
||||
failed_when: false
|
||||
no_log: true
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
}
|
||||
]
|
||||
if (rhel_iso is defined and rhel_iso | length > 0
|
||||
and not (os == 'rhel' and system_cfg.features.rhel_repo.source == 'iso'))
|
||||
and not (os == 'rhel' and system_cfg.content.source == 'dvd'))
|
||||
else []
|
||||
)
|
||||
}}
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
- name: Remove RHEL ISO fstab entry when not using local repo
|
||||
when:
|
||||
- os == "rhel"
|
||||
- system_cfg.features.rhel_repo.source != "iso"
|
||||
- system_cfg.content.source != "dvd"
|
||||
ansible.builtin.lineinfile:
|
||||
path: /mnt/etc/fstab
|
||||
regexp: "^.*\\/dvd.*$"
|
||||
@@ -35,7 +35,7 @@
|
||||
- name: Replace ISO UUID entry with /dev/sr0 in fstab
|
||||
when:
|
||||
- os == "rhel"
|
||||
- system_cfg.features.rhel_repo.source == "iso"
|
||||
- system_cfg.content.source == "dvd"
|
||||
vars:
|
||||
configuration_fstab_dvd_line: >-
|
||||
{{
|
||||
@@ -53,7 +53,7 @@
|
||||
when:
|
||||
- os == "rhel"
|
||||
- hypervisor_type == "vmware"
|
||||
- system_cfg.features.rhel_repo.source == "iso"
|
||||
- system_cfg.content.source == "dvd"
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- dd
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
ansible.builtin.include_tasks: "{{ configuration_task.file }}"
|
||||
loop:
|
||||
- file: repositories.yml
|
||||
when: "{{ os_family == 'Debian' }}"
|
||||
- file: banner.yml
|
||||
- file: fstab.yml
|
||||
- file: locales.yml
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
---
|
||||
- name: Write final sources.list
|
||||
# Config runs against the chroot, so these write /mnt directly via templates
|
||||
# rather than apt_repository/yum_repository, which would touch the live host.
|
||||
- name: Write the apt sources.list
|
||||
when: os_family == 'Debian'
|
||||
vars:
|
||||
_debian_release_map:
|
||||
"12": bookworm
|
||||
@@ -13,11 +16,69 @@
|
||||
dest: /mnt/etc/apt/sources.list
|
||||
mode: "0644"
|
||||
|
||||
- name: Ensure apt performance configuration persists
|
||||
- name: Ensure apt performance and content-proxy configuration
|
||||
when: os_family == 'Debian'
|
||||
ansible.builtin.copy:
|
||||
dest: /mnt/etc/apt/apt.conf.d/99performance
|
||||
content: |
|
||||
Acquire::Retries "3";
|
||||
Acquire::http::Pipeline-Depth "10";
|
||||
APT::Install-Recommends "false";
|
||||
{% if system_cfg.content.proxy | length > 0 %}
|
||||
Acquire::http::Proxy "{{ system_cfg.content.proxy }}";
|
||||
Acquire::https::Proxy "{{ system_cfg.content.proxy }}";
|
||||
{% endif %}
|
||||
mode: "0644"
|
||||
|
||||
- name: Drop the install-time DVD repo from the target on non-dvd sources
|
||||
when:
|
||||
- os_family == 'RedHat'
|
||||
- system_cfg.content.source != 'dvd'
|
||||
ansible.builtin.file:
|
||||
path: /mnt/etc/yum.repos.d/redhat.repo
|
||||
state: absent
|
||||
|
||||
- name: Write the EL mirror repo on the target
|
||||
when:
|
||||
- os_family == 'RedHat'
|
||||
- system_cfg.content.source == 'mirror'
|
||||
- system_cfg.content.url | length > 0
|
||||
ansible.builtin.template:
|
||||
src: el_mirror.repo.j2
|
||||
dest: "/mnt/etc/yum.repos.d/{{ os }}.repo"
|
||||
mode: "0644"
|
||||
|
||||
- name: Find the stock vendor repos shipped by the release package
|
||||
when:
|
||||
- os_family == 'RedHat'
|
||||
- system_cfg.content.source == 'mirror'
|
||||
- system_cfg.content.url | length > 0
|
||||
ansible.builtin.find:
|
||||
paths: /mnt/etc/yum.repos.d
|
||||
patterns: "*.repo"
|
||||
excludes: "{{ os }}.repo"
|
||||
register: el_stock_repos
|
||||
|
||||
- name: Remove the stock vendor repos so only the custom mirror is reachable
|
||||
when:
|
||||
- os_family == 'RedHat'
|
||||
- system_cfg.content.source == 'mirror'
|
||||
- system_cfg.content.url | length > 0
|
||||
ansible.builtin.file:
|
||||
path: "{{ item.path }}"
|
||||
state: absent
|
||||
loop: "{{ el_stock_repos.files | default([]) }}"
|
||||
loop_control:
|
||||
label: "{{ item.path }}"
|
||||
|
||||
- name: Configure the dnf content proxy on the target
|
||||
when:
|
||||
- os_family == 'RedHat'
|
||||
- system_cfg.content.proxy | length > 0
|
||||
ansible.builtin.lineinfile:
|
||||
path: /mnt/etc/dnf/dnf.conf
|
||||
line: "proxy={{ system_cfg.content.proxy }}"
|
||||
regexp: "^proxy="
|
||||
create: true
|
||||
mode: "0644"
|
||||
state: present
|
||||
|
||||
46
roles/configuration/tasks/satellite_register.yml
Normal file
46
roles/configuration/tasks/satellite_register.yml
Normal file
@@ -0,0 +1,46 @@
|
||||
---
|
||||
# Invoked post-reboot on the booted host, not in the chroot: subscription-manager
|
||||
# needs a running systemd and the live network.
|
||||
- name: Add the Satellite host to /etc/hosts
|
||||
when: system_cfg.content.satellite.ip | length > 0
|
||||
ansible.builtin.lineinfile:
|
||||
path: /etc/hosts
|
||||
line: "{{ system_cfg.content.satellite.ip }} {{ system_cfg.content.satellite.host }}"
|
||||
regexp: "[[:space:]]{{ system_cfg.content.satellite.host | regex_escape }}([[:space:]]|$)"
|
||||
state: present
|
||||
|
||||
- name: Fetch the Katello CA consumer RPM
|
||||
ansible.builtin.get_url:
|
||||
url: >-
|
||||
{{ system_cfg.content.satellite.ca_url
|
||||
if (system_cfg.content.satellite.ca_url | length > 0)
|
||||
else 'https://' ~ system_cfg.content.satellite.host ~ '/pub/katello-ca-consumer-latest.noarch.rpm' }}
|
||||
dest: /tmp/katello-ca-consumer-latest.noarch.rpm
|
||||
validate_certs: false
|
||||
mode: "0644"
|
||||
|
||||
- name: Install the Katello CA consumer RPM
|
||||
ansible.builtin.dnf:
|
||||
name: /tmp/katello-ca-consumer-latest.noarch.rpm
|
||||
state: present
|
||||
disable_gpg_check: true
|
||||
|
||||
- name: Clean any stale subscription identity
|
||||
ansible.builtin.command: subscription-manager clean
|
||||
changed_when: true
|
||||
|
||||
- name: Register with Satellite via activation key
|
||||
no_log: true
|
||||
community.general.redhat_subscription:
|
||||
state: present
|
||||
server_hostname: "{{ system_cfg.content.satellite.host }}"
|
||||
org_id: "{{ system_cfg.content.satellite.org }}"
|
||||
activationkey: "{{ system_cfg.content.satellite.activation_key }}"
|
||||
environment: "{{ system_cfg.content.satellite.environment | default(omit, true) }}"
|
||||
auto_attach: true
|
||||
force_register: true
|
||||
server_proxy_hostname: "{{ (system_cfg.content.proxy | urlsplit('hostname')) | default(omit, true) }}"
|
||||
server_proxy_port: "{{ (system_cfg.content.proxy | urlsplit('port')) | default(omit, true) }}"
|
||||
syspurpose:
|
||||
service_level_agreement: "{{ system_cfg.content.satellite.service_level | default(omit, true) }}"
|
||||
sync: true
|
||||
@@ -1,6 +1,6 @@
|
||||
# Managed by Ansible.
|
||||
{% set release = _debian_release_map[os_version | string] | default('trixie') %}
|
||||
{% set mirror = system_cfg.mirror | default('http://deb.debian.org/debian', true) %}
|
||||
{% set mirror = system_cfg.content.url | default('http://deb.debian.org/debian', true) %}
|
||||
{% set components = 'main contrib non-free non-free-firmware' %}
|
||||
|
||||
deb {{ mirror }} {{ release }} {{ components }}
|
||||
|
||||
17
roles/configuration/templates/el_mirror.repo.j2
Normal file
17
roles/configuration/templates/el_mirror.repo.j2
Normal file
@@ -0,0 +1,17 @@
|
||||
[{{ os }}{{ os_version_major }}-baseos]
|
||||
name={{ os }} {{ os_version_major }} BaseOS
|
||||
baseurl={{ system_cfg.content.url }}/BaseOS
|
||||
enabled=1
|
||||
gpgcheck={{ 1 if system_cfg.content.gpgcheck | bool else 0 }}
|
||||
{% if system_cfg.content.proxy | length > 0 %}
|
||||
proxy={{ system_cfg.content.proxy }}
|
||||
{% endif %}
|
||||
|
||||
[{{ os }}{{ os_version_major }}-appstream]
|
||||
name={{ os }} {{ os_version_major }} AppStream
|
||||
baseurl={{ system_cfg.content.url }}/AppStream
|
||||
enabled=1
|
||||
gpgcheck={{ 1 if system_cfg.content.gpgcheck | bool else 0 }}
|
||||
{% if system_cfg.content.proxy | length > 0 %}
|
||||
proxy={{ system_cfg.content.proxy }}
|
||||
{% endif %}
|
||||
@@ -1,6 +1,6 @@
|
||||
# Managed by Ansible.
|
||||
{% set release = _ubuntu_release_map[os] | default('resolute') %}
|
||||
{% set mirror = system_cfg.mirror %}
|
||||
{% set mirror = system_cfg.content.url %}
|
||||
{% set components = 'main restricted universe multiverse' %}
|
||||
|
||||
deb {{ mirror }} {{ release }} {{ components }}
|
||||
|
||||
@@ -1,13 +1,24 @@
|
||||
{% set _baseurl = system_cfg.content.url if system_cfg.content.source == 'mirror' else 'file:///usr/local/install/redhat/dvd' %}
|
||||
[rhel{{ os_version_major }}-baseos]
|
||||
name=RHEL {{ os_version_major }} BaseOS
|
||||
baseurl=file:///usr/local/install/redhat/dvd/BaseOS
|
||||
baseurl={{ _baseurl }}/BaseOS
|
||||
enabled=1
|
||||
gpgcheck=0
|
||||
{% if system_cfg.content.source != 'mirror' %}
|
||||
gpgkey=file:///usr/local/install/redhat/dvd/RPM-GPG-KEY-redhat-release
|
||||
{% endif %}
|
||||
{% if system_cfg.content.proxy | length > 0 %}
|
||||
proxy={{ system_cfg.content.proxy }}
|
||||
{% endif %}
|
||||
|
||||
[rhel{{ os_version_major }}-appstream]
|
||||
name=RHEL {{ os_version_major }} AppStream
|
||||
baseurl=file:///usr/local/install/redhat/dvd/AppStream
|
||||
baseurl={{ _baseurl }}/AppStream
|
||||
enabled=1
|
||||
gpgcheck=0
|
||||
{% if system_cfg.content.source != 'mirror' %}
|
||||
gpgkey=file:///usr/local/install/redhat/dvd/RPM-GPG-KEY-redhat-release
|
||||
{% endif %}
|
||||
{% if system_cfg.content.proxy | length > 0 %}
|
||||
proxy={{ system_cfg.content.proxy }}
|
||||
{% endif %}
|
||||
|
||||
@@ -78,7 +78,23 @@ system_defaults:
|
||||
timezone: "Europe/Vienna"
|
||||
locale: "en_US.UTF-8"
|
||||
keymap: "us"
|
||||
mirror: ""
|
||||
# Uniform content source, family-resolved. source: dvd|mirror|satellite|none
|
||||
# ('' -> family default: EL=dvd, debian/ubuntu/arch=mirror). satellite values
|
||||
# come from inventory/vault only, never committed code.
|
||||
content:
|
||||
source: ""
|
||||
url: ""
|
||||
proxy: ""
|
||||
gpgcheck: true
|
||||
satellite:
|
||||
host: ""
|
||||
ip: "" # optional /etc/hosts entry when DNS does not resolve host
|
||||
org: ""
|
||||
activation_key: ""
|
||||
ca_url: ""
|
||||
service_level: ""
|
||||
environment: ""
|
||||
install: false
|
||||
packages: []
|
||||
disks: []
|
||||
users: {}
|
||||
@@ -127,9 +143,6 @@ system_defaults:
|
||||
banner:
|
||||
motd: false
|
||||
sudo: true
|
||||
rhel_repo:
|
||||
source: "iso" # iso|satellite|none - how RHEL systems get packages post-install
|
||||
url: "" # Satellite/custom repo URL when source=satellite
|
||||
chroot:
|
||||
tool: "arch-chroot" # arch-chroot|chroot|systemd-nspawn
|
||||
initramfs:
|
||||
|
||||
@@ -91,12 +91,27 @@
|
||||
timezone: "{{ system_raw.timezone | string }}"
|
||||
locale: "{{ system_raw.locale | string }}"
|
||||
keymap: "{{ system_raw.keymap | string }}"
|
||||
mirror: >-
|
||||
{{
|
||||
system_raw.mirror | string | trim
|
||||
if (system_raw.mirror | default('') | string | trim | length) > 0
|
||||
else _mirror_defaults[system_raw.os | default('') | string | lower] | default('')
|
||||
}}
|
||||
content:
|
||||
source: >-
|
||||
{%- set s = system_raw.content.source | default('') | string | lower | trim -%}
|
||||
{%- if s | length > 0 -%}{{ s }}
|
||||
{%- elif (system_raw.os | default('') | string | lower) == 'rhel' -%}dvd
|
||||
{%- else -%}mirror{%- endif -%}
|
||||
url: >-
|
||||
{%- set u = system_raw.content.url | default('') | string | trim -%}
|
||||
{%- if u | length > 0 -%}{{ u }}
|
||||
{%- else -%}{{ _mirror_defaults[system_raw.os | default('') | string | lower] | default('') }}{%- endif -%}
|
||||
proxy: "{{ system_raw.content.proxy | default('') | string | trim }}"
|
||||
gpgcheck: "{{ system_raw.content.gpgcheck | default(true) | bool }}"
|
||||
satellite:
|
||||
host: "{{ system_raw.content.satellite.host | default('') | string | trim }}"
|
||||
ip: "{{ system_raw.content.satellite.ip | default('') | string | trim }}"
|
||||
org: "{{ system_raw.content.satellite.org | default('') | string }}"
|
||||
activation_key: "{{ system_raw.content.satellite.activation_key | default('') | string }}"
|
||||
ca_url: "{{ system_raw.content.satellite.ca_url | default('') | string | trim }}"
|
||||
service_level: "{{ system_raw.content.satellite.service_level | default('') | string }}"
|
||||
environment: "{{ system_raw.content.satellite.environment | default('') | string }}"
|
||||
install: "{{ system_raw.content.satellite.install | default(false) | bool }}"
|
||||
path: >-
|
||||
{{
|
||||
(system_raw.path | default('') | string)
|
||||
@@ -161,9 +176,6 @@
|
||||
banner:
|
||||
motd: "{{ system_raw.features.banner.motd | bool }}"
|
||||
sudo: "{{ system_raw.features.banner.sudo | bool }}"
|
||||
rhel_repo:
|
||||
source: "{{ system_raw.features.rhel_repo.source | default('iso') | string | lower }}"
|
||||
url: "{{ system_raw.features.rhel_repo.url | default('') | string }}"
|
||||
chroot:
|
||||
tool: "{{ system_raw.features.chroot.tool | string }}"
|
||||
initramfs:
|
||||
|
||||
@@ -50,23 +50,28 @@
|
||||
ansible.builtin.set_fact:
|
||||
system_cfg: "{{ system_defaults | combine(system | default({}), recursive=True) | combine(system_cfg, recursive=True) }}"
|
||||
|
||||
- name: Apply mirror default for pre-computed system_cfg
|
||||
- name: Apply content-source family defaults for pre-computed system_cfg
|
||||
when:
|
||||
- system_cfg is defined
|
||||
- _bootstrap_needs_enrichment | default(false) | bool
|
||||
- system_cfg.mirror | default('') | string | trim | length == 0
|
||||
vars:
|
||||
# Same as _normalize_system.yml - kept in sync manually.
|
||||
# Same family resolution as _normalize_system.yml - kept in sync manually.
|
||||
_mirror_defaults:
|
||||
debian: "https://deb.debian.org/debian/"
|
||||
ubuntu: "http://archive.ubuntu.com/ubuntu/"
|
||||
ubuntu-lts: "http://archive.ubuntu.com/ubuntu/"
|
||||
_os: "{{ system_cfg.os | default('') | string | lower }}"
|
||||
ansible.builtin.set_fact:
|
||||
system_cfg: >-
|
||||
{{
|
||||
system_cfg | combine({
|
||||
'mirror': _mirror_defaults[system_cfg.os | default('') | string | lower] | default('')
|
||||
}, recursive=True)
|
||||
system_cfg | combine({'content': {
|
||||
'source': system_cfg.content.source
|
||||
if (system_cfg.content.source | default('') | string | trim | length > 0)
|
||||
else ('dvd' if _os == 'rhel' else 'mirror'),
|
||||
'url': system_cfg.content.url
|
||||
if (system_cfg.content.url | default('') | string | trim | length > 0)
|
||||
else (_mirror_defaults[_os] | default('')),
|
||||
}}, recursive=True)
|
||||
}}
|
||||
|
||||
- name: Populate primary network fields from first interface (pre-computed)
|
||||
|
||||
@@ -148,8 +148,8 @@
|
||||
- name: Validate RHEL ISO requirement
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- os != "rhel" or (rhel_iso is defined and (rhel_iso | string | length) > 0)
|
||||
fail_msg: "rhel_iso is required when os=rhel."
|
||||
- os != "rhel" or system_cfg.content.source == "mirror" or (rhel_iso is defined and (rhel_iso | string | length) > 0)
|
||||
fail_msg: "rhel_iso is required when os=rhel unless content.source is mirror."
|
||||
quiet: true
|
||||
|
||||
- name: Validate hypervisor-specific required fields
|
||||
|
||||
40
tests/content/_assert_content.yml
Normal file
40
tests/content/_assert_content.yml
Normal file
@@ -0,0 +1,40 @@
|
||||
---
|
||||
- name: "Seed raw system input (content {{ cf.name }})"
|
||||
ansible.builtin.set_fact:
|
||||
system: "{{ cf.system }}"
|
||||
|
||||
- name: "Normalize system (content {{ cf.name }})"
|
||||
ansible.builtin.include_tasks: ../../roles/global_defaults/tasks/_normalize_system.yml
|
||||
|
||||
- name: "Apply family defaults (content {{ cf.name }})"
|
||||
ansible.builtin.include_tasks: ../../roles/global_defaults/tasks/_apply_family_defaults.yml
|
||||
|
||||
- name: "Assert computed content source and url (content {{ cf.name }})"
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- system_cfg.content.source == cf.expect.source
|
||||
- system_cfg.content.url == cf.expect.url
|
||||
fail_msg: "[content {{ cf.name }}] FAIL got {{ system_cfg.content }}"
|
||||
success_msg: "[content {{ cf.name }}] OK {{ system_cfg.content.source }} {{ system_cfg.content.url }}"
|
||||
|
||||
- name: "Assert satellite register inputs (content {{ cf.name }})"
|
||||
when: cf.expect.satellite is defined
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- system_cfg.content.satellite.host == cf.expect.satellite.host
|
||||
- system_cfg.content.satellite.org == cf.expect.satellite.org
|
||||
- system_cfg.content.satellite.activation_key == cf.expect.satellite.activation_key
|
||||
fail_msg: "[content {{ cf.name }}] satellite FAIL got {{ system_cfg.content.satellite }}"
|
||||
|
||||
- name: "Assert Arch reflector lock-out (content {{ cf.name }})"
|
||||
when: cf.expect_reflector is defined
|
||||
block:
|
||||
- name: "Load Arch package set (content {{ cf.name }})"
|
||||
ansible.builtin.include_vars:
|
||||
file: ../../roles/bootstrap/vars/main.yml
|
||||
|
||||
- name: "Assert reflector membership (content {{ cf.name }})"
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- ('reflector' in (bootstrap_archlinux.base + bootstrap_archlinux.conditional)) == (cf.expect_reflector == 'present')
|
||||
fail_msg: "[content {{ cf.name }}] reflector expected {{ cf.expect_reflector }}, url='{{ system_cfg.content.url }}'"
|
||||
78
tests/content/content_fixtures.yml
Normal file
78
tests/content/content_fixtures.yml
Normal file
@@ -0,0 +1,78 @@
|
||||
---
|
||||
# Raw system.content input -> expected normalized system_cfg.content. Covers family
|
||||
# source defaults (EL=dvd, else mirror), url pass-through, satellite inputs, and the
|
||||
# Arch reflector lock-out (dropped only when a custom mirror url is set).
|
||||
content_fixtures:
|
||||
- name: arch-mirror-url-drops-reflector
|
||||
system:
|
||||
os: archlinux
|
||||
content: { url: "https://mirror.internal/archlinux" }
|
||||
expect:
|
||||
source: mirror
|
||||
url: "https://mirror.internal/archlinux"
|
||||
expect_reflector: absent
|
||||
|
||||
- name: arch-no-url-keeps-public-and-reflector
|
||||
system:
|
||||
os: archlinux
|
||||
content: {}
|
||||
expect:
|
||||
source: mirror
|
||||
url: ""
|
||||
expect_reflector: present
|
||||
|
||||
- name: el-mirror-url
|
||||
system:
|
||||
os: almalinux
|
||||
version: "10"
|
||||
content: { source: mirror, url: "https://mirror.internal/almalinux" }
|
||||
expect:
|
||||
source: mirror
|
||||
url: "https://mirror.internal/almalinux"
|
||||
|
||||
- name: el-default-dvd
|
||||
system:
|
||||
os: rhel
|
||||
version: "10"
|
||||
content: {}
|
||||
expect:
|
||||
source: dvd
|
||||
url: ""
|
||||
|
||||
- name: el-satellite-register
|
||||
system:
|
||||
os: almalinux
|
||||
version: "10"
|
||||
content:
|
||||
source: satellite
|
||||
satellite: { host: "sat.internal", org: "SG", activation_key: "ak-el10" }
|
||||
expect:
|
||||
source: satellite
|
||||
url: ""
|
||||
satellite: { host: "sat.internal", org: "SG", activation_key: "ak-el10" }
|
||||
|
||||
- name: debian-default-mirror
|
||||
system:
|
||||
os: debian
|
||||
version: "13"
|
||||
content: {}
|
||||
expect:
|
||||
source: mirror
|
||||
url: "https://deb.debian.org/debian/"
|
||||
|
||||
- name: debian-custom-mirror-lands
|
||||
system:
|
||||
os: debian
|
||||
version: "13"
|
||||
content: { source: mirror, url: "https://mirror.internal/debian" }
|
||||
expect:
|
||||
source: mirror
|
||||
url: "https://mirror.internal/debian"
|
||||
|
||||
- name: ubuntu-default-mirror
|
||||
system:
|
||||
os: ubuntu
|
||||
content: {}
|
||||
expect:
|
||||
source: mirror
|
||||
url: "http://archive.ubuntu.com/ubuntu/"
|
||||
22
tests/content/test_content.yml
Normal file
22
tests/content/test_content.yml
Normal file
@@ -0,0 +1,22 @@
|
||||
---
|
||||
# Run: ansible-playbook tests/content/test_content.yml
|
||||
- name: Content-source fixture tests
|
||||
hosts: localhost
|
||||
gather_facts: false
|
||||
connection: local
|
||||
vars:
|
||||
hypervisor_type: libvirt
|
||||
hypervisor_cfg: { folder: "" }
|
||||
vars_files:
|
||||
- content_fixtures.yml
|
||||
tasks:
|
||||
- name: Load global defaults (system_defaults, content_mirror_defaults, os maps)
|
||||
ansible.builtin.include_vars:
|
||||
file: ../../roles/global_defaults/defaults/main.yml
|
||||
|
||||
- name: Run each content fixture
|
||||
ansible.builtin.include_tasks: _assert_content.yml
|
||||
loop: "{{ content_fixtures }}"
|
||||
loop_control:
|
||||
loop_var: cf
|
||||
label: "{{ cf.name }}"
|
||||
Reference in New Issue
Block a user