Skip to content

[cifmw_setup] Retry nova discover_hosts to handle registration race - #4156

Open
sbauza wants to merge 1 commit into
openstack-k8s-operators:mainfrom
sbauza:fix/discover-hosts-retry
Open

[cifmw_setup] Retry nova discover_hosts to handle registration race#4156
sbauza wants to merge 1 commit into
openstack-k8s-operators:mainfrom
sbauza:fix/discover-hosts-retry

Conversation

@sbauza

@sbauza sbauza commented Sep 2, 2026

Copy link
Copy Markdown

Problem

nova-manage cell_v2 discover_hosts is a point-in-time snapshot: it only
maps compute hosts that have already registered with the message queue.
When the command runs before all nova-compute services finish starting,
some hosts are silently missed. The subsequent Tempest run then fails
because the scheduler sees zero hypervisors.

This race condition has been consistently hitting the uni04delta job
since around Aug 27, causing widespread Tempest failures
(NoValidHost / 0 hypervisors).

Fix

Replace the single fire-and-forget discover_hosts command with a retry
loop that:

  1. Runs discover_hosts --verbose.
  2. Runs list_hosts and counts mapped hosts (excluding the header).
  3. Retries up to 30 times with a 10-second delay (~5 min budget) until
    at least one host appears.

The retry values are hardcoded rather than exposed as role variables
because this is a Nova-specific workaround in a generic role; making
them configurable would add unnecessary API surface. 30 × 10s gives
a 5-minute window, which is generous for compute services to register
while keeping CI wall-clock impact minimal on healthy runs (the loop
exits on the first success).

Resolves: OSPCIX-1493

Assisted-By: Cursor Claude 4.6 Opus

Made with Cursor

@openshift-ci

openshift-ci Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign eshulman2 for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Retry Nova host discovery until a compute host is mapped

🐞 Bug fix 🕐 Less than 10 minutes

Grey Divider

AI Description

• Retries Nova host discovery while compute services finish registering.
• Verifies at least one host mapping before post-deployment hooks continue.
• Bounds retries to five minutes and exits immediately on healthy deployments.
Diagram

sequenceDiagram
    participant T as Setup task
    participant O as OpenShift CLI
    participant N as Nova management
    participant M as Host mappings
    loop Up to 30 attempts
        T->>O: Run discover_hosts
        O->>N: Execute in conductor
        N->>M: Map registered computes
        T->>O: Run list_hosts
        O->>N: Request mapped hosts
        N->>M: Read host mappings
        M-->>N: Return host table
        N-->>O: Return command output
        O-->>T: Return mapped count
        alt Host found
            T->>T: Continue deployment
        else No hosts
            T->>T: Wait 10 seconds
        end
    end
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Wait for expected compute count
  • ➕ Ensures every expected compute is registered before continuing
  • ➕ Avoids succeeding when only one of several hosts is mapped
  • ➖ Requires topology-specific expected counts in a generic setup role
  • ➖ Adds configuration and coordination across deployment scenarios
2. Enable periodic Nova discovery
  • ➕ Handles late compute registration continuously
  • ➕ Removes orchestration-time discovery polling
  • ➖ Requires broader Nova operator or service configuration changes
  • ➖ May delay host availability beyond the deployment workflow

Recommendation: Use the PR's bounded retry for this targeted CI race because it is localized, exits immediately on healthy deployments, and requires no new role API. If reliable expected-compute metadata becomes available, validating the full expected count would provide stronger multi-compute coverage.

Files changed (1) +14 / -5

Bug fix (1) +14 / -5
deploy_architecture.ymlRetry Nova discovery until a host mapping appears +14/-5

Retry Nova discovery until a host mapping appears

• Replaces the one-shot Nova discovery command with a retryable shell task. Each attempt discovers hosts, lists mappings, and uses the pipeline exit status to retry every 10 seconds up to 30 times when no host is present.

roles/cifmw_setup/tasks/deploy_architecture.yml

