From b89613bffadaa52438ea3f3606e460dceee07ae1 Mon Sep 17 00:00:00 2001 From: Miguel Angel Nieto Jimenez Date: Wed, 18 Feb 2026 16:25:39 +0100 Subject: [PATCH] [multiple] Co-locate provisionserver with metal3 to prevent DHCP failures II When metal3-dnsmasq pod restarts during a node's DHCP lease renewal on the provisioning network (172.23.0.0/24), NetworkManager fails to renew and sets ipv4.method=disabled. NMState operator then preserves this disabled state, causing permanent loss of provisioning network connectivity on that node. The issue occurs when OpenStackProvisionServer and metal3 pods run on different nodes. If metal3 restarts while a node is attempting DHCP renewal, the temporary unavailability of metal3-dnsmasq causes the renewal to fail. Solution: Automatically detect the node running metal3 pod (via k8s-app=metal3 label) and configure provisionServerNodeSelector in baremetalSetTemplate to schedule OpenStackProvisionServer on the same node. This ensures provisioning network connectivity is maintained because metal3-static-ip-manager maintains a static IP (172.23.0.3) on the metal3 node regardless of dnsmasq restarts. Signed-off-by: Miguel Angel Nieto Jimenez Co-Authored-By: Claude Sonnet 4.5 --- .../edpm-nodeset-values/values.yaml.j2 | 9 ++++++++ .../edpm-nodeset-values/values.yaml.j2 | 9 ++++++++ .../edpm-nodeset-values/values.yaml.j2 | 9 ++++++++ .../edpm-nodeset-values/values.yaml.j2 | 9 ++++++++ .../edpm-nodeset-values/values.yaml.j2 | 9 ++++++++ .../edpm-nodeset-values/values.yaml.j2 | 9 ++++++++ .../sriov/edpm-nodeset-values/values.yaml.j2 | 9 ++++++++ roles/kustomize_deploy/tasks/execute_step.yml | 23 +++++++++++++++++++ 8 files changed, 86 insertions(+) diff --git a/roles/ci_gen_kustomize_values/templates/nfv-ovs-dpdk-sriov-hci/edpm-nodeset-values/values.yaml.j2 b/roles/ci_gen_kustomize_values/templates/nfv-ovs-dpdk-sriov-hci/edpm-nodeset-values/values.yaml.j2 index 369dae6a2b..0119057a93 100644 --- a/roles/ci_gen_kustomize_values/templates/nfv-ovs-dpdk-sriov-hci/edpm-nodeset-values/values.yaml.j2 +++ b/roles/ci_gen_kustomize_values/templates/nfv-ovs-dpdk-sriov-hci/edpm-nodeset-values/values.yaml.j2 @@ -4,6 +4,7 @@ {% set _original_nodeset = (original_content.data | default({})).nodeset | default({}) %} {% set _original_nodes = _original_nodeset.nodes | default({}) %} {% set _original_services = _original_nodeset['services'] | default([]) %} +{% set _original_baremetal_template = (original_content.data | default({})).baremetalSetTemplate | default({}) %} {% for _inst in cifmw_baremetal_hosts.keys() %} {% set _ = instances_names.append(_inst) %} {% endfor %} @@ -43,3 +44,11 @@ data: - "{{ svc }}" {% endfor %} {% endif %} +{% if cifmw_kustomize_deploy_metal3_node is defined %} + baremetalSetTemplate: +{% for key, value in _original_baremetal_template.items() %} + {{ key }}: {{ value }} +{% endfor %} + provisionServerNodeSelector: + kubernetes.io/hostname: "{{ cifmw_kustomize_deploy_metal3_node }}" +{% endif %} diff --git a/roles/ci_gen_kustomize_values/templates/ovs-dpdk-sriov-2nodesets/edpm-nodeset-values/values.yaml.j2 b/roles/ci_gen_kustomize_values/templates/ovs-dpdk-sriov-2nodesets/edpm-nodeset-values/values.yaml.j2 index 6ae842b92b..c8e0045ade 100644 --- a/roles/ci_gen_kustomize_values/templates/ovs-dpdk-sriov-2nodesets/edpm-nodeset-values/values.yaml.j2 +++ b/roles/ci_gen_kustomize_values/templates/ovs-dpdk-sriov-2nodesets/edpm-nodeset-values/values.yaml.j2 @@ -4,6 +4,7 @@ {% set _original_nodeset = (original_content.data | default({})).nodeset | default({}) %} {% set _original_nodes = _original_nodeset.nodes | default({}) %} {% set _original_services = _original_nodeset['services'] | default([]) %} +{% set _original_baremetal_template = (original_content.data | default({})).baremetalSetTemplate | default({}) %} {% if cifmw_baremetal_hosts | default([]) | length > 0 %} {% for _inst in cifmw_baremetal_hosts.keys() %} {% if (('label' in cifmw_baremetal_hosts[_inst]) and @@ -56,3 +57,11 @@ data: - "{{ svc }}" {% endfor %} {% endif %} +{% if cifmw_kustomize_deploy_metal3_node is defined %} + baremetalSetTemplate: +{% for key, value in _original_baremetal_template.items() %} + {{ key }}: {{ value }} +{% endfor %} + provisionServerNodeSelector: + kubernetes.io/hostname: "{{ cifmw_kustomize_deploy_metal3_node }}" +{% endif %} diff --git a/roles/ci_gen_kustomize_values/templates/ovs-dpdk-sriov-ipv6-2nodesets/edpm-nodeset-values/values.yaml.j2 b/roles/ci_gen_kustomize_values/templates/ovs-dpdk-sriov-ipv6-2nodesets/edpm-nodeset-values/values.yaml.j2 index 62ec8dad00..bc10fd8d90 100644 --- a/roles/ci_gen_kustomize_values/templates/ovs-dpdk-sriov-ipv6-2nodesets/edpm-nodeset-values/values.yaml.j2 +++ b/roles/ci_gen_kustomize_values/templates/ovs-dpdk-sriov-ipv6-2nodesets/edpm-nodeset-values/values.yaml.j2 @@ -4,6 +4,7 @@ {% set _original_nodeset = (original_content.data | default({})).nodeset | default({}) %} {% set _original_nodes = _original_nodeset.nodes | default({}) %} {% set _original_services = _original_nodeset['services'] | default([]) %} +{% set _original_baremetal_template = (original_content.data | default({})).baremetalSetTemplate | default({}) %} {% if cifmw_baremetal_hosts | default([]) | length > 0 %} {% for _inst in cifmw_baremetal_hosts.keys() %} {% if (('label' in cifmw_baremetal_hosts[_inst]) and @@ -56,3 +57,11 @@ data: - "{{ svc }}" {% endfor %} {% endif %} +{% if cifmw_kustomize_deploy_metal3_node is defined %} + baremetalSetTemplate: +{% for key, value in _original_baremetal_template.items() %} + {{ key }}: {{ value }} +{% endfor %} + provisionServerNodeSelector: + kubernetes.io/hostname: "{{ cifmw_kustomize_deploy_metal3_node }}" +{% endif %} diff --git a/roles/ci_gen_kustomize_values/templates/ovs-dpdk-sriov-ipv6/edpm-nodeset-values/values.yaml.j2 b/roles/ci_gen_kustomize_values/templates/ovs-dpdk-sriov-ipv6/edpm-nodeset-values/values.yaml.j2 index cf1e9ce624..76207e147c 100644 --- a/roles/ci_gen_kustomize_values/templates/ovs-dpdk-sriov-ipv6/edpm-nodeset-values/values.yaml.j2 +++ b/roles/ci_gen_kustomize_values/templates/ovs-dpdk-sriov-ipv6/edpm-nodeset-values/values.yaml.j2 @@ -4,6 +4,7 @@ {% set _original_nodeset = (original_content.data | default({})).nodeset | default({}) %} {% set _original_nodes = _original_nodeset.nodes | default({}) %} {% set _original_services = _original_nodeset['services'] | default([]) %} +{% set _original_baremetal_template = (original_content.data | default({})).baremetalSetTemplate | default({}) %} {% for _inst in cifmw_baremetal_hosts.keys() %} {% set _ = instances_names.append(_inst) %} {% endfor %} @@ -43,3 +44,11 @@ data: - "{{ svc }}" {% endfor %} {% endif %} +{% if cifmw_kustomize_deploy_metal3_node is defined %} + baremetalSetTemplate: +{% for key, value in _original_baremetal_template.items() %} + {{ key }}: {{ value }} +{% endfor %} + provisionServerNodeSelector: + kubernetes.io/hostname: "{{ cifmw_kustomize_deploy_metal3_node }}" +{% endif %} diff --git a/roles/ci_gen_kustomize_values/templates/ovs-dpdk-sriov/edpm-nodeset-values/values.yaml.j2 b/roles/ci_gen_kustomize_values/templates/ovs-dpdk-sriov/edpm-nodeset-values/values.yaml.j2 index 7d92c69d87..cf4082c389 100644 --- a/roles/ci_gen_kustomize_values/templates/ovs-dpdk-sriov/edpm-nodeset-values/values.yaml.j2 +++ b/roles/ci_gen_kustomize_values/templates/ovs-dpdk-sriov/edpm-nodeset-values/values.yaml.j2 @@ -4,6 +4,7 @@ {% set _original_nodeset = (original_content.data | default({})).nodeset | default({}) %} {% set _original_nodes = _original_nodeset.nodes | default({}) %} {% set _original_services = _original_nodeset['services'] | default([]) %} +{% set _original_baremetal_template = (original_content.data | default({})).baremetalSetTemplate | default({}) %} {% for _inst in cifmw_baremetal_hosts.keys() %} {% set _ = instances_names.append(_inst) %} {% endfor %} @@ -43,3 +44,11 @@ data: - "{{ svc }}" {% endfor %} {% endif %} +{% if cifmw_kustomize_deploy_metal3_node is defined %} + baremetalSetTemplate: +{% for key, value in _original_baremetal_template.items() %} + {{ key }}: {{ value }} +{% endfor %} + provisionServerNodeSelector: + kubernetes.io/hostname: "{{ cifmw_kustomize_deploy_metal3_node }}" +{% endif %} diff --git a/roles/ci_gen_kustomize_values/templates/ovs-dpdk/edpm-nodeset-values/values.yaml.j2 b/roles/ci_gen_kustomize_values/templates/ovs-dpdk/edpm-nodeset-values/values.yaml.j2 index 3d4fb5cc4d..af1438fa0c 100644 --- a/roles/ci_gen_kustomize_values/templates/ovs-dpdk/edpm-nodeset-values/values.yaml.j2 +++ b/roles/ci_gen_kustomize_values/templates/ovs-dpdk/edpm-nodeset-values/values.yaml.j2 @@ -4,6 +4,7 @@ {% set _original_nodeset = (original_content.data | default({})).nodeset | default({}) %} {% set _original_nodes = _original_nodeset.nodes | default({}) %} {% set _original_services = _original_nodeset['services'] | default([]) %} +{% set _original_baremetal_template = (original_content.data | default({})).baremetalSetTemplate | default({}) %} {% for _inst in cifmw_baremetal_hosts.keys() %} {% set _ = instances_names.append(_inst) %} {% endfor %} @@ -42,3 +43,11 @@ data: - "{{ svc }}" {% endfor %} {% endif %} +{% if cifmw_kustomize_deploy_metal3_node is defined %} + baremetalSetTemplate: +{% for key, value in _original_baremetal_template.items() %} + {{ key }}: {{ value }} +{% endfor %} + provisionServerNodeSelector: + kubernetes.io/hostname: "{{ cifmw_kustomize_deploy_metal3_node }}" +{% endif %} diff --git a/roles/ci_gen_kustomize_values/templates/sriov/edpm-nodeset-values/values.yaml.j2 b/roles/ci_gen_kustomize_values/templates/sriov/edpm-nodeset-values/values.yaml.j2 index 8139a2dc1d..35d55602be 100644 --- a/roles/ci_gen_kustomize_values/templates/sriov/edpm-nodeset-values/values.yaml.j2 +++ b/roles/ci_gen_kustomize_values/templates/sriov/edpm-nodeset-values/values.yaml.j2 @@ -4,6 +4,7 @@ {% set _original_nodeset = (original_content.data | default({})).nodeset | default({}) %} {% set _original_nodes = _original_nodeset.nodes | default({}) %} {% set _original_services = _original_nodeset['services'] | default([]) %} +{% set _original_baremetal_template = (original_content.data | default({})).baremetalSetTemplate | default({}) %} {% for _inst in cifmw_baremetal_hosts.keys() %} {% set _ = instances_names.append(_inst) %} {% endfor %} @@ -42,3 +43,11 @@ data: - "{{ svc }}" {% endfor %} {% endif %} +{% if cifmw_kustomize_deploy_metal3_node is defined %} + baremetalSetTemplate: +{% for key, value in _original_baremetal_template.items() %} + {{ key }}: {{ value }} +{% endfor %} + provisionServerNodeSelector: + kubernetes.io/hostname: "{{ cifmw_kustomize_deploy_metal3_node }}" +{% endif %} diff --git a/roles/kustomize_deploy/tasks/execute_step.yml b/roles/kustomize_deploy/tasks/execute_step.yml index 76bd5b82bf..5f8d53f502 100644 --- a/roles/kustomize_deploy/tasks/execute_step.yml +++ b/roles/kustomize_deploy/tasks/execute_step.yml @@ -126,6 +126,29 @@ ansible.builtin.include_role: name: run_hook + - name: Detect metal3 pod node for baremetal nodeset provisioning + when: + - not cifmw_kustomize_deploy_generate_crs_only | bool + - stage.path is defined + - stage.path is match('.*/edpm/nodeset.*') + block: + - name: Get metal3 pod information + kubernetes.core.k8s_info: + kubeconfig: "{{ cifmw_openshift_kubeconfig }}" + kind: Pod + namespace: openshift-machine-api + label_selectors: + - k8s-app=metal3 + register: _cifmw_kustomize_deploy_metal3_pod_info + + - name: Set metal3 node for provisionserver nodeSelector + ansible.builtin.set_fact: + cifmw_kustomize_deploy_metal3_node: "{{ _cifmw_kustomize_deploy_metal3_pod_info.resources[0].spec.nodeName }}" + cacheable: true + when: + - _cifmw_kustomize_deploy_metal3_pod_info.resources is defined + - _cifmw_kustomize_deploy_metal3_pod_info.resources | length > 0 + - name: "Generate values.yaml for {{ stage.path }}" when: - _val.src_file is defined