Changing Nova compute pod IP acquisition

This task aims to change the IP acquisition method for Nova compute
pods from the Nova plugin to a new environment variable that maps to
the status.hostIP field. The environment variable-based approach will
provide the cluster host IP address to the Nova compute container.

With the goal of assisting in the task of deploying Nova compute with
fewer daemonsets, grouping hosts with identical configurations, and
consequently making the solution more scalable, this implementation
removes the responsibility from the plugin of setting the IP
information, since doing so would prevent the grouping of the override
configurations due to having different values for each compute host.
Using the environment variable-based approach, the IP change will occur
inside the container just before executing the nova-compute command.

Since this task aims to set the IP inside the container and the Nova
configuration file located at /etc/nova is read-only, a new Nova
configuration file has been created, which is located inside the
compute container at /tmp/pod-shared, a similar approach of using this
path is already followed by other Nova configuration files
(nova-console.conf, nova-hypervisor.conf and nova-libvirt.conf). The
difference between the two nova.conf files is only the IPs in fields
my_ip, server_listen, server_proxyclient_address and
live_migration_inbound_addr, which will contain the cluster host IP
configured in the new environment variable in the new one.

TEST PLAN:
    PASS: build-pkg -c -l openstack
    PASS: build openstack tarball
    PASS: upload and apply openstack tarball on standard system
    PASS: nova-compute pod is running
    PASS: CLUSTER_HOST_IP environment variable created with
          .status.hostIP value
    PASS: /tmp/pod-shared/nova.conf has the same configuration of
          /etc/nova/nova.conf, with the only difference being that the
          fields:
                  DEFAULT.my_ip
                  vnc.server_listen
                  vnc.server_proxyclient_address and
                  libvirt.live_migration_inbound_addr
          are updated with the IP from the new environment variable
    PASS: launch a guest instance (tis-centos-guest VM)

Story: 2011304
Task: 51517

Change-Id: I19792f4c15bc9adddc7e45c2d600ddeb1b3ec420
Signed-off-by: marantes <murillo.arantes@windriver.com>
This commit is contained in:
marantes 2025-01-06 14:13:18 -03:00
parent 72be7336c9
commit 785cfbb4f0
5 changed files with 133 additions and 19 deletions
openstack-helm/debian/deb_folder/patches
python3-k8sapp-openstack/k8sapp_openstack/k8sapp_openstack
helm
tests/helm
stx-openstack-helm-fluxcd/stx-openstack-helm-fluxcd/manifests/nova

@ -0,0 +1,127 @@
From 9dbf2a0cc29a051471b7bdf8f4f762259722d5a9 Mon Sep 17 00:00:00 2001
From: marantes <murillo.arantes@windriver.com>
Date: Fri, 3 Jan 2025 16:04:17 -0300
Subject: [PATCH] Add cluster host ip env var to nova
This patch reads the Nova configurations from /etc/nova/nova.conf and
writes them to a new Nova configuration file located at
/tmp/pod-shared/nova.conf, with the only difference being that the
fields DEFAULT.my_ip, vnc.server_listen, vnc.server_proxyclient_address
and libvirt.live_migration_inbound_addr will be updated to contain the
cluster host IP configured in a environment variable. This new
configuration file will be used by the Nova compute container.
This patch aims to assist in the task of changing the IP acquisition
method for Nova compute pods from the Nova plugin to an environment
variable-based approach that will provide the cluster host IP address
to the Nova compute container. Since the Nova configuration file
located at /etc/nova is read-only, the solution of creating a new
configuration file was used, following a similar approach that is
already followed by other Nova configuration files using this path
(nova-console.conf, nova-hypervisor.conf and nova-libvirt.conf).
Signed-off-by: Murillo Arantes <murillo.arantes@windriver.com>
---
nova/templates/bin/_nova-compute.sh.tpl | 51 ++++++++++++++++++++++++-
nova/templates/daemonset-compute.yaml | 8 +++-
2 files changed, 56 insertions(+), 3 deletions(-)
diff --git a/nova/templates/bin/_nova-compute.sh.tpl b/nova/templates/bin/_nova-compute.sh.tpl
index 702e3b92..116f41a6 100644
--- a/nova/templates/bin/_nova-compute.sh.tpl
+++ b/nova/templates/bin/_nova-compute.sh.tpl
@@ -16,8 +16,57 @@ limitations under the License.
set -ex
+# Check if environment variable exists
+if [ -z "$CLUSTER_HOST_IP" ]; then
+ echo "Error: CLUSTER_HOST_IP environment variable is not set."
+ exit 1
+fi
+
+# Set input and output files
+INPUT_FILE="/etc/nova/nova.conf"
+OUTPUT_FILE="/tmp/pod-shared/nova.conf"
+
+# Check if the output directory exists
+if [ ! -d "$(dirname "$OUTPUT_FILE")" ]; then
+ echo "Error: Output directory does not exist."
+ exit 1
+fi
+
+# Set fields to replace with cluster host ip
+declare -A CONFIG_CHANGES
+CONFIG_CHANGES["DEFAULT.my_ip"]="$CLUSTER_HOST_IP"
+CONFIG_CHANGES["vnc.server_listen"]="$CLUSTER_HOST_IP"
+CONFIG_CHANGES["vnc.server_proxyclient_address"]="$CLUSTER_HOST_IP"
+CONFIG_CHANGES["libvirt.live_migration_inbound_addr"]="$CLUSTER_HOST_IP"
+
+# Loop through the lines of the input file
+while IFS="=" read -r line; do
+ # Check if the line is a section
+ if [[ "$line" =~ ^\[.*\]$ ]]; then
+ section="${line//[\[\]]/}" # Get section name by stripping brackets
+ fi
+
+ # Loop through the dictionary of field.section and update the values
+ for field_section in "${!CONFIG_CHANGES[@]}"; do
+ section_name="${field_section%%.*}" # Extract section (before the dot)
+ field_name="${field_section#*.}" # Extract field (after the dot)
+ new_value="${CONFIG_CHANGES[$field_section]}"
+
+ # If we are in the correct section, update the field value
+ if [[ "$section" == "$section_name" && "$line" =~ ^$field_name\ = ]]; then
+ line="$field_name = $new_value"
+ fi
+ done
+
+ # Write the line (modified or unmodified) to the output file
+ if ! echo "$line" >> "$OUTPUT_FILE"; then
+ echo "Error: Failed to write to output file."
+ exit 1
+ fi
+done < "$INPUT_FILE"
+
exec nova-compute \
- --config-file /etc/nova/nova.conf \
+ --config-file /tmp/pod-shared/nova.conf \
{{- if .Values.console.address_search_enabled }}
--config-file /tmp/pod-shared/nova-console.conf \
{{- end }}
diff --git a/nova/templates/daemonset-compute.yaml b/nova/templates/daemonset-compute.yaml
index 1a117456..794674f3 100644
--- a/nova/templates/daemonset-compute.yaml
+++ b/nova/templates/daemonset-compute.yaml
@@ -18,7 +18,7 @@ exec:
- python
- /tmp/health-probe.py
- --config-file
- - /etc/nova/nova.conf
+ - /tmp/pod-shared/nova.conf
- --service-queue-name
- compute
- --liveness-probe
@@ -33,7 +33,7 @@ exec:
- python
- /tmp/health-probe.py
- --config-file
- - /etc/nova/nova.conf
+ - /tmp/pod-shared/nova.conf
- --service-queue-name
- compute
{{- if .Values.pod.use_fqdn.compute }}
@@ -278,6 +278,10 @@ spec:
value: "{{ .Values.pod.probes.rpc_timeout }}"
- name: RPC_PROBE_RETRIES
value: "{{ .Values.pod.probes.rpc_retries }}"
+ - name: CLUSTER_HOST_IP
+ valueFrom:
+ fieldRef:
+ fieldPath: status.hostIP
{{- if or .Values.manifests.certificates .Values.tls.identity }}
- name: REQUESTS_CA_BUNDLE
value: "/etc/ssl/certs/openstack-helm.crt"
--
2.34.1

