Inventory model
YAIDAP is inventory-driven. Most behavior comes from shared objects in group_vars and per-host overrides in host_vars. When UMKIM binds a site with provider: yaidap, the hub stores the same native YAML tree in ConfigMap fleet-site-{site}-yaidap-inventory.
Canonical schema source: yaidap/docs/inventory-model.md.
Inventory tree
Section titled “Inventory tree”Each inventory root (for example inventory/example/ or a site-specific path on the jumphost) contains:
guests.yml Guest index (ansible_host, vm_location; jumphost may add external.hosts)bare_metals.yml Bare-metal cluster nodes (hub store; merged into guests on jumphost sync)hypervisors.yml Hypervisor group{cluster}.yml Ansible group membershipcontrollers.yml Controller hosts (jumphost-only, not synced to hub)routers.yml OpenWrt routers (jumphost-only)group_vars/all/all.yml Shared catalogs: networks, storages, defaultsgroup_vars/{group}.yml Group vars (cluster intent for UMKIM)host_vars/{host}.yml Per-host profile (uplinks, disks, TempXE, GPU)generated/ Discovery drafts, PXE tarballs (jumphost-only)Example inventories in the YAIDAP repo:
| Path | Role |
|---|---|
inventory/example/ |
Sanitized schema contract |
inventory/demo/ |
Fictional reference lab walkthrough |
Hub store vs jumphost
Section titled “Hub store vs jumphost”When UMKIM manages inventory on the hub, paths sync to the jumphost except hub-only metadata:
| Path | Synced to jumphost | Role |
|---|---|---|
guests.yml |
yes (hub: VM index only) | guests.hosts; jumphost copy also has external.hosts composed from hub bare_metals.yml on sync |
bare_metals.yml |
hub only | Bare-metal cluster nodes (kind: bare_metal in host APIs) |
hypervisors.yml |
yes | Hypervisor group (kind: hypervisor in host APIs) |
{cluster}.yml |
yes | Ansible group membership (hosts: list) |
group_vars/all/all.yml |
yes | Site networks, storages, defaults |
group_vars/{group}.yml |
yes | Group vars; Fleet cluster intent for cluster groups |
host_vars/{guest}.yml |
yes | Per-guest YAIDAP profile |
_meta/meta.json |
no | Sync phase, revision head, last sync/import timestamps |
_meta/status.json |
no | Per-guest provision + cluster-apply phase |
_meta/revisions.json |
no | Timestamped edit log |
_meta/import_preview.json |
no | Staging for jumphost import diff |
Jumphost-only (preserved on sync; not stored on hub): controllers.yml, routers.yml, generated/.
Sync phases
Section titled “Sync phases”_meta/meta.json → syncPhase:
| Phase | Meaning |
|---|---|
pending |
Never synced or freshly migrated |
dirty |
Hub edits not yet on jumphost |
syncing |
Push job running |
synced |
Jumphost tree matches last successful push |
Push only synced paths; jumphost-only files are never overwritten. See UMKIM integration for sync API and CLI.
Hub schema boundary
Section titled “Hub schema boundary”Do not import YAIDAP networks, uplinks, storages, or disk catalogs into Fleet CRDs. They stay in group_vars / host_vars. Fleet cluster intent uses native Ansible layout in {cluster}.yml and group_vars/{cluster}.yml — see Site provisioning for the cluster-apply flow.
Shared objects
Section titled “Shared objects”networks
Section titled “networks”Canonical L2/L3 networks referenced by name from host uplinks.
| Field | Meaning |
|---|---|
network_name |
Unique name referenced by uplinks |
cidr |
Network CIDR |
gw |
Gateway address |
dns |
DNS server |
domain |
DNS suffix |
tag |
Default VLAN tag; empty string means untagged |
physical_network |
Default logical fabric / trunk name |
default_route |
Catalog default for whether this L3 owns the host default route |
tag and physical_network on networks[] are defaults. An uplink attachment may override them so the same L3 object can use different L1 encoding on different NICs.
networks: - network_name: mgmt_nw cidr: 192.168.1.0/24 gw: 192.168.1.1 dns: 192.168.1.1 domain: lab.example tag: "" physical_network: default_l2 default_route: true - network_name: lab_nw cidr: 172.16.10.0/24 gw: 172.16.10.1 tag: "10" physical_network: default_l2storages
Section titled “storages”Catalog of backends. Guest disks[].storage and hypervisor prepare both use this list. Scope an entry with os: (family prefix) and/or hosts: so Rocky/libvirt and Proxmox can share one catalog.
storages: - name: local type: local # alias of dir; libvirt file pool path: /opt/local os: [rocky] - name: local-lvm type: lvmthin builtin: true # installer-created; prepare does not touch it os: [proxmox] - name: nfs-iso type: nfs server: 172.16.10.2 export: /export/iso path: /mnt/nfs-iso shared: trueos family |
Allowed type |
|---|---|
rocky* |
dir (local), nfs, unused |
proxmox* |
dir, nfs, lvmthin, lvm, zfspool, unused, extend_local_lvm |
Extra local disks use storages[].disk pointing at a disks[].name entry. Default extra-disk type is unused until you change it for prepare to consume the disk.
Boot/data disks for bare metal or VMs.
| Field | Meaning |
|---|---|
name |
Inventory label (bootdisk, disk1, …) |
disk |
Block device selector (see below) |
bootdisk |
Whether this disk is the OS install target |
size |
Size in GiB |
storage |
storages[].name (VM guests; parent HV pool) |
format |
VM disk format (qcow2, raw) |
disk accepts three forms:
| Form | Example | Use |
|---|---|---|
| Kernel name | sda, nvme0n1 |
VMs and simple lab hosts |
| Kickstart id | disk/by-id/ata-TOSHIBA_… |
Bare metal (stable across reboots) |
| Full path | /dev/disk/by-id/ata-… |
Same as kickstart id |
Prefer disk/by-id/… on bare metal. Discovery emits disk/by-id/… in generated host vars when /dev/disk/by-id symlinks are available.
uplinks
Section titled “uplinks”Multi-NIC / bridge model. Each uplink is a physical (or bond) attachment carrying one or more networks:
uplinks: - name: n0p0 physical_network: default_l2 mac_address: "00:11:22:33:44:55" networks: - zone: external network_name: mgmt_nw vm_network: true ip: "{{ ansible_host }}" tcp_open: [22] - zone: lab network_name: lab_nw vm_network: true ip: "172.16.10.2" tcp_open: [22]| Field | Meaning |
|---|---|
mac_address |
Required on physical HV uplinks. Kernel ifname is resolved from MAC on the live host |
networks[].network_name |
Must exist in networks |
networks[].tag |
Optional override of catalog VLAN tag for this attachment |
networks[].vm_network |
Hypervisor creates a guest bridge for this network |
networks[].zone |
firewalld zone when configure_firewalld is true |
configure-common normalizes uplinks into interfaces before hypervisor, firewalld, and provisioning logic runs. Inventory interface: is a discovery hint only when mac_address is set.
The same network_name may appear on multiple uplinks (same L3, different L1). Each (uplink, network_name) pair must be unique on a host.
VM placement
Section titled “VM placement”Guests set vm_location to a hypervisor hostname, or use least-utilized (or auto) to schedule on a Rocky libvirt hypervisor from groups['hypervisors'] by planned memory.
| Field | Meaning |
|---|---|
vm_location |
Concrete hypervisor hostname, or least-utilized / auto |
vm_location_schedule |
Per-guest opt-out (false requires an explicit hostname) |
vm_scheduling_pool |
Per-hypervisor opt-out (false excludes host from the pool) |
hypervisor_memory_reserve_mib |
Host OS + libvirt headroom subtracted before guest sums |
Scheduling uses planned memory only (no ballooning). GPU passthrough guests must pin vm_location. Proxmox guests are unchanged.
When UMKIM runs create_vm, the fleet-site controller parses YAIDAP_RESULT (vm_location field; legacy fallback: FLEET_YAIDAP_VM_LOCATION= log marker) and rewrites schedule tokens to the concrete hypervisor in guests.yml and host_vars/{guest}.yml, then auto-syncs inventory to the jumphost.
When the hypervisor exposes the same network_name on more than one uplink, guests must set hypervisor_uplink on the attachment to pick the bridge path.
Cluster intent files
Section titled “Cluster intent files”Optional cluster membership and Fleet intent use native Ansible layout:
{cluster}.yml(inventory root) — group withhosts:listing member guest names.group_vars/{cluster}.yml— FleetClusterSpecfields (topology,autoApply,controlPlaneVip,haGroup,mode, …).
Members are defined only in the root group file, not duplicated in group_vars. Full cluster-apply flow: Site provisioning.
Discovery and placeholders
Section titled “Discovery and placeholders”discover-hosts.yml (check_host_details) writes draft host_vars/<host>.yml with CHANGE_ME placeholders plus notes (hardware detail not consumed by prepare/create). PXE discovery tarballs land under generated/ on the jumphost.
Import preview and the console editor surface warnings per path. Resolve placeholders before sync or provision; YAIDAP may fail or produce wrong networks.
GPU passthrough
Section titled “GPU passthrough”| Field | Where | Meaning |
|---|---|---|
gpu_passthrough_host.enabled |
HV | Bind listed PCI funcs to vfio-pci, IOMMU kernel args |
gpu_passthrough_host.pci_devices |
HV | Sysfs addresses (0000:01:00.0) |
gpu_passthrough.enabled |
guest | Attach those devices (hostdev / Proxmox hostpci) |
gpu_passthrough.pci_devices |
guest | Same addresses as the HV list |
Host prep tag: prepare_gpu_passthrough. Guest attach tag: create. Pin PCI addresses from notes.gpus[].pci in discovery output.
TempXE discovery
Section titled “TempXE discovery”For PXE-based hardware discovery, set in host_vars:
tempxe_discovery: enabled: true reboot_after_discovery: false # default: no auto-reboot after PXE collectRequires uplink mac_address. UMKIM discover_pxe action arms TempXE on the jumphost; output lands under generated/pxe-discovery/ and is promoted via import preview/apply.
See also
Section titled “See also”- YAIDAP introduction — scope, playbooks, noop vs yaidap
- Provisioning workflows — discover → validate → prepare → create
- UMKIM integration — hub inventory editing, sync, import