From 8a724e01d1443e4f7c269dc0d2218388b6b6264b Mon Sep 17 00:00:00 2001 From: Alejandro Mosteiro Date: Mon, 23 Feb 2026 13:16:10 +0100 Subject: [PATCH 1/6] M #-: Improve infra role - Add support for OVS and OVS + DPDK interfaces for infra VMs - Add qemu-guest-agent to infra VM template - Add SEARCH_DOMAIN as supported context parameter - Install opennebula-node-kvm and configure libvirt as part of infra tasks Signed-off-by: Alejandro Mosteiro --- roles/infra/README.md | 59 +++++++++++++++------------ roles/infra/defaults/main.yml | 1 + roles/infra/tasks/main.yml | 25 ++++++++++++ roles/infra/templates/context.sh.j2 | 1 + roles/infra/templates/frontend.xml.j2 | 35 +++++++++++++--- 5 files changed, 89 insertions(+), 32 deletions(-) diff --git a/roles/infra/README.md b/roles/infra/README.md index d1a4a417..235f8dca 100644 --- a/roles/infra/README.md +++ b/roles/infra/README.md @@ -1,44 +1,49 @@ Role: opennebula.deploy.infra ============================= -A role that pre-deploys Front-end VMs directly in Libvirt. +A role that pre-deploys Front-end VMs directly in Libvirt after installing `opennebula-node-kvm` and configuring Libvirt in target hypervisor. Requirements ------------ -Pre-installed Libvirt software. Role Variables -------------- -| Name | Type | Default | Example | Description | -|--------------------------|--------|--------------------|---------------------|-------------------------------------------------------------------| -| `frontend_group` | `str` | `frontend` | | Custom name of the Frontend group in the inventory. | -| `infra_group` | `str` | `infra` | | Custom name of the Infra group in the inventory. | -| | | | | | -| `runtime_dir` | `str` | `/var/one-deploy/` | | Directory used to store QCOW2 and ISO images. | -| `os_image_url` | `str` | (check below) | | HTTP(S) link to Debian/RedHat-like image running `one-contextd`. | -| `os_image_size` | `str` | `20G` | | The size to which one-deploy will **try** to adjust the OS image. | -| `memory_KiB` | `str` | `2097152` | | Memory amount to be set in XML in Libvirt. | -| `vcpu_static` | `str` | `1` | | VCPU amount to be set in XML in Libvirt. | -| `vnc_max_port` | `str` | `65535` | | Upper limit for VNC ports to start counting-down from. | -| `infra_bridge` | `str` | `br0` | | Pre-defined bridge interface to insert VM NICs to. | -| `passthrough_fs` | `list` | `[]` | (check below) | Shared HV filesystems to attach to the Front-end VMs. | -| | | | | | -| `infra_hostname` | `str` | | `n1a1` | Defines on which HV machine the Front-end VM should be deployed. | -| `context.ETH0_DNS` | `str` | | `1.1.1.1` | DNS server. | -| `context.ETH0_GATEWAY` | `str` | | `10.2.50.1` | Gateway. | -| `context.ETH0_IP` | `str` | | `10.2.50.100` | IPv4 address to be set on eth0. | -| `context.ETH0_MAC` | `str` | | `02:01:0a:02:32:64` | MAC address to be set on eth0 (**MUST** match MAC set in XML.) | -| `context.ETH0_MASK` | `str` | | `255.255.255.0` | Network mask. | -| `context.ETH0_NETWORK` | `str` | | `10.2.50.0` | Network address. | -| `context.GROW_FS` | `str` | `/` | | Filesystems to grow. | -| `context.PASSWORD` | `str` | `opennebula` | | Root's password. | -| `context.SET_HOSTNAME` | `str` | name of the FE VM | | Hostname. | -| `context.SSH_PUBLIC_KEY` | `str` | | (check below) | Root's extra authorized keys. | +| Name | Type | Default | Example | Description | +|------------------------------|--------|--------------------|---------------------|-------------------------------------------------------------------| +| `frontend_group` | `str` | `frontend` | | Custom name of the Frontend group in the inventory. | +| `infra_group` | `str` | `infra` | | Custom name of the Infra group in the inventory. | +| | | | | | +| `runtime_dir` | `str` | `/var/one-deploy/` | | Directory used to store QCOW2 and ISO images. | +| `os_image_url` | `str` | (check below) | | HTTP(S) link to Debian/RedHat-like image running `one-contextd`. | +| `os_image_size` | `str` | `20G` | | The size to which one-deploy will **try** to adjust the OS image. | +| `memory_KiB` | `str` | `2097152` | | Memory amount to be set in XML in Libvirt. | +| `vcpu_static` | `str` | `1` | | VCPU amount to be set in XML in Libvirt. | +| `vnc_max_port` | `str` | `65535` | | Upper limit for VNC ports to start counting-down from. | +| `infra_bridge` | `str` | `br0` | | Pre-defined bridge interface to insert VM NICs to. | +| `infra_bridge_type` | `str` | `bridge` | | Supported values: bridge, openvswitch, openvswitch_dpdk | +| `infra_dpdk_socket_path` | `str` | | | Path for existing socket when using OVS with DPDK. | +| `infra_vlan_id` | `str` | | | Optionally set the VLAN ID for the bridge. | +| `passthrough_fs` | `list` | `[]` | (check below) | Shared HV filesystems to attach to the Front-end VMs. | +| | | | | | +| `infra_hostname` | `str` | | `n1a1` | Defines on which HV machine the Front-end VM should be deployed. | +| `context.ETH0_DNS` | `str` | | `1.1.1.1` | DNS server. | +| `context.ETH0_SEARCH_DOMAIN` | `str` | | `1.1.1.1` | DNS search domain. | +| `context.ETH0_GATEWAY` | `str` | | `10.2.50.1` | Gateway. | +| `context.ETH0_IP` | `str` | | `10.2.50.100` | IPv4 address to be set on eth0. | +| `context.ETH0_MAC` | `str` | | `02:01:0a:02:32:64` | MAC address to be set on eth0 (**MUST** match MAC set in XML.) | +| `context.ETH0_MASK` | `str` | | `255.255.255.0` | Network mask. | +| `context.ETH0_NETWORK` | `str` | | `10.2.50.0` | Network address. | +| `context.GROW_FS` | `str` | `/` | | Filesystems to grow. | +| `context.PASSWORD` | `str` | `opennebula` | | Root's password. | +| `context.SET_HOSTNAME` | `str` | name of the FE VM | | Hostname. | +| `context.SSH_PUBLIC_KEY` | `str` | | (check below) | Root's extra authorized keys. | **NOTE**: The `infra_hostname` and `context` dictionary should be set for members of the `frontend` group (please check the `inventory/infra.yml` example). +**NOTE**: Use `--skip-tags libvirt` when pre-installed Libvirt software is available in `infra_hostname`. + Dependencies ------------ diff --git a/roles/infra/defaults/main.yml b/roles/infra/defaults/main.yml index 685b7781..d6df3480 100644 --- a/roles/infra/defaults/main.yml +++ b/roles/infra/defaults/main.yml @@ -6,4 +6,5 @@ memory_KiB: 2097152 # 2 GiB vcpu_static: 1 vnc_max_port: 65535 infra_bridge: br0 +infra_bridge_type: bridge passthrough_fs: [] diff --git a/roles/infra/tasks/main.yml b/roles/infra/tasks/main.yml index 0b724e0c..bddd7e11 100644 --- a/roles/infra/tasks/main.yml +++ b/roles/infra/tasks/main.yml @@ -12,6 +12,31 @@ retries: 12 delay: 5 +- tags: [libvirt] + block: + - ansible.builtin.include_role: + name: repository + vars: + repos_enabled: [opennebula] + when: opennebula_repo is undefined + + - name: Install OpenNebula KVM packages + ansible.builtin.package: + name: "{{ _common + _specific[ansible_os_family] }}" + vars: + _common: [opennebula-node-kvm] + _specific: + Debian: [] + RedHat: [] + register: package + until: package is success + retries: 12 + delay: 5 + + - ansible.builtin.include_role: + name: kvm + tasks_from: libvirt + - name: List defined VMs community.libvirt.virt: command: list_vms diff --git a/roles/infra/templates/context.sh.j2 b/roles/infra/templates/context.sh.j2 index 0997c2c2..2be98bd8 100644 --- a/roles/infra/templates/context.sh.j2 +++ b/roles/infra/templates/context.sh.j2 @@ -1,6 +1,7 @@ # Context variables generated by one-deploy DISK_ID='1' ETH0_DNS='{{ context.ETH0_DNS }}' +ETH0_SEARCH_DOMAIN='{{ context.ETH0_SEARCH_DOMAIN }}' ETH0_GATEWAY='{{ context.ETH0_GATEWAY }}' ETH0_IP='{{ context.ETH0_IP }}' ETH0_MAC='{{ context.ETH0_MAC | d("02:01:%02x:%02x:%02x:%02x" | format(*(context.ETH0_IP.split(".") | map("int")))) }}' diff --git a/roles/infra/templates/frontend.xml.j2 b/roles/infra/templates/frontend.xml.j2 index c6c328f5..5a54a118 100644 --- a/roles/infra/templates/frontend.xml.j2 +++ b/roles/infra/templates/frontend.xml.j2 @@ -22,12 +22,17 @@ restart destroy -{% if 'virtiofs' in (passthrough_fs | map(attribute='driver_type') - | map('default', None) - | select - | map('lower')) %} +{% set use_dpdk = (infra_bridge_type is defined and infra_bridge_type == 'openvswitch_dpdk') %} +{% set use_virtiofs = ('virtiofs' in (passthrough_fs | map(attribute='driver_type') | map('default', None) | select | map('lower'))) %} + +{% if use_dpdk or use_virtiofs %} +{% if use_dpdk %} + +{% endif %} +{% if use_virtiofs and not use_dpdk %} +{% endif %} {% endif %} @@ -82,14 +87,34 @@
+{% if infra_bridge_type is defined and infra_bridge_type in ['bridge', 'openvswitch', 'openvswitch_dpdk'] %} +{% if infra_bridge_type in ['bridge', 'openvswitch'] %} - +{% elif infra_bridge_type == 'openvswitch_dpdk' %} + + + +{% endif %} + +{% if infra_bridge_type == 'openvswitch' %} + +{% endif %} +{% if infra_vlan_id is defined and infra_vlan_id %} + + + +{% endif %}
+{% endif %} + + + + From e2b804d4b7e038b9cf2009ebda490ef8aff2fc8f Mon Sep 17 00:00:00 2001 From: Alejandro Mosteiro Date: Tue, 24 Feb 2026 11:17:55 +0100 Subject: [PATCH 2/6] M #-: Optionally install opennebula-node-kvm in infra role Signed-off-by: Alejandro Mosteiro --- roles/infra/README.md | 64 +++++++++++++++++------------------ roles/infra/defaults/main.yml | 1 + roles/infra/tasks/main.yml | 3 +- 3 files changed, 35 insertions(+), 33 deletions(-) diff --git a/roles/infra/README.md b/roles/infra/README.md index 235f8dca..ae98c05f 100644 --- a/roles/infra/README.md +++ b/roles/infra/README.md @@ -1,49 +1,49 @@ Role: opennebula.deploy.infra ============================= -A role that pre-deploys Front-end VMs directly in Libvirt after installing `opennebula-node-kvm` and configuring Libvirt in target hypervisor. +A role that pre-deploys Front-end VMs directly in Libvirt. Requirements ------------ +Pre-installed Libvirt software. Use `infra_install_opennebula_node_kvm` if Libvirt is not pre-installed and you want to use `opennebula-node-kvm` to install it. Role Variables -------------- -| Name | Type | Default | Example | Description | -|------------------------------|--------|--------------------|---------------------|-------------------------------------------------------------------| -| `frontend_group` | `str` | `frontend` | | Custom name of the Frontend group in the inventory. | -| `infra_group` | `str` | `infra` | | Custom name of the Infra group in the inventory. | -| | | | | | -| `runtime_dir` | `str` | `/var/one-deploy/` | | Directory used to store QCOW2 and ISO images. | -| `os_image_url` | `str` | (check below) | | HTTP(S) link to Debian/RedHat-like image running `one-contextd`. | -| `os_image_size` | `str` | `20G` | | The size to which one-deploy will **try** to adjust the OS image. | -| `memory_KiB` | `str` | `2097152` | | Memory amount to be set in XML in Libvirt. | -| `vcpu_static` | `str` | `1` | | VCPU amount to be set in XML in Libvirt. | -| `vnc_max_port` | `str` | `65535` | | Upper limit for VNC ports to start counting-down from. | -| `infra_bridge` | `str` | `br0` | | Pre-defined bridge interface to insert VM NICs to. | -| `infra_bridge_type` | `str` | `bridge` | | Supported values: bridge, openvswitch, openvswitch_dpdk | -| `infra_dpdk_socket_path` | `str` | | | Path for existing socket when using OVS with DPDK. | -| `infra_vlan_id` | `str` | | | Optionally set the VLAN ID for the bridge. | -| `passthrough_fs` | `list` | `[]` | (check below) | Shared HV filesystems to attach to the Front-end VMs. | -| | | | | | -| `infra_hostname` | `str` | | `n1a1` | Defines on which HV machine the Front-end VM should be deployed. | -| `context.ETH0_DNS` | `str` | | `1.1.1.1` | DNS server. | -| `context.ETH0_SEARCH_DOMAIN` | `str` | | `1.1.1.1` | DNS search domain. | -| `context.ETH0_GATEWAY` | `str` | | `10.2.50.1` | Gateway. | -| `context.ETH0_IP` | `str` | | `10.2.50.100` | IPv4 address to be set on eth0. | -| `context.ETH0_MAC` | `str` | | `02:01:0a:02:32:64` | MAC address to be set on eth0 (**MUST** match MAC set in XML.) | -| `context.ETH0_MASK` | `str` | | `255.255.255.0` | Network mask. | -| `context.ETH0_NETWORK` | `str` | | `10.2.50.0` | Network address. | -| `context.GROW_FS` | `str` | `/` | | Filesystems to grow. | -| `context.PASSWORD` | `str` | `opennebula` | | Root's password. | -| `context.SET_HOSTNAME` | `str` | name of the FE VM | | Hostname. | -| `context.SSH_PUBLIC_KEY` | `str` | | (check below) | Root's extra authorized keys. | +| Name | Type | Default | Example | Description | +|--------------------------------------|--------|--------------------|---------------------|-------------------------------------------------------------------| +| `frontend_group` | `str` | `frontend` | | Custom name of the Frontend group in the inventory. | +| `infra_group` | `str` | `infra` | | Custom name of the Infra group in the inventory. | +| | | | | | +| `runtime_dir` | `str` | `/var/one-deploy/` | | Directory used to store QCOW2 and ISO images. | +| `os_image_url` | `str` | (check below) | | HTTP(S) link to Debian/RedHat-like image running `one-contextd`. | +| `os_image_size` | `str` | `20G` | | The size to which one-deploy will **try** to adjust the OS image. | +| `memory_KiB` | `str` | `2097152` | | Memory amount to be set in XML in Libvirt. | +| `vcpu_static` | `str` | `1` | | VCPU amount to be set in XML in Libvirt. | +| `vnc_max_port` | `str` | `65535` | | Upper limit for VNC ports to start counting-down from. | +| `passthrough_fs` | `list` | `[]` | (check below) | Shared HV filesystems to attach to the Front-end VMs. | +| | | | | | +| `infra_bridge` | `str` | `br0` | | Pre-defined bridge interface to insert VM NICs to. | +| `infra_bridge_type` | `str` | `bridge` | | Supported values: bridge, openvswitch, openvswitch_dpdk | +| `infra_dpdk_socket_path` | `str` | | | Path for existing socket when using OVS with DPDK. | +| `infra_vlan_id` | `str` | | | Optionally set the VLAN ID for the bridge. | +| `infra_hostname` | `str` | | `n1a1` | Defines on which HV machine the Front-end VM should be deployed. | +| `infra_install_opennebula_node_kvm` | `bool` | `false` | | Installs opennebula-node-kvm package in HV before deploying VMs. | +| `context.ETH0_DNS` | `str` | | `1.1.1.1` | DNS server. | +| `context.ETH0_SEARCH_DOMAIN` | `str` | | `1.1.1.1` | DNS search domain. | +| `context.ETH0_GATEWAY` | `str` | | `10.2.50.1` | Gateway. | +| `context.ETH0_IP` | `str` | | `10.2.50.100` | IPv4 address to be set on eth0. | +| `context.ETH0_MAC` | `str` | | `02:01:0a:02:32:64` | MAC address to be set on eth0 (**MUST** match MAC set in XML.) | +| `context.ETH0_MASK` | `str` | | `255.255.255.0` | Network mask. | +| `context.ETH0_NETWORK` | `str` | | `10.2.50.0` | Network address. | +| `context.GROW_FS` | `str` | `/` | | Filesystems to grow. | +| `context.PASSWORD` | `str` | `opennebula` | | Root's password. | +| `context.SET_HOSTNAME` | `str` | name of the FE VM | | Hostname. | +| `context.SSH_PUBLIC_KEY` | `str` | | (check below) | Root's extra authorized keys. | **NOTE**: The `infra_hostname` and `context` dictionary should be set for members of the `frontend` group (please check the `inventory/infra.yml` example). -**NOTE**: Use `--skip-tags libvirt` when pre-installed Libvirt software is available in `infra_hostname`. - Dependencies ------------ diff --git a/roles/infra/defaults/main.yml b/roles/infra/defaults/main.yml index d6df3480..fecb1a20 100644 --- a/roles/infra/defaults/main.yml +++ b/roles/infra/defaults/main.yml @@ -7,4 +7,5 @@ vcpu_static: 1 vnc_max_port: 65535 infra_bridge: br0 infra_bridge_type: bridge +infra_install_opennebula_node_kvm: false passthrough_fs: [] diff --git a/roles/infra/tasks/main.yml b/roles/infra/tasks/main.yml index bddd7e11..01e16934 100644 --- a/roles/infra/tasks/main.yml +++ b/roles/infra/tasks/main.yml @@ -12,7 +12,8 @@ retries: 12 delay: 5 -- tags: [libvirt] +- name: Install opennebula-node-kvm + when: infra_install_opennebula_node_kvm | bool block: - ansible.builtin.include_role: name: repository From 3e71609da2f5f26e06be0520c79874473c22e61a Mon Sep 17 00:00:00 2001 From: Alejandro Mosteiro Date: Fri, 27 Feb 2026 12:20:18 +0100 Subject: [PATCH 3/6] M #-: Change templates extension to jinja in infra role Signed-off-by: Alejandro Mosteiro --- roles/infra/templates/{context.sh.j2 => context.sh.jinja} | 0 roles/infra/templates/{frontend.xml.j2 => frontend.xml.jinja} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename roles/infra/templates/{context.sh.j2 => context.sh.jinja} (100%) rename roles/infra/templates/{frontend.xml.j2 => frontend.xml.jinja} (100%) diff --git a/roles/infra/templates/context.sh.j2 b/roles/infra/templates/context.sh.jinja similarity index 100% rename from roles/infra/templates/context.sh.j2 rename to roles/infra/templates/context.sh.jinja diff --git a/roles/infra/templates/frontend.xml.j2 b/roles/infra/templates/frontend.xml.jinja similarity index 100% rename from roles/infra/templates/frontend.xml.j2 rename to roles/infra/templates/frontend.xml.jinja From cd4b5e81044253499932343ef30c880474e5efd1 Mon Sep 17 00:00:00 2001 From: Alejandro Mosteiro Date: Fri, 27 Feb 2026 12:29:35 +0100 Subject: [PATCH 4/6] M OpenNebula/one-deploy#179: Use q35 for machine type in infra VMs Signed-off-by: Alejandro Mosteiro --- roles/infra/templates/frontend.xml.jinja | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/infra/templates/frontend.xml.jinja b/roles/infra/templates/frontend.xml.jinja index 5a54a118..a38783f1 100644 --- a/roles/infra/templates/frontend.xml.jinja +++ b/roles/infra/templates/frontend.xml.jinja @@ -10,7 +10,7 @@ /machine - hvm + hvm From a370b2bb5c2f469a1bbddf4e89c280ccb78e98bc Mon Sep 17 00:00:00 2001 From: Alejandro Mosteiro Date: Wed, 4 Mar 2026 11:33:59 +0100 Subject: [PATCH 5/6] M OpenNebula/one-deploy#179: Update infra VM template to work with q35 - Update devices to be compatible with machine type q35 - Update inputs and graphics devices to modern options - Remove addresses for devices, let libvirt auto assign them - Update deploy task to use .jinja extensions Signed-off-by: Alejandro Mosteiro --- roles/infra/tasks/deploy.yml | 4 +- roles/infra/templates/frontend.xml.jinja | 56 +++++++++++++----------- 2 files changed, 32 insertions(+), 28 deletions(-) diff --git a/roles/infra/tasks/deploy.yml b/roles/infra/tasks/deploy.yml index 6639266b..90dbdb77 100644 --- a/roles/infra/tasks/deploy.yml +++ b/roles/infra/tasks/deploy.yml @@ -34,7 +34,7 @@ - name: Create context.sh files ansible.builtin.template: dest: "{{ tempfile.results[item].path }}/context.sh" - src: context.sh.j2 + src: context.sh.jinja mode: ug=rw,o= vars: frontend: "{{ tempfile.results[item].frontend }}" @@ -100,7 +100,7 @@ - name: Define Front-end VMs community.libvirt.virt: command: define - xml: "{{ lookup('template', 'frontend.xml.j2') }}" + xml: "{{ lookup('template', 'frontend.xml.jinja') }}" autostart: true vars: context: "{{ hostvars[frontend].context }}" diff --git a/roles/infra/templates/frontend.xml.jinja b/roles/infra/templates/frontend.xml.jinja index a38783f1..34af82bc 100644 --- a/roles/infra/templates/frontend.xml.jinja +++ b/roles/infra/templates/frontend.xml.jinja @@ -9,8 +9,12 @@ /machine - + hvm + + + + @@ -42,34 +46,35 @@ - + - -
+ - + - - -
+ + - - - -
+ + - - + + + + - - -
+ + + + + + {% for fs in passthrough_fs %} @@ -84,7 +89,6 @@ -
{% if infra_bridge_type is defined and infra_bridge_type in ['bridge', 'openvswitch', 'openvswitch_dpdk'] %} @@ -98,7 +102,7 @@ {% endif %} -{% if infra_bridge_type == 'openvswitch' %} +{% if infra_bridge_type == 'openvswitch' %} {% endif %} {% if infra_vlan_id is defined and infra_vlan_id %} @@ -108,19 +112,20 @@ {% endif %} -
{% endif %} - + + + - + - + @@ -131,9 +136,8 @@