OpenKeel: the sovereign French Cloud solution of the inherent group, with a European reach Discover inherent

Reverse-spec · Services

ovn-octavia-provider — Summary

Reverse-specification of ovn-octavia-provider — branch stable/2026.2

Branch stable/2026.2 @ c56940998594 (11.0.0-2-gc569409) — repository https://opendev.org/openstack/ovn-octavia-provider — analysed on 2026-10-28

  • Scope: the whole project (about 7,400 lines of Python outside tests): the Octavia provider driver, the request queue and helper, the provider agent (OVSDB events, maintenance tasks), the OVSDB layer, the Neutron/Octavia clients and the sync tools; plus a rewrite pack. No change history (step 7) was requested.
  • References are file:line relative to the repository root. octavia: is Octavia stable/2026.2 @ 2900ed67cac2, octavia-lib: is octavia-lib stable/2026.2 @ a46b0ff4fa95, neutron: is Neutron stable/2026.2 @ eef1a0f7ee36. [inferred] marks a statement not followed to the end in the code.

Files of this specification

FileContent
01-driver-api_stable-2026.2.mdthe provider-driver methods called by Octavia (instead of REST endpoints), the OVN NB row layout, lifecycles
02-errors_stable-2026.2.mdexception → HTTP translation by Octavia, synchronous refusals, asynchronous ERROR statuses, retries, key logs
03-interactions_stable-2026.2.mdOVSDB connections, tables and transactions; driver-agent sockets (status, get); Neutron and Octavia REST calls
04-scenarios_stable-2026.2.md5 scenarios: LB creation, health monitor and failing member, VIP floating IP, router interface, cascade delete
05-async-processing_stable-2026.2.mdthe request queue, the three OVSDB events, the three maintenance tasks, the sync tool
07-rewrite-pack_stable-2026.2.mdrewrite pack: OVN NB contract, vips algorithm with 57 replayed vectors, status derivation, client expectations, checklist
_verification_stable-2026.2.mdevery reference with the function it points into

Overview

ovn-octavia-provider lets Octavia create load balancers without amphora VMs: each Octavia load balancer becomes one or more rows of the OVN Northbound Load_Balancer table, which ovn-northd and ovn-controller turn into distributed DNAT flows on every chassis. Only L4 is supported (TCP, UDP, SCTP), with SOURCE_IP_PORT or SOURCE_IP hashing, TCP/UDP-CONNECT health checks and SOURCE_IP session persistence.

The code runs inside two Octavia processes:

  • in octavia-api, the ovn provider driver validates each API call synchronously, creates the VIP port in Neutron, and queues the work for a helper thread that writes the OVN NB database and reports statuses to Octavia;
  • in octavia-driver-agent, the ovn provider agent watches OVN (router interfaces, floating IPs on VIP ports, health-check results in the Southbound Service_Monitor table) and runs repair tasks.

The provider has no database of its own: its state is stored in Load_Balancer.external_ids. It reads Octavia objects and reports statuses through the driver-agent Unix sockets, and calls Neutron for ports, subnets and floating IPs.

Architecture

flowchart LR
  user[User / CLI] -->|HTTPS REST| api[octavia-api]
  subgraph api_p[octavia-api process]
    api --> drv[ovn provider driver] --> hq[request queue + helper thread]
  end
  subgraph agent_p[octavia-driver-agent process]
    sock[status.sock / get.sock]
    pa[ovn provider agent: events + maintenance + helper]
  end
  hq -->|OVSDB transact| nb[(OVN Northbound)]
  pa -->|OVSDB transact / monitor + lock| nb
  pa -->|OVSDB monitor + lock| sb[(OVN Southbound)]
  hq -->|JSON over Unix socket| sock
  pa -->|JSON over Unix socket| sock
  sock -->|SQL| odb[(Octavia DB)]
  drv -->|REST ports, subnets| neutron[Neutron]
  hq -->|REST ports, subnets, floating IPs| neutron
  pa -->|REST ports| neutron
  nb --> northd[ovn-northd] --> sb --> ctl[ovn-controller on each chassis]
  neutron -->|OVSDB| nb

Processes

ProcessEntry pointRoleListens to / consumes
octavia-api (plugin)octavia.api.drivers = ovn → ovn_octavia_provider/driver.py:40 (setup.cfg:32-33)validate calls, create VIP ports, queue OVN work, report statusesin-process queue (ovn_octavia_provider/helper.py:408)
octavia-driver-agent (plugin)octavia.driver_agent.provider_agents = ovn → ovn_octavia_provider/agent.py:31 (setup.cfg:38-39)OVSDB events, maintenance, queueNB Logical_Router_Port, Logical_Switch_Port; SB Service_Monitor; timers
octavia-ovn-db-sync-utilovn_octavia_provider/cmd/octavia_ovn_db_sync_util.py:37 (setup.cfg:35-36)repair OVN from the Octavia DB—
neutron-ovn-db-sync-util plugin octavia_ovn_syncovn_octavia_provider/ovn/db_sync.py:30 (setup.cfg:44-45)same, from Neutron's sync tool—

