File: //opt/saltstack/salt/lib/python3.10/site-packages/salt/templates/virt/libvirt_domain.jinja
{%- import 'libvirt_disks.jinja' as libvirt_disks -%}
{%- from 'libvirt_macros.jinja' import opt_attribute as opt_attribute -%}
{%- macro opt_attribute(obj, name, conv=none) %}
{%- if obj.get(name) is not none %} {{ name }}='{{ obj[name] if conv is none else conv(obj[name]) }}'{% endif -%}
{%- endmacro %}
{%- import 'libvirt_chardevs.jinja' as libvirt_chardevs -%}
<domain type='{{ hypervisor }}'>
<name>{{ name }}</name>
{%- if cpu %}
<vcpu {{ opt_attribute(cpu, 'placement') }} {{ opt_attribute(cpu, 'cpuset') }} {{ opt_attribute(cpu, 'current') }}>{{ cpu.get('maximum', '') }}</vcpu>
{%- endif %}
{%- if cpu.get('vcpus') %}
<vcpus>
{%- for vcpu_id in cpu["vcpus"].keys() %}
<vcpu id='{{ vcpu_id }}' {{ opt_attribute(cpu.vcpus[vcpu_id], 'enabled', yesno) }} {{ opt_attribute(cpu.vcpus[vcpu_id], 'hotpluggable', yesno) }} {{ opt_attribute(cpu.vcpus[vcpu_id], 'order') }}/>
{%- endfor %}
</vcpus>
{%- endif %}
{%- if cpu %}
<cpu {{ opt_attribute(cpu, 'match') }} {{ opt_attribute(cpu, 'mode') }} {{ opt_attribute(cpu, 'check') }}>
{%- if cpu.model %}
<model {{ opt_attribute(cpu.model, 'fallback') }} {{ opt_attribute(cpu.model, 'vendor_id') }}>{{ cpu.model.get('name', '') }}</model>
{%- endif %}
{%- if cpu.vendor %}
<vendor>{{ cpu.get('vendor', '') }}</vendor>
{%- endif %}
{%- if cpu.topology %}
<topology {{ opt_attribute(cpu.topology, 'sockets') }} {{ opt_attribute(cpu.topology, 'dies') }} {{ opt_attribute(cpu.topology, 'cores') }} {{ opt_attribute(cpu.topology, 'threads') }}/>
{%- endif %}
{%- if cpu.cache %}
<cache {{ opt_attribute(cpu.cache, 'level') }} {{ opt_attribute(cpu.cache, 'mode') }}/>
{%- endif %}
{%- if cpu.features %}
{%- for k, v in cpu.features.items() %}
<feature policy='{{ v }}' name='{{ k }}'/>
{%- endfor %}
{%- endif %}
{%- if cpu.numa %}
<numa>
{%- for numa_id in cpu.numa.keys() %}
{%- if cpu.numa.get(numa_id) %}
<cell id='{{ numa_id }}' {{ opt_attribute(cpu.numa[numa_id], 'cpus') }} {{ opt_attribute(cpu.numa[numa_id], 'memory', to_kib) }} {{ opt_attribute(cpu.numa[numa_id], 'discard', yesno) }} {{ opt_attribute(cpu.numa[numa_id], 'memAccess') }}>
{%- if cpu.numa[numa_id].distances %}
<distances>
{%- for sibling_id in cpu.numa[numa_id].distances %}
<sibling id='{{ sibling_id }}' value='{{ cpu.numa[numa_id].distances[sibling_id] }}'/>
{%- endfor %}
</distances>
{%- endif %}
</cell>
{%- endif %}
{%- endfor %}
</numa>
{%- endif %}
</cpu>
{%- if cpu.iothreads %}
<iothreads>{{ cpu.iothreads }}</iothreads>
{%- endif %}
{%- endif %}
{%- if cpu.tuning %}
<cputune>
{%- if cpu.tuning.vcpupin %}
{%- for vcpu_id, cpuset in cpu.tuning.vcpupin.items() %}
<vcpupin vcpu='{{ vcpu_id }}' cpuset='{{ cpuset }}'/>
{%- endfor %}
{%- endif %}
{%- if cpu.tuning.emulatorpin %}
<emulatorpin cpuset="{{ cpu.tuning.emulatorpin }}"/>
{%- endif %}
{%- if cpu.tuning.iothreadpin %}
{%- for thread_id, cpuset in cpu.tuning.iothreadpin.items() %}
<iothreadpin iothread='{{ thread_id }}' cpuset='{{ cpuset }}'/>
{%- endfor %}
{%- endif %}
{%- if cpu.tuning.shares %}
<shares>{{ cpu.tuning.shares }}</shares>
{%- endif %}
{%- if cpu.tuning.period %}
<period>{{ cpu.tuning.period }}</period>
{%- endif %}
{%- if cpu.tuning.quota %}
<quota>{{ cpu.tuning.quota }}</quota>
{%- endif %}
{%- if cpu.tuning.global_period %}
<global_period>{{ cpu.tuning.global_period }}</global_period>
{%- endif %}
{%- if cpu.tuning.global_quota %}
<global_quota>{{ cpu.tuning.global_quota }}</global_quota>
{%- endif %}
{%- if cpu.tuning.emulator_period %}
<emulator_period>{{ cpu.tuning.emulator_period }}</emulator_period>
{%- endif %}
{%- if cpu.tuning.emulator_quota %}
<emulator_quota>{{ cpu.tuning.emulator_quota }}</emulator_quota>
{%- endif %}
{%- if cpu.tuning.iothread_period %}
<iothread_period>{{ cpu.tuning.iothread_period }}</iothread_period>
{%- endif %}
{%- if cpu.tuning.iothread_quota %}
<iothread_quota>{{ cpu.tuning.iothread_quota }}</iothread_quota>
{%- endif %}
{%- if cpu.tuning.vcpusched %}
{%- for sched in cpu.tuning.vcpusched %}
<vcpusched scheduler='{{ sched.scheduler }}'{{ opt_attribute(sched, "vcpus") }}{{ opt_attribute(sched, "priority") }}/>
{%- endfor %}
{%- endif %}
{%- if cpu.tuning.iothreadsched %}
{%- for sched in cpu.tuning.iothreadsched %}
<iothreadsched scheduler='{{ sched.scheduler }}'{{ opt_attribute(sched, "iothreads") }}{{ opt_attribute(sched, "priority") }}/>
{%- endfor %}
{%- endif %}
{%- if cpu.tuning.emulatorsched %}
<emulatorsched scheduler='{{ cpu.tuning.emulatorsched.scheduler }}'{{ opt_attribute(cpu.tuning.emulatorsched, "priority") }}/>
{%- endif %}
{%- if cpu.tuning.cachetune %}
{%- for k, v in cpu.tuning.cachetune.items() %}
<cachetune vcpus='{{ k }}'>
{%- for e, atrs in v.items() %}
{%- if e is number and atrs %}
<cache id='{{ e }}' {%- for atr, val in atrs.items() %} {{ atr }}='{{ val }}' {%- endfor %} />
{%- elif e is not number %}
{%- for atr, val in atrs.items() %}
<monitor level='{{ val }}' vcpus='{{ atr }}'/>
{%- endfor %}
{%- endif %}
{%- endfor %}
</cachetune>
{%- endfor %}
{%- endif %}
{%- if cpu.tuning.memorytune %}
{%- for vcpus, nodes in cpu.tuning.memorytune.items() %}
<memorytune vcpus='{{ vcpus}}'>
{%- for id, bandwidth in nodes.items() %}
<node id='{{ id }}' bandwidth='{{ bandwidth }}'/>
{%- endfor %}
</memorytune>
{%- endfor %}
{%- endif %}
</cputune>
{%- endif %}
{%- if mem.max %}
<maxMemory {{ opt_attribute(mem, 'slots') }} unit='KiB'>{{ to_kib(mem.max) }}</maxMemory>
{%- endif %}
{%- if mem.boot %}
<memory unit='KiB'>{{ to_kib(mem.boot) }}</memory>
{%- endif %}
{%- if mem.current %}
<currentMemory unit='KiB'>{{ to_kib(mem.current) }}</currentMemory>
{%- endif %}
{%- if mem %}
<memtune>
{%- if 'hard_limit' in mem and mem.hard_limit %}
<hard_limit unit="KiB">{{ to_kib(mem.hard_limit) }}</hard_limit>
{%- endif %}
{%- if 'soft_limit' in mem and mem.soft_limit %}
<soft_limit unit="KiB">{{ to_kib(mem.soft_limit) }}</soft_limit>
{%- endif %}
{%- if 'swap_hard_limit' in mem and mem.swap_hard_limit %}
<swap_hard_limit unit="KiB">{{ to_kib(mem.swap_hard_limit) }}</swap_hard_limit>
{%- endif %}
{%- if 'min_guarantee' in mem and mem.min_guarantee %}
<min_guarantee unit="KiB">{{ to_kib(mem.min_guarantee) }}</min_guarantee>
{%- endif %}
</memtune>
{%- endif %}
{%- if numatune %}
<numatune>
{%- if 'memory' in numatune and numatune.memory %}
<memory mode='{{ numatune.memory.mode }}'{{ opt_attribute(numatune.memory, "nodeset") }}/>
{%- endif %}
{%- if 'memnodes' in numatune and numatune.memnodes %}
{%- for cell_id in numatune['memnodes'] %}
<memnode cellid='{{ cell_id }}' mode='{{ numatune.memnodes[cell_id].mode }}' nodeset='{{ numatune.memnodes[cell_id].nodeset }}'/>
{%- endfor %}
{%- endif %}
</numatune>
{%- endif %}
{%- if mem %}
<memoryBacking>
{%- if mem.hugepages %}
<hugepages>
{%- for page in mem.hugepages %}
<page size="{{ to_kib(page.get("size")) }}" unit="KiB"{{ opt_attribute(page, "nodeset" )}}/>
{%- endfor %}
</hugepages>
{%- if mem.nosharepages %}
<nosharepages/>
{%- endif %}
{%- if mem.locked %}
<locked/>
{%- endif %}
{%- if mem.source %}
<source type="{{ mem.source }}"/>
{%- endif %}
{%- if mem.access %}
<access mode="{{ mem.access }}"/>
{%- endif %}
{%- if mem.allocation %}
<allocation mode="{{ mem.allocation }}"/>
{%- endif %}
{%- if mem.discard %}
<discard/>
{%- endif %}
{%- endif %}
</memoryBacking>
{%- endif %}
<os {{ boot.os_attrib }}>
<type arch='{{ arch }}'>{{ os_type }}</type>
{%- if boot %}
{%- if 'kernel' in boot %}
<kernel>{{ boot.kernel }}</kernel>
{%- endif %}
{%- if 'initrd' in boot %}
<initrd>{{ boot.initrd }}</initrd>
{%- endif %}
{%- if 'cmdline' in boot %}
<cmdline>{{ boot.cmdline }}</cmdline>
{%- endif %}
{%- if 'loader' in boot %}
<loader readonly='yes' type='pflash'>{{ boot.loader }}</loader>
{%- endif %}
{%- if 'nvram' in boot %}
<nvram template='{{boot.nvram}}'></nvram>
{%- endif %}
{%- endif %}
{%- for dev in boot_dev %}
<boot dev='{{ dev }}' />
{%- endfor %}
</os>
{%- if clock %}
<clock offset="{{ clock.offset }}"{{ opt_attribute(clock, "adjustment") }}{{ opt_attribute(clock, "timezone") }}>
{%- for timer_name in clock.timers %}
{%- set timer = clock.timers[timer_name] %}
<timer name='{{ timer_name }}'{{ opt_attribute(timer, "track") }}{{ opt_attribute(timer, "tickpolicy") }}{{ opt_attribute(timer, "frequency") }}{{ opt_attribute(timer, "mode") }}{{ opt_attribute(timer, "present", yesno) }}>
{%- if "threshold" in timer or "slew" in timer or "limit" in timer %}
<catchup{{ opt_attribute(timer, "slew") }}{{ opt_attribute(timer, "threshold") }}{{ opt_attribute(timer, "limit") }}/>
{%- endif %}
</timer>
{%- endfor %}
</clock>
{%- endif %}
<on_reboot>{{ on_reboot }}</on_reboot>
<devices>
{%- for disk in disks %}
<disk type='{{ disk.type }}' device='{{ disk.device }}'>
{%- if disk.type == 'file' and 'source_file' in disk -%}
<source file='{{ disk.source_file }}' />
{%- endif %}
{%- if disk.type == 'block' -%}
<source dev='{{ disk.source_file }}' />
{%- endif %}
{%- if disk.type == 'volume' and 'pool' in disk -%}
<source pool='{{ disk.pool }}' volume='{{ disk.volume }}' />
{%- endif %}
{%- if disk.type == 'network' %}{{ libvirt_disks.network_source(disk) }}{%- endif %}
<target dev='{{ disk.target_dev }}' bus='{{ disk.disk_bus }}' />
{%- if disk.address -%}
<address type='drive' controller='0' bus='0' target='0' unit='{{ disk.index }}' />
{%- endif %}
{%- if disk.driver -%}
<driver name='qemu' type='{{ disk.format}}' cache='none' io='{{ disk.io }}'{{ opt_attribute(disk, "iothread") }}/>
{%- endif %}
</disk>
{%- endfor %}
{%- if controller_model %}
<controller type='scsi' index='0' model='{{ controller_model }}' />
{%- endif %}
{%- for nic in nics %}
<interface type='{{ nic.type }}'>
<source {{ nic.type }}='{{ nic.source }}'/>
{%- if nic.get('mac') -%}
<mac address='{{ nic.mac }}'/>
{%- endif %}
{%- if nic.model %}<model type='{{ nic.model }}'/>{% endif %}
</interface>
{%- endfor %}
{%- if graphics %}
<graphics type='{{ graphics.type }}'{{ opt_attribute(graphics, "port") }}
{%- if graphics.listen.address %}
listen='{{ graphics.listen.address }}'
{%- endif %}
{%- if graphics.type == 'spice' and graphics.tls_port %}
tlsPort='{{ graphics.tls_port }}'
{%- endif %}
autoport='{{ yesno(not graphics.port and not graphics.tls_port) }}'>
<listen type='{{ graphics.listen.type }}'{{ opt_attribute(graphics.listen, "address") }}/>
</graphics>
{%- if graphics.type == "spice" and hypervisor in ["qemu", "kvm"] %}
<channel type='spicevmc'>
<target type='virtio' name='com.redhat.spice.0'/>
</channel>
{%- endif %}
{%- endif %}
{%- for serial in serials %}
<serial type='{{ serial.type }}'>
{{ libvirt_chardevs.chardev(serial) }}
</serial>
{%- endfor %}
{%- for console in consoles %}
<console type='{{ console.type }}'>
{{ libvirt_chardevs.chardev(console) }}
</console>
{%- endfor %}
{%- if hypervisor in ["qemu", "kvm"] %}
<channel type='unix'>
<target type='virtio' name='org.qemu.guest_agent.0'/>
</channel>
{%- endif %}
{%- for hostdev in hostdevs %}
<hostdev mode='subsystem' type='{{ hostdev["type"] }}'{% if hostdev["type"] == "pci" %} managed='yes'{% endif %}>
<source>
{%- if hostdev["type"] == "usb" %}
<vendor id='{{ hostdev["vendor"] }}'/>
<product id='{{ hostdev["product"] }}'/>
{%- elif hostdev["type"] == "pci" %}
<address
domain='{{ hostdev["domain"] }}'
bus='{{ hostdev["bus"] }}'
slot='{{ hostdev["slot"] }}'
function='{{ hostdev["function"] }}'/>
{%- endif %}
</source>
</hostdev>
{%- endfor %}
</devices>
<features>
<acpi />
<apic />
<pae />
{%- if hypervisor_features.get("kvm-hint-dedicated") %}
<kvm>
<hint-dedicated state="on"/>
</kvm>
{%- endif %}
</features>
</domain>