Processing triggered outside the API — placement — branch stable/2026.2
Branch
stable/2026.2@f4a89d3803cb— repository https://opendev.org/openstack/placement — analysed on 2026-10-28
Finding: there is none while the service runs
The automated inventory found no trigger: 0 RPC server, 0 periodic task, 0 consumer, 0 event (_inventory/inventory_stable-2026.2.md). Reading the code confirms it:
| Family | Present? | Check |
|---|---|---|
| Bus consumers (RabbitMQ, Kafka…) | no | no import of oslo_messaging or of an AMQP client outside tests |
| SQL polling (periodic tasks) | no | no periodic_task, LoopingCall, thread or timer in placement/ outside tests |
| Cache polling | no | the caches (ResourceClassCache, ConsumerTypeCache) are per request (placement/context.py:26-27) and reload on demand (placement/attribute_cache.py), never on a timer |
| Events (OVSDB, callbacks, watchers) | no | no event registry |
Functional consequence: Placement never changes the state it stores on its own. Its data only changes in four cases:
- a REST request from a client;
- the startup of an API process (sync of the standard traits and classes);
- an administration command;
- a
db syncat startup, if[placement_database]/sync_on_startup = True.
Everything that looks like periodic processing is done by the clients. For example, the resource tracker of nova-compute sends the host's inventory on each cycle of its update_available_resource task, every 60 s by default [inferred: Nova behaviour, outside this repository].
So there is no "automatic cleanup":
- an orphan allocation stays until someone deletes it;
- a provider of a host that disappeared also stays, with its inventory, and remains a candidate as long as it has capacity.
For orphan allocations, the Nova-side tool is nova-manage placement audit --delete [inferred: a Nova tool].
Processing at API process startup
| Trigger | Purpose | Data read and written | Concurrency | Error | Defined at |
|---|---|---|---|---|---|
loadapp, when the WSGI module is loaded (once per process or worker) | apply the schema if sync_on_startup = True (False by default) | Alembic upgrade head | several workers starting together run several upgrades [inferred] | the application does not load | placement/deploy.py:122-127 |
| same | copy the standard traits from os-traits into the database | SELECT name FROM traits, then INSERT of the missing ones | process-local lock, plus DBDuplicateEntry ignored between processes | logged at DEBUG | placement/deploy.py:129; placement/objects/trait.py:125-147,265-299 |
| same | copy the standard resource classes from os-resource-classes | SELECT … FROM resource_classes, then INSERT of the missing ones | same | same | placement/deploy.py:130; placement/objects/resource_class.py:209-255 |
| same | load the policies | policy.yaml or defaults | — | — | placement/deploy.py:140-150; placement/policy.py |
These copies only add: a trait or class removed from os-traits or os-resource-classes is not deleted from the database. An upgrade of those libraries is only taken into account when the API processes restart. On this branch the minimum os-traits version is 3.9.0 (requirements.txt:23, see change history, change 11).
On this branch, startup no longer silences oslo.policy's "failed scope check" warnings when enforce_scope is disabled: that filter was removed with the option itself (see 06, change 5).
Administration processing (CLI, run by the operator)
| Command | Purpose | Effect on the database | Defined at |
|---|---|---|---|
placement-manage db sync | create or upgrade the schema | Alembic DDL | placement/cmd/manage.py:57-60 |
placement-manage db version / db stamp | show or force the revision | alembic_version table | placement/cmd/manage.py:62-68 |
placement-manage db online_data_migrations [--max-count N] | data migrations in batches of 50 until done. Exit code 0 when everything is done, 1 when some remain, 2 on error, 127 on an invalid argument | set_root_provider_ids fills root_provider_id for old providers (placement/objects/resource_provider.py:494-524); create_incomplete_consumers creates the missing consumers rows for old allocations, with the placeholder project and user (placement/objects/consumer.py:26-64) | placement/cmd/manage.py:31-34,70-163 |
placement-status upgrade check | pre-upgrade checks: missing root_provider_id, incomplete consumers, obsolete policy.json file | read only | placement/cmd/status.py:33-109 |
Source: reverse-spec-placement/05-async-processing_stable-2026.2.md. The _rewrite/ and _inventory/ files are not published on the site.