@qodo-code-review

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (2) 📜 Skill insights (0)

Grey Divider


Action required

1. _nova_discover_hosts lacks namespace 📘 Rule violation ⚙ Maintainability
Description
The new registered variable does not match the required cifmw_setup role namespace. This violates
the mandated cifmw_<role_name>_<variable_name> structure.
Code

roles/cifmw_setup/tasks/deploy_architecture.yml[314]

+  register: _nova_discover_hosts
Evidence
Compliance rule 1 requires every role variable to use the cifmw_<role_name>_<variable_name>
structure, while the added registration uses _nova_discover_hosts.

AGENTS.md: Ansible Role Variables Must Follow the Repository Naming Pattern
roles/cifmw_setup/tasks/deploy_architecture.yml[314-314]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The registered variable `_nova_discover_hosts` does not follow the required `cifmw_setup` role-variable naming pattern.

## Issue Context
Rename it consistently in both `register` and the retry condition, using a name such as `cifmw_setup_nova_discover_hosts`.

## Fix Focus Areas
- roles/cifmw_setup/tasks/deploy_architecture.yml[314-327]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Discovery task combines operations 📘 Rule violation ◔ Observability
Description
One shell task performs host discovery, host listing, output normalization, and host counting
without structured rescue diagnostics. A failure in any stage is reported only as a failure of the
combined retry task, obscuring which operation failed.
Code

roles/cifmw_setup/tasks/deploy_architecture.yml[R320-324]

+        nova-manage cell_v2 discover_hosts --verbose
+      oc rsh -n {{ cifmw_openstack_namespace }} \
+        nova-cell0-conductor-0 \
+        nova-manage cell_v2 list_hosts | tr -d '\r' | \
+        grep '^|' | grep -vc 'Cell Name'
Evidence
Rules 4 and 7 require complex task sequences to be divided into debuggable tasks and to provide
structured failure diagnostics. The added shell body combines two remote Nova commands and a
multi-stage parsing pipeline under one retry result, with no rescue path reporting the individual
results.

AGENTS.md: Complex Ansible Task Sequences Must Provide Structured Failure Diagnostics
AGENTS.md: Ansible Tasks Must Be Small and Debuggable
roles/cifmw_setup/tasks/deploy_architecture.yml[315-327]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The retry task combines multiple separable operations and lacks a structured rescue path that reports discovery and host-listing results before explicitly failing.

## Issue Context
Preserve the retry behavior while separating discovery from verification. Wrap the workflow in appropriate `block`/`rescue` handling, register relevant command results, report them in the rescue path, and terminate with `ansible.builtin.fail` after retries are exhausted.

## Fix Focus Areas
- roles/cifmw_setup/tasks/deploy_architecture.yml[308-327]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Partial host discovery exits early 🐞 Bug ≡ Correctness
Description
The retry succeeds as soon as list_hosts contains one host, so if one compute registers before the
others, discovery stops and later computes remain unmapped. Supported multi-compute scenarios can
therefore proceed with missing hypervisors despite this retry reporting success.
Code

roles/cifmw_setup/tasks/deploy_architecture.yml[R323-324]

+        nova-manage cell_v2 list_hosts | tr -d '\r' | \
+        grep '^|' | grep -vc 'Cell Name'
Evidence
The changed pipeline returns success for any non-header host row, while va-multi provisions at
least two computes in each compute group. The repository's dedicated Nova wait hook avoids this race
by comparing list_hosts with the complete expected compute count and continuing discovery until
they match.

roles/cifmw_setup/tasks/deploy_architecture.yml[321-327]
scenarios/reproducers/va-multi.yml[100-124]
hooks/playbooks/nova_wait_for_compute_service.yml[82-87]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The discovery retry stops after finding any mapped host. In multi-compute deployments, one early registration can end the loop while slower compute services remain undiscovered.