@ -22,3 +22,4 @@
0022-Add-missing-initial-delay-in-readiness-probes.patch
0023-Add-pre-apply-cleanup-Job-to-STX-O-Helm-charts.patch
0024-Define-values-for-NetApp-volume-backend.patch
0025-Add-cluster-host-ip-env-var-to-nova.patch

@ -1,5 +1,5 @@
#
# Copyright (c) 2019-2024 Wind River Systems, Inc.
# Copyright (c) 2019-2025 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
@ -468,15 +468,6 @@ class NovaHelm(openstack.OpenstackBaseHelm):
else:
libvirt_config.update({'images_type': 'default'})
def _update_host_addresses(self, host, default_config, vnc_config, libvirt_config):
cluster_host_ip = self._get_cluster_host_ip(
host, self.addresses_by_hostid)
default_config.update({'my_ip': cluster_host_ip})
vnc_config.update({'server_listen': cluster_host_ip})
vnc_config.update({'server_proxyclient_address': cluster_host_ip})
libvirt_config.update({'live_migration_inbound_addr': cluster_host_ip})
def _get_ssh_subnet(self):
address_pool = self.dbapi.address_pool_get(self.cluster_host_network.pool_uuid)
return '%s/%s' % (str(address_pool.network), str(address_pool.prefix))
@ -672,13 +663,10 @@ class NovaHelm(openstack.OpenstackBaseHelm):
hostname = str(host.hostname)
default_config = {}
compute_config = {}
vnc_config = {}
libvirt_config = {}
pci_config = {}
self._update_host_cpu_maps(host, compute_config)
self._update_host_storage(host, default_config, libvirt_config)
self._update_host_addresses(host, default_config, vnc_config,
libvirt_config)
self._update_host_pci_whitelist(host, pci_config)
self._update_reserved_memory(host, default_config)
host_nova = {
@ -687,7 +675,6 @@ class NovaHelm(openstack.OpenstackBaseHelm):
'nova': {
'DEFAULT': default_config,
'compute': compute_config if compute_config else None,
'vnc': vnc_config,
'libvirt': libvirt_config,
'pci': pci_config if pci_config else None,
}

@ -1,5 +1,5 @@
#
# Copyright (c) 2020-2024 Wind River Systems, Inc.
# Copyright (c) 2020-2025 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
@ -44,9 +44,6 @@ class NovaGetOverrideTest(NovaHelmTestCase,
'enable_dad': self.oam_subnet.version == 6
})
def test_update_host_addresses(self):
self.nova._update_host_addresses(self.worker, {}, {}, {})
@mock.patch('k8sapp_openstack.utils.is_openstack_https_ready', return_value=False)
def test_nova_overrides(self, *_):
overrides = self.operator.get_helm_chart_overrides(

@ -1,5 +1,5 @@
#
# Copyright (c) 2023-2024 Wind River Systems, Inc.
# Copyright (c) 2023-2025 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
@ -186,6 +186,7 @@ conf:
vnc:
novncproxy_host: "::"
server_listen: "::"
server_proxyclient_address: "::"
spice:
html5proxy_host: "::"
server_listen: "::"
@ -199,6 +200,7 @@ conf:
rbd_user: cinder
# Allow up to 1 day for resize conf
remove_unused_resized_minimum_age_seconds: 86400
live_migration_inbound_addr: "::"
database:
idle_timeout: 60
max_overflow: 64