External dependencies

SystemProtocolLibraryConfigurationUsage
OVN NorthboundOVSDB JSON-RPC (TCP/SSL/Unix)ovsdbapp, ovs[ovn] ovn_nb_*state store and data plane
OVN SouthboundOVSDB JSON-RPCovsdbapp[ovn] ovn_sb_*health-check results
Octavia driver agentJSON over Unix socketsoctavia-lib DriverLibraryoctavia-lib defaults /var/run/octavia/*.sockstatus updates, object reads
NeutronRESTopenstacksdk, keystoneauth1[neutron], [service_auth]VIP and HM ports, subnets, floating IPs
Octavia APIRESTopenstacksdk[service_auth]list LBs (sync only)

Key figures

  • 19 provider-driver methods implemented (15 Octavia calls, plus create-VIP-port, batch update, failover refusal and sync), L7/flavor/AZ left unimplemented (501).
  • 20 request types handled by the helper thread (ovn_octavia_provider/helper.py:70-92).
  • 3 OVSDB events, 3 periodic maintenance tasks (600 s, self-stopping), 1 on-demand sync.
  • 3 exception classes defined (2 never raised); about 20 distinct synchronous refusal messages.
  • 9 NB tables replicated, 4 written (Load_Balancer, Load_Balancer_Health_Check, Logical_Switch/Logical_Router load_balancer columns, 2 NAT columns); 1 SB table monitored.
  • 13 Neutron REST operations, 2 driver-agent socket operations, 1 Octavia REST operation.
  • Rewrite pack: 57 vips vectors, 57/57 replayed.

Points of attention

  1. One driver instance per API call: Octavia instantiates the driver for every call, so each call opens an NB connection and starts a helper thread (octavia:octavia/api/drivers/driver_factory.py:43, ovn_octavia_provider/helper.py:55-68). Requests of different calls run concurrently and unordered on the same rows, with no optimistic locking (03 § 1.3).
  2. "Unsupported" is HTTP 501, not 400 (02 § 1).
  3. Unsupported session-persistence types give a 500: the error message formatting reads session.type on a dict (ovn_octavia_provider/driver.py:79-80).
  4. **pool_update silently ignores algorithm changes** (ovn_octavia_provider/driver.py:282-295), and selection_fields/affinity_timeout are shared by every pool of the same protocol (ovn_octavia_provider/helper.py:2364-2366). The admin guide still says only SOURCE_IP_PORT is supported (doc/source/admin/driver.rst:44).
  5. **Stuck PENDING_* statuses**: a handler that raises outside its own try sends no status (ovn_octavia_provider/helper.py:434-437), and a failing status socket blocks the queue for up to ~15 minutes before giving up (ovn_octavia_provider/helper.py:448-451).
  6. Members without a subnet get the VIP subnet, which is not stored in Octavia; such a member cannot be deleted if its address does not fit the VIP subnet any more (ovn_octavia_provider/driver.py:440-460).
  7. A disabled health monitor still probes (only the reported status changes, ovn_octavia_provider/helper.py:3488-3490).
  8. The OVSDB event lock only serialises event handling across agents; maintenance tasks run in every agent (ovn_octavia_provider/maintenance.py:72).
  9. Process-wide SSL settings for NB and SB (ovn_octavia_provider/ovsdb/ovsdb_monitor.py:89-118).
  10. **lb_create failure after the row was committed** reports ERROR but leaves the Load_Balancer row (ovn_octavia_provider/helper.py:1732-1760).

Blind spots / [inferred]

  • The Octavia side (API locking, PENDING_* transitions, driver-agent processing) was read only at the points cited; its full behaviour is outside this spec.
  • The exact OVSDB wire encoding (mutate versus update) is chosen by the ovs IDL and is shown reconstructed (03 § 1.4).
  • ovn-northd behaviour (how vips, selection_fields, ip_port_mappings and health checks become flows and Service_Monitor rows) is not part of this repository.
  • The functional tests (ovn_octavia_provider/tests/functional/) need a running OVN and were not run; no dynamic capture was made.
  • openstacksdk find_port request sequence is inferred from the library's general behaviour.
  • ovn_octavia_provider/hacking/ (flake8 checks) is development tooling and not described.

Source: reverse-spec-ovn-octavia-provider/00-summary_stable-2026.2.md. The _rewrite/ and _inventory/ files are not published on the site.