## Issue Context
The repository supports deployments containing multiple computes, and the existing Nova wait hook compares discovered hosts against an expected compute count before stopping.

## Fix Focus Areas
- roles/cifmw_setup/tasks/deploy_architecture.yml[321-327]
- hooks/playbooks/nova_wait_for_compute_service.yml[82-87]
- scenarios/reproducers/va-multi.yml[100-124]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Context sources
⚠️ Tickets: not configured — ticket URL found in PR but could not be fetched — check ticket provider credentials
Review mode: ⚖️ Balanced

Grey Divider

Tip of the day
💡 Did you know, you can turn on the rule miner and Qodo learns your standards from review history

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

-n {{ cifmw_openstack_namespace }}
nova-cell0-conductor-0
nova-manage cell_v2 discover_hosts --verbose
register: _nova_discover_hosts

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

1. _nova_discover_hosts lacks namespace 📘 Rule violation ⚙ Maintainability

The new registered variable does not match the required cifmw_setup role namespace. This violates
the mandated cifmw_<role_name>_<variable_name> structure.
Agent Prompt
## Issue description
The registered variable `_nova_discover_hosts` does not follow the required `cifmw_setup` role-variable naming pattern.

## Issue Context
Rename it consistently in both `register` and the retry condition, using a name such as `cifmw_setup_nova_discover_hosts`.

## Fix Focus Areas
- roles/cifmw_setup/tasks/deploy_architecture.yml[314-327]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +320 to +324
nova-manage cell_v2 discover_hosts --verbose
oc rsh -n {{ cifmw_openstack_namespace }} \
nova-cell0-conductor-0 \
nova-manage cell_v2 list_hosts | tr -d '\r' | \
grep '^|' | grep -vc 'Cell Name'

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

2. Discovery task combines operations 📘 Rule violation ◔ Observability

One shell task performs host discovery, host listing, output normalization, and host counting
without structured rescue diagnostics. A failure in any stage is reported only as a failure of the
combined retry task, obscuring which operation failed.
Agent Prompt
## Issue description
The retry task combines multiple separable operations and lacks a structured rescue path that reports discovery and host-listing results before explicitly failing.

## Issue Context
Preserve the retry behavior while separating discovery from verification. Wrap the workflow in appropriate `block`/`rescue` handling, register relevant command results, report them in the rescue path, and terminate with `ansible.builtin.fail` after retries are exhausted.

## Fix Focus Areas
- roles/cifmw_setup/tasks/deploy_architecture.yml[308-327]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +323 to +324
nova-manage cell_v2 list_hosts | tr -d '\r' | \
grep '^|' | grep -vc 'Cell Name'

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

3. Partial host discovery exits early 🐞 Bug ≡ Correctness

The retry succeeds as soon as list_hosts contains one host, so if one compute registers before the
others, discovery stops and later computes remain unmapped. Supported multi-compute scenarios can
therefore proceed with missing hypervisors despite this retry reporting success.
Agent Prompt
## Issue description
The discovery retry stops after finding any mapped host. In multi-compute deployments, one early registration can end the loop while slower compute services remain undiscovered.

## Issue Context
The repository supports deployments containing multiple computes, and the existing Nova wait hook compares discovered hosts against an expected compute count before stopping.

## Fix Focus Areas
- roles/cifmw_setup/tasks/deploy_architecture.yml[321-327]
- hooks/playbooks/nova_wait_for_compute_service.yml[82-87]
- scenarios/reproducers/va-multi.yml[100-124]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so something like:

    - name: Count expected compute hosts from the deployed nodesets
      ansible.builtin.command: >-
        oc get openstackdataplanenodeset
        -n {{ cifmw_openstack_namespace }}
        -o jsonpath={.items[*].spec.nodes.*.hostName}
      register: _nova_expected_hosts
      changed_when: false

So in the modified task:

      until: >-
        _nova_discover_hosts.rc == 0 and
        _nova_discover_hosts.stdout | int >= _expected_compute_count
      vars:
        _expected_compute_count: "{{ _nova_expected_hosts.stdout.split() | length }}"

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@qodo-code-review

