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

Reverse-spec · Services

octavia — Async processing

Processing outside the API — octavia — branch stable/2026.2

Branch stable/2026.2 @ 2900ed67cac2 — repository https://opendev.org/openstack/octavia — analysed on 2026-11-01

ProcessTriggerTypePurposeReadsWrites / emitsDefined at
octavia-driver-agentstatus.sockUnix stream socket, one fork per requesta provider reports statusesmessageload_balancer, listener, pool, member, health_monitor, l7policy, l7rule, quotas; VIP deallocationoctavia/api/drivers/driver_agent/driver_listener.py:49
octavia-driver-agentstats.socksamea provider reports listener statisticsmessagelistener_statistics via [controller_worker] statistics_driversoctavia/api/drivers/driver_agent/driver_listener.py:73
octavia-driver-agentget.socksamea provider reads an objectall resource tablesnothingoctavia/api/drivers/driver_agent/driver_listener.py:97
octavia-driver-agentprovider agentschild processes from entry points octavia.driver_agent.provider_agentsrun the provider's own loops (OVN provider: OVSDB events, maintenance)——octavia/cmd/driver_agent.py:54-57

Everything else found by the inventory (28 triggers) is the amphora driver: § 3.

1. Driver agent

1.1 Sockets

  • Framing: <decimal length>\n<JSON of that length>, both ways; one request per connection (octavia/api/drivers/driver_agent/driver_listener.py:33-46, octavia/api/drivers/driver_agent/driver_listener.py:63-68).
  • Server: ForkingMixIn + UnixStreamServer, a process per request (octavia/api/drivers/driver_agent/driver_listener.py:120-122).
  • Limits: max_children = *_max_processes (50), timeout = *_request_timeout (5 s) (octavia/api/drivers/driver_agent/driver_listener.py:139-140). The socket files are removed at start and at stop (octavia/api/drivers/driver_agent/driver_listener.py:125-131).
  • Client side (provider): octavia-lib DriverLibrary; default paths /var/run/octavia/{status,stats,get}.sock; send timeout 5 s, receive 30 s in the Go client (openkeel-ovn-octavia-provider:internal/driverlib/driverlib.go:123-124).
  • Receive failure: logged, connection dropped, no reply.

1.2 Status message

Trigger: update_loadbalancer_status of the driver library. Emitter: the provider. Purpose: move objects out of PENDING_*, publish operating statuses.

Order of processing is fixed: members, health monitors, pools, L7 rules, L7 policies, listeners, load balancers; unknown top-level keys are ignored (octavia/api/drivers/driver_agent/driver_updater.py:142-179). For each record (octavia/api/drivers/driver_agent/driver_updater.py:89-127):

  1. prov_status == DELETED:
    • load balancer: if vip.octavia_owned, deallocate_vip with the service credentials (octavia/api/drivers/driver_agent/driver_updater.py:48-57);
    • quota decrement in its own locking transaction, unless already DELETED or row missing (octavia/api/drivers/driver_agent/driver_updater.py:59-87);
    • non-LB: DELETE row and return; a load balancer row stays, status DELETED.
  2. Otherwise UPDATE … SET provisioning_status, operating_status for those present; a record with neither does nothing.
  3. Any exception → UpdateStatusError → reply with status_code: 500 and the identification; no rollback of earlier records.

Reply: {"status_code": 200} or the fault (values from octavia-lib DRVR_STATUS_CODE_OK/FAILED). Idempotency: repeating a message is harmless; a DELETED repeated on a LB finds the row already DELETED and skips the quota but calls deallocate_vip again. Concurrency: per-record transactions; two senders may interleave; last write wins. Cost: at least 1 transaction per record, 2-3 for a deletion. Vectors: _rewrite/cases-driver-seam_stable-2026.2.json.

1.3 Statistics message

Each listener record needs id, bytes_in, bytes_out, active_connections, total_connections, request_errors (octavia/api/drivers/driver_agent/driver_updater.py:204-217). stats_base.update_stats_via_driver(deltas=False) calls each driver of statistics_drivers (default stats_db) (octavia/statistics/stats_base.py:39-48, octavia/common/config.py:518): absolute values replace the row keyed on (listener, amphora); without amphora id the amphora_id column takes the listener id (octavia/db/repositories.py:1187-1209). The API read path knows this trick: active_connections of a row counts only if its amphora is ALLOCATED or amphora_id == listener_id (octavia/common/stats.py:42-53).

1.4 Get message

{"object": "loadbalancers"|"listeners"|"pools"|"members"|"healthmonitors"|"l7policies"|"l7rules", "id": "<uuid>"} → the provider object to_dict(recurse=True, render_unsets=True) (all keys present, unset as null), or {} when unknown, DELETED, or the object kind is unknown (octavia/api/drivers/driver_agent/driver_get.py:23-90). The OVN provider uses it for its members and pools.

2. API-side background

None: the API process has no periodic task and no consumer. Start-up: _init_drivers loads each enabled provider and removes those that fail (octavia/api/app.py:45-60).

3. Out of depth: the amphora driver and everything it brings

Not ported; listed so that nobody searches them in this spec.

PartWhat it isWhere
amphora provider driverturns driver calls into RPC casts to the workeroctavia/api/drivers/amphora_driver/v2/driver.py
controller workertaskflow flows building VMs, ports, certificates, haproxy configs; also sends the notifications octavia.* when [controller_worker] event_notificationsoctavia/controller/worker/v2/, octavia/controller/worker/v2/tasks/notification_tasks.py
amphora agent, haproxy-vrrp-check, amphora-health-checker, amphora-interface, prometheus-proxycode inside the VM imageoctavia/amphorae/, octavia/cmd/
health managerUDP heartbeats from amphorae, statuses, failoveroctavia/controller/healthmanager/
housekeepingspare/certificate rotation, **DB purge of DELETED load balancers and amphorae**octavia/controller/housekeeping/house_keeping.py:39, octavia/controller/housekeeping/house_keeping.py:66
certificates, compute, volume, image driversNova, Cinder, Glanceoctavia/certificates/, octavia/compute/, octavia/volume/, octavia/image/

The only item with a visible effect on the API contract is the purge: DELETED LB rows are invisible through the API, so without a purge they only use space. The Go port should add a small periodic delete (load_balancer_expiry_age, default 604800 s) **[inferred from octavia/controller/housekeeping/house_keeping.py:66]**.

Source: reverse-spec-octavia/05-async-processing_stable-2026.2.md. The _rewrite/ and _inventory/ files are not published on the site.