Copy link
Copy Markdown

Qodo reviews are paused for this user.

Troubleshooting steps vary by plan Learn more →

On a Teams plan?
Reviews resume once this user has a paid seat and their Git account is linked in Qodo.
Link Git account →

Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center?
These require an Enterprise plan - Contact us
Contact us →

@mrkisaolamb mrkisaolamb left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@centosinfra-prod-github-app

Copy link
Copy Markdown

Build failed (check pipeline). Post recheck (without leading slash)
to rerun all jobs. Make sure the failure cause has been resolved before
you rerun jobs.

https://gateway-cloud-softwarefactory.apps.ocp.cloud.ci.centos.org/zuul/t/rdoproject.org/buildset/32563b1c30ee4b049830326055e42391

✔️ openstack-k8s-operators-content-provider SUCCESS in 3h 53m 11s
✔️ podified-multinode-edpm-deployment-crc SUCCESS in 1h 30m 09s
✔️ cifmw-crc-podified-edpm-baremetal SUCCESS in 1h 55m 27s
✔️ cifmw-crc-podified-edpm-baremetal-minor-update SUCCESS in 2h 36m 36s
✔️ cifmw-pod-zuul-files SUCCESS in 4m 33s
✔️ openstack-k8s-operators-content-provider-bootc SUCCESS in 2h 57m 26s
✔️ cifmw-crc-podified-edpm-baremetal-bootc SUCCESS in 1h 47m 15s
adoption-standalone-to-crc-ceph-provider POST_FAILURE in 3h 25m 20s
✔️ noop SUCCESS in 0s
✔️ cifmw-pod-ansible-test SUCCESS in 10m 05s
✔️ cifmw-pod-pre-commit SUCCESS in 9m 48s
✔️ cifmw-molecule-cifmw_setup SUCCESS in 2m 16s

@sbauza
sbauza force-pushed the fix/discover-hosts-retry branch from fe0de4e to 2fad5c0 Compare September 3, 2026 16:51
@sbauza

sbauza commented Sep 3, 2026

Copy link
Copy Markdown
Author

Shouldn't we reuse this similar logic instead?

https://github.com/openstack-k8s-operators/ci-framework/blob/main/hooks/playbooks/nova_wait_for_compute_service.yml

Good point, thanks for the pointer. The v2 adopts the same two-phase pattern from that hook:

Wait for all expected nova-compute services to appear in the API (openstack compute service list)
Then run discover_hosts + verify list_hosts
The expected compute count is derived dynamically from the deployed openstackdataplanenodeset CRs rather than passed as a hardcoded extra_vars.

The reason I kept it inline in deploy_architecture.yml instead of wiring the existing hook is that the hook is opt-in — only scenarios that explicitly add it to their post_deploy or post_admin_setup hooks get the protection. The inline approach makes every deployment go through the wait+discover sequence, which is what we want since discover_hosts is already called unconditionally here.

The first test run on testproject confirmed the gap between EDPM Ready and compute services registering can be ~15 min, so the original 5 min budget was way too short. The service-wait step (90 × 10s) handles that, and the discover_hosts retry (10 × 10s) only needs to cover the brief mapping delay once services are up.

@centosinfra-prod-github-app

Copy link
Copy Markdown

Build failed (check pipeline). Post recheck (without leading slash)
to rerun all jobs. Make sure the failure cause has been resolved before
you rerun jobs.

https://gateway-cloud-softwarefactory.apps.ocp.cloud.ci.centos.org/zuul/t/rdoproject.org/buildset/22f0eb2add674a8d91028de6f8ca972a

✔️ openstack-k8s-operators-content-provider SUCCESS in 3h 44m 06s
✔️ podified-multinode-edpm-deployment-crc SUCCESS in 1h 37m 27s
✔️ cifmw-crc-podified-edpm-baremetal SUCCESS in 2h 10m 04s
✔️ cifmw-crc-podified-edpm-baremetal-minor-update SUCCESS in 2h 14m 23s
✔️ cifmw-pod-zuul-files SUCCESS in 6m 15s
✔️ openstack-k8s-operators-content-provider-bootc SUCCESS in 2h 10m 30s
cifmw-crc-podified-edpm-baremetal-bootc FAILURE in 35m 39s
✔️ adoption-standalone-to-crc-ceph-provider SUCCESS in 3h 26m 40s
✔️ noop SUCCESS in 0s
✔️ cifmw-pod-ansible-test SUCCESS in 10m 15s
cifmw-pod-pre-commit FAILURE in 9m 06s
✔️ cifmw-molecule-cifmw_setup SUCCESS in 2m 13s

@sbauza
sbauza force-pushed the fix/discover-hosts-retry branch from 2fad5c0 to 2ed3419 Compare September 4, 2026 06:14
nova-manage cell_v2 discover_hosts is a point-in-time snapshot: it only
maps compute hosts that have already registered with the message queue.
When the command runs before all nova-compute services finish starting,
some hosts are silently missed. The subsequent Tempest run then fails
because the scheduler sees zero hypervisors.

The gap between openstackdataplanedeployment Ready and nova-compute
services actually registering can exceed 15 minutes, so a simple
short retry on discover_hosts alone is insufficient.

Adopt the same two-phase approach used by the
nova_wait_for_compute_service hook but inline in deploy_architecture,
so all deployments benefit without opting into a hook:

1. Wait for at least one nova-compute service to appear in the
   Nova API via the openstackclient pod (90 retries x 10 s = 15 min
   budget).
2. Run discover_hosts and verify that list_hosts reports at least as
   many mapped hosts as registered compute services (10 retries x
   10 s, enough once services are registered).

The service count from phase 1 is reused as the expected host count
in phase 2, avoiding any dependency on nodeset CRs which include
non-compute nodes (e.g. ceph-nodes).

All retry values are hardcoded: they are a Nova-specific workaround
in a generic role, and exposing them as variables would add
unnecessary API surface.

Resolves: OSPCIX-1493
Co-authored-by: Cursor <cursoragent@cursor.com>
@sbauza
sbauza force-pushed the fix/discover-hosts-retry branch from 2ed3419 to 38bc0ac Compare September 4, 2026 08:34
@centosinfra-prod-github-app

Copy link
Copy Markdown

Build failed (check pipeline). Post recheck (without leading slash)
to rerun all jobs. Make sure the failure cause has been resolved before
you rerun jobs.

https://gateway-cloud-softwarefactory.apps.ocp.cloud.ci.centos.org/zuul/t/rdoproject.org/buildset/722f032ccb1244ad84c279c7c3625a2f

✔️ openstack-k8s-operators-content-provider SUCCESS in 4h 25m 23s
✔️ podified-multinode-edpm-deployment-crc SUCCESS in 1h 21m 38s
✔️ cifmw-crc-podified-edpm-baremetal SUCCESS in 1h 44m 15s
✔️ cifmw-crc-podified-edpm-baremetal-minor-update SUCCESS in 2h 19m 33s
✔️ cifmw-pod-zuul-files SUCCESS in 5m 15s
✔️ openstack-k8s-operators-content-provider-bootc SUCCESS in 1h 33m 04s
cifmw-crc-podified-edpm-baremetal-bootc NODE_FAILURE Node(set) request 099-0000192213 failed in 0s
✔️ adoption-standalone-to-crc-ceph-provider SUCCESS in 3h 06m 22s
✔️ noop SUCCESS in 0s
✔️ cifmw-pod-ansible-test SUCCESS in 9m 06s
cifmw-pod-pre-commit FAILURE in 9m 30s
✔️ cifmw-molecule-cifmw_setup SUCCESS in 2m 10s

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants