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

Reverse-spec · Services

nova — Interactions

Interactions — nova — branch stable/2026.2

Branch stable/2026.2 @ 8df1922926dd (34.0.0 + 7 commits) — repository https://opendev.org/openstack/nova — analysed on 2026-10-28

Related files: REST API · errors · scenarios · async processing. Client-side expectations of Glance and Placement are already specified in reverse-spec-glance/07-rewrite-pack_stable-2026.2.md and reverse-spec-placement/07-rewrite-pack_stable-2026.2.md (§ "What the clients expect").

0. Overview

SystemProtocolLibraryConfigurationUsed byUsage
RabbitMQ (per cell)AMQP 0-9-1oslo.messaging (rabbit driver)[DEFAULT]/transport_url, cell_mappings.transport_urlall servicesRPC between api, conductor, scheduler, compute; notifications
MariaDB/MySQL — API DBSQLoslo.db + SQLAlchemy 2[api_database]/connectionapi, conductor, schedulerflavors, mappings, build requests, request specs, quotas, aggregates, key pairs, server groups
MariaDB/MySQL — cell DBs (cell0 + N cells)SQLoslo.db + SQLAlchemy 2[database]/connection, cell_mappings.database_connectionapi (read/write through mappings), conductor, scheduler (read)instances, BDMs, migrations, compute nodes, services, actions, faults
PlacementHTTPS REST (microversioned)keystoneauth1 adapter[placement]api, conductor, scheduler, computeresource providers, inventories, traits, aggregates, allocation candidates, allocations
NeutronHTTPS RESTpython-neutronclient[neutron]api, computeports, networks, port bindings, security groups, floating IPs, QoS resource requests
CinderHTTPS REST (v3 microversioned)python-cinderclient[cinder]api, conductor, computevolumes, attachments (3.44), snapshots, reimage (3.68)
GlanceHTTPS REST (v2)python-glanceclient[glance]api, conductor, computeimage metadata, download, snapshot upload
KeystoneHTTPS REST (v3)keystonemiddleware, keystoneauth1, oslo.limit[keystone_authtoken], [keystone], [oslo_limit], [service_user]api (and all for service tokens)token validation, project existence, unified limits, service tokens
CyborgHTTPS REST (v2)openstacksdk / keystoneauth[cyborg]api, conductor, computedevice profiles, accelerator requests (ARQs)
ManilaHTTPS RESTopenstacksdk[manila]api, computeshare access rules for virtiofs shares (2.97+)
Memcached / Redis (oslo.cache)memcached / RESPoslo.cache (dogpile)[cache]api (metadata, AZ), computemetadata responses, availability-zone names per host
Hypervisorlocal (libvirt socket, vCenter API, Ironic REST, z/VM)virt drivers[DEFAULT]/compute_drivercomputeguest lifecycle — out of scope for OpenKeel (KubeVirt)

1. RabbitMQ (oslo.messaging RPC)

1.1 Topology

Nova uses one RPC transport per cell plus an optional API-level transport:

  • [DEFAULT]/transport_url of each service points at its own cell's broker; nova-api and nova-conductor (super-conductor) reach a cell's broker through cell_mappings.transport_url in the API database. nova.rpc.ClientRouter picks the transport from the request context (context.mq_connection, set by set_target_cell) and falls back to the default client (nova/rpc.py:423-444).
  • Exchange: [DEFAULT]/control_exchange (default nova). Topics and servers:
TopicServer (queue topic.server)ConsumersFanoutDefined at
conductorconductor hostConductorManager (v3.0) + ComputeTaskManager (namespace compute_task, v1.26)nonova/conductor/rpcapi.py:30, nova/conductor/manager.py:120, nova/conductor/manager.py:269
schedulerscheduler hostSchedulerManager (v4.5)yes (scheduler_fanout) for instance/aggregate trackingnova/scheduler/rpcapi.py:28, nova/scheduler/manager.py:65
computecompute host name (CONF.host)ComputeManager (v6.5) and _ComputeV5Proxy (v5.13, previous major)nonova/compute/rpcapi.py:34, nova/compute/manager.py:646, nova/compute/manager.py:12006
compute-altcompute host namesame endpoints, second RPC server used during graceful shutdownnonova/compute/rpcapi.py:42, nova/service.py:267-285
  • Graceful shutdown (new in 2026.2, compute RPC 6.5): every compute creates a second RPC server on compute-alt (nova/service.py:267-285). On shutdown it stops consuming compute but keeps compute-alt alive until its ongoing operations end. Calls that belong to an operation already in progress on that host — finish_resize, finish_revert_resize, finish_snapshot_based_resize_at_dest, finish_revert_snapshot_based_resize_at_source, check_instance_shared_storage, validate_console_port, live_migration, pre_live_migration, post_live_migration_at_destination — are sent to compute-alt (nova/compute/rpcapi.py:578-603), with a fallback to compute when the target is pinned below 6.5.

1.2 Versioning and rolling upgrades

  • Each client pins a version_cap. For compute it is [upgrade_levels]/compute (auto by default): the minimum nova-compute service version across all cells is read from the services tables and mapped to an RPC version through SERVICE_VERSION_HISTORY (nova/compute/rpcapi.py:496-560); release aliases go from bobcat = 6.2 to hibiscus = 6.5 (nova/compute/rpcapi.py:440-446). Conductor and scheduler use static aliases (nova/conductor/rpcapi.py:203-218).
  • Clients downgrade messages with can_send_version() checks, dropping or converting arguments for older servers (nova/conductor/rpcapi.py:331-386 for examples).
  • Objects travel as nova_object.* primitives (NovaObjectSerializer); a receiver that is too old asks the conductor to backport them (object_backport_versions).
  • call timeouts: [DEFAULT]/rpc_response_timeout (60 s). Long calls (select_destinations, migrate_server, attach_volume, cache_images, check_can_live_migrate_*, prep_snapshot_based_resize_at_*…) use [DEFAULT]/long_rpc_timeout (1800 s) with call_monitor_timeout = rpc_response_timeout, which makes the server send heartbeats so that a dead server is detected early (nova/compute/rpcapi.py:562-575).

1.3 RPC methods

90 client methods (nova/compute/rpcapi.py, nova/conductor/rpcapi.py, nova/scheduler/rpcapi.py), each matched to its server handler. "Mode" is call (request/response) or cast (fire-and-forget); call/cast means the client chooses at run time (e.g. do_cast arguments). Versions are the ones the client may send depending on the pin. Compute messages are always sent to server=<instance.host> or an explicit host (nova/compute/rpcapi.py:61-77 _compute_host). Machine-readable: _rewrite/rpc-contract_stable-2026.2.json.

Client methodModeRPC methodTopicVersion(s) sentprepare()Server handler
nova/compute/rpcapi.py:605 add_fixed_ip_to_instancecastadd_fixed_ip_to_instancecompute—server=_compute_host(None, instance)nova/compute/manager.py:6923
nova/compute/rpcapi.py:612 attach_interfacecallattach_interfacecompute—server=_compute_host(None, instance)nova/compute/manager.py:8566
nova/compute/rpcapi.py:623 attach_volumecastattach_volumecompute—server=_compute_host(None, instance)nova/compute/manager.py:7845
nova/compute/rpcapi.py:629 check_can_live_migrate_destinationcallcheck_can_live_migrate_destinationcompute5.0call_monitor_timeout=CONF.rpc_response_timeout
server=destination
timeout=CONF.long_rpc_timeout
nova/compute/manager.py:8810
nova/compute/rpcapi.py:656 check_can_live_migrate_sourcecallcheck_can_live_migrate_sourcecompute—server=sourcenova/compute/manager.py:9036
nova/compute/rpcapi.py:669 check_instance_shared_storagecallcheck_instance_shared_storagecompute——nova/compute/manager.py:8785
nova/compute/rpcapi.py:698 confirm_snapshot_based_resize_at_sourcecallconfirm_snapshot_based_resize_at_sourcecompute—call_monitor_timeout=CONF.rpc_response_timeout
server=migration.source_compute
timeout=CONF.long_rpc_timeout
nova/compute/manager.py:5152
nova/compute/rpcapi.py:733 detach_interfacecastdetach_interfacecompute—server=_compute_host(None, instance)nova/compute/manager.py:8707
nova/compute/rpcapi.py:740 detach_volumecastdetach_volumecompute—server=_compute_host(None, instance)nova/compute/manager.py:8001
nova/compute/rpcapi.py:749 finish_resizecastfinish_resizecompute5.0—nova/compute/manager.py:6646
nova/compute/rpcapi.py:774 finish_revert_resizecastfinish_revert_resizecompute5.0—nova/compute/manager.py:5661
nova/compute/rpcapi.py:799 finish_snapshot_based_resize_at_destcallfinish_snapshot_based_resize_at_destcompute——nova/compute/manager.py:6730
nova/compute/rpcapi.py:847 finish_revert_snapshot_based_resize_at_sourcecallfinish_revert_snapshot_based_resize_at_sourcecompute——nova/compute/manager.py:5452
nova/compute/rpcapi.py:889 get_console_outputcallget_console_outputcompute—server=_compute_host(None, instance)nova/compute/manager.py:7550
nova/compute/rpcapi.py:896 get_diagnosticscallget_diagnosticscompute—server=_compute_host(None, instance)nova/compute/manager.py:7098
nova/compute/rpcapi.py:902 get_instance_diagnosticscallget_instance_diagnosticscompute—server=_compute_host(None, instance)nova/compute/manager.py:7114
nova/compute/rpcapi.py:909 get_vnc_consolecallget_vnc_consolecompute—server=_compute_host(None, instance)nova/compute/manager.py:7582
nova/compute/rpcapi.py:916 get_spice_consolecallget_spice_consolecompute—server=_compute_host(None, instance)nova/compute/manager.py:7628
nova/compute/rpcapi.py:923 get_mks_consolecallget_mks_consolecompute—server=_compute_host(None, instance)nova/compute/manager.py:7695
nova/compute/rpcapi.py:930 get_serial_consolecallget_serial_consolecompute—server=_compute_host(None, instance)nova/compute/manager.py:7741
nova/compute/rpcapi.py:937 validate_console_portcallvalidate_console_portcompute——nova/compute/manager.py:7780
nova/compute/rpcapi.py:951 host_maintenance_modecallhost_maintenance_modecompute—server=hostnova/compute/manager.py:7015
nova/compute/rpcapi.py:966 host_power_actioncallhost_power_actioncompute—server=hostnova/compute/manager.py:7010
nova/compute/rpcapi.py:972 inject_network_infocastinject_network_infocompute—server=_compute_host(None, instance)nova/compute/manager.py:7540
nova/compute/rpcapi.py:978 live_migrationcastlive_migrationcompute——nova/compute/manager.py:9469
nova/compute/rpcapi.py:993 live_migration_force_completecastlive_migration_force_completecompute—server=_compute_host(migration.source_compute, instance)nova/compute/manager.py:9507
nova/compute/rpcapi.py:1001 live_migration_abortcastlive_migration_abortcompute—server=_compute_host(None, instance)nova/compute/manager.py:9539
nova/compute/rpcapi.py:1008 pause_instancecastpause_instancecompute—server=_compute_host(None, instance)nova/compute/manager.py:6969
nova/compute/rpcapi.py:1014 post_live_migration_at_destinationcallpost_live_migration_at_destinationcompute——nova/compute/manager.py:9950
nova/compute/rpcapi.py:1031 pre_live_migrationcallpre_live_migrationcompute6.0, 5.0—nova/compute/manager.py:9066
nova/compute/rpcapi.py:1054 prep_resizecastprep_resizecompute6.0, 5.1, 5.0server=hostnova/compute/manager.py:5955
nova/compute/rpcapi.py:1090 prep_snapshot_based_resize_at_destcallprep_snapshot_based_resize_at_destcompute—call_monitor_timeout=CONF.rpc_response_timeout
server=destination
timeout=CONF.long_rpc_timeout
nova/compute/manager.py:6124
nova/compute/rpcapi.py:1145 prep_snapshot_based_resize_at_sourcecallprep_snapshot_based_resize_at_sourcecompute——nova/compute/manager.py:6197
nova/compute/rpcapi.py:1190 reboot_instancecastreboot_instancecompute—server=_compute_host(None, instance)nova/compute/manager.py:4407
nova/compute/rpcapi.py:1200 rebuild_instancecastrebuild_instancecompute6.2, 6.1, 5.0server=_compute_host(host, instance)nova/compute/manager.py:3894
nova/compute/rpcapi.py:1252 remove_fixed_ip_from_instancecastremove_fixed_ip_from_instancecompute—server=_compute_host(None, instance)nova/compute/manager.py:6945
nova/compute/rpcapi.py:1259 remove_volume_connectioncallremove_volume_connectioncompute6.3—nova/compute/manager.py:8301
nova/compute/rpcapi.py:1281 rescue_instancecastrescue_instancecompute—server=_compute_host(None, instance)nova/compute/manager.py:4864
nova/compute/rpcapi.py:1293 resize_instancecastresize_instancecompute6.0, 5.0—nova/compute/manager.py:6331
nova/compute/rpcapi.py:1323 resume_instancecastresume_instancecompute—server=_compute_host(None, instance)nova/compute/manager.py:7157
nova/compute/rpcapi.py:1329 revert_resizecastrevert_resizecompute5.0server=_compute_host(host, instance)nova/compute/manager.py:5610
nova/compute/rpcapi.py:1353 revert_snapshot_based_resize_at_destcallrevert_snapshot_based_resize_at_destcompute—call_monitor_timeout=CONF.rpc_response_timeout
server=migration.dest_compute
timeout=CONF.long_rpc_timeout
nova/compute/manager.py:5339
nova/compute/rpcapi.py:1389 rollback_live_migration_at_destinationcastrollback_live_migration_at_destinationcompute——nova/compute/manager.py:10290
nova/compute/rpcapi.py:1412 drop_move_claim_at_destinationcalldrop_move_claim_at_destinationcompute——nova/compute/manager.py:10276
nova/compute/rpcapi.py:1431 set_admin_passwordcallset_admin_passwordcompute—server=_compute_host(None, instance)nova/compute/manager.py:4771
nova/compute/rpcapi.py:1438 set_host_enabledcallset_host_enabledcompute—call_monitor_timeout=CONF.rpc_response_timeout
server=host
timeout=CONF.long_rpc_timeout
nova/compute/manager.py:7067
nova/compute/rpcapi.py:1446 swap_volumecastswap_volumecompute—server=_compute_host(None, instance)nova/compute/manager.py:8192
nova/compute/rpcapi.py:1458 get_host_uptimecallget_host_uptimecompute—server=hostnova/compute/manager.py:7091
nova/compute/rpcapi.py:1464 reserve_block_device_namecallreserve_block_device_namecompute—call_monitor_timeout=CONF.rpc_response_timeout
server=_compute_host(None, instance)
timeout=CONF.long_rpc_timeout
nova/compute/manager.py:7798
nova/compute/rpcapi.py:1479 backup_instancecastbackup_instancecompute—server=_compute_host(None, instance)nova/compute/manager.py:4553
nova/compute/rpcapi.py:1490 snapshot_instancecastsnapshot_instancecompute—server=_compute_host(None, instance)nova/compute/manager.py:4569
nova/compute/rpcapi.py:1498 start_instancecaststart_instancecompute—server=_compute_host(None, instance)nova/compute/manager.py:3581
nova/compute/rpcapi.py:1513 suspend_instancecastsuspend_instancecompute—server=_compute_host(None, instance)nova/compute/manager.py:7131
nova/compute/rpcapi.py:1519 terminate_instancecastterminate_instancecompute—server=_compute_host(None, instance)nova/compute/manager.py:3446
nova/compute/rpcapi.py:1526 unpause_instancecastunpause_instancecompute—server=_compute_host(None, instance)nova/compute/manager.py:6991
nova/compute/rpcapi.py:1532 unrescue_instancecastunrescue_instancecompute—server=_compute_host(None, instance)nova/compute/manager.py:4929
nova/compute/rpcapi.py:1538 soft_delete_instancecastsoft_delete_instancecompute—server=_compute_host(None, instance)nova/compute/manager.py:3636
nova/compute/rpcapi.py:1545 restore_instancecastrestore_instancecompute—server=_compute_host(None, instance)nova/compute/manager.py:3658
nova/compute/rpcapi.py:1551 shelve_instancecastshelve_instancecompute5.0server=_compute_host(None, instance)nova/compute/manager.py:7204
nova/compute/rpcapi.py:1573 shelve_offload_instancecastshelve_offload_instancecompute5.0server=_compute_host(None, instance)nova/compute/manager.py:7289
nova/compute/rpcapi.py:1589 unshelve_instancecastunshelve_instancecompute5.2, 5.0server=hostnova/compute/manager.py:7384
nova/compute/rpcapi.py:1613 volume_snapshot_createcastvolume_snapshot_createcompute—server=_compute_host(None, instance)nova/compute/manager.py:4682
nova/compute/rpcapi.py:1621 volume_snapshot_deletecastvolume_snapshot_deletecompute—server=_compute_host(None, instance)nova/compute/manager.py:4694
nova/compute/rpcapi.py:1630 allow_sharecastallow_sharecompute6.4server=_compute_host(None, instance)nova/compute/manager.py:4708
nova/compute/rpcapi.py:1646 deny_sharecastdeny_sharecompute6.4server=_compute_host(None, instance)nova/compute/manager.py:4715
nova/compute/rpcapi.py:1662 external_instance_eventcastexternal_instance_eventcompute——nova/compute/manager.py:11657
nova/compute/rpcapi.py:1676 build_and_run_instancecastbuild_and_run_instancecompute5.0server=hostnova/compute/manager.py:2396
nova/compute/rpcapi.py:1706 quiesce_instancecallquiesce_instancecompute—server=_compute_host(None, instance)nova/compute/manager.py:11861
nova/compute/rpcapi.py:1712 unquiesce_instancecastunquiesce_instancecompute—server=_compute_host(None, instance)nova/compute/manager.py:11885
nova/compute/rpcapi.py:1719 trigger_crash_dumpcasttrigger_crash_dumpcompute—server=_compute_host(None, instance)nova/compute/manager.py:3613
nova/compute/rpcapi.py:1726 cache_imagescallcache_imagescompute—call_monitor_timeout=CONF.rpc_response_timeout
server=host
timeout=CONF.long_rpc_timeout
nova/compute/manager.py:11722
nova/conductor/rpcapi.py:302 live_migrate_instancecastlive_migrate_instanceconductor (namespace compute_task)1.15—nova/conductor/manager.py:494
nova/conductor/rpcapi.py:317 migrate_servercall/castmigrate_serverconductor (namespace compute_task)1.20, 1.13, 1.11, 1.10, 1.6, 1.4call_monitor_timeout=CONF.rpc_response_timeout
timeout=CONF.long_rpc_timeout
nova/conductor/manager.py:339
nova/conductor/rpcapi.py:355 build_instancescastbuild_instancesconductor (namespace compute_task)1.19, 1.18, 1.10, 1.9, 1.8, 1.5—nova/conductor/manager.py:671
nova/conductor/rpcapi.py:395 schedule_and_build_instancescastschedule_and_build_instancesconductor (namespace compute_task)1.17, 1.16—nova/conductor/manager.py:1675
nova/conductor/rpcapi.py:418 unshelve_instancecastunshelve_instanceconductor (namespace compute_task)1.14, 1.3—nova/conductor/manager.py:1033
nova/conductor/rpcapi.py:429 rebuild_instancecastrebuild_instanceconductor (namespace compute_task)1.25, 1.24, 1.12, 1.8—nova/conductor/manager.py:1233
nova/conductor/rpcapi.py:471 cache_imagescastcache_imagesconductor (namespace compute_task)1.21—nova/conductor/manager.py:2086
nova/conductor/rpcapi.py:480 confirm_snapshot_based_resizecall/castconfirm_snapshot_based_resizeconductor (namespace compute_task)1.22—nova/conductor/manager.py:2217
nova/conductor/rpcapi.py:491 revert_snapshot_based_resizecastrevert_snapshot_based_resizeconductor (namespace compute_task)1.23—nova/conductor/manager.py:2236
nova/conductor/rpcapi.py:499 attach_volumecall/castattach_volumeconductor (namespace compute_task)1.26call_monitor_timeout=CONF.rpc_response_timeout
timeout=CONF.long_rpc_timeout
nova/conductor/manager.py:2267
nova/conductor/rpcapi.py:237 object_class_action_versionscallobject_class_action_versionsconductor——nova/conductor/manager.py:147
nova/conductor/rpcapi.py:245 object_actioncallobject_actionconductor——nova/conductor/manager.py:172
nova/conductor/rpcapi.py:250 object_backport_versionscallobject_backport_versionsconductor——nova/conductor/manager.py:192
nova/scheduler/rpcapi.py:132 select_destinationscallselect_destinationsscheduler4.5, 4.4, 4.3, 4.0call_monitor_timeout=CONF.rpc_response_timeout
timeout=CONF.long_rpc_timeout
nova/scheduler/manager.py:188
nova/scheduler/rpcapi.py:162 update_aggregatescastupdate_aggregatesscheduler—fanout=Truenova/scheduler/manager.py:800
nova/scheduler/rpcapi.py:167 delete_aggregatecastdelete_aggregatescheduler—fanout=Truenova/scheduler/manager.py:810
nova/scheduler/rpcapi.py:172 update_instance_infocastupdate_instance_infoscheduler—fanout=Truenova/scheduler/manager.py:819
nova/scheduler/rpcapi.py:177 delete_instance_infocastdelete_instance_infoscheduler—fanout=Truenova/scheduler/manager.py:826
nova/scheduler/rpcapi.py:182 sync_instance_infocastsync_instance_infoscheduler—fanout=Truenova/scheduler/manager.py:833

1.4 Notifications

  • Driver and topics come from [oslo_messaging_notifications]; the format is chosen by [notifications]/notification_format, whose default on this branch is **unversioned** (nova/conf/notifications.py:59-60): only legacy compute.instance.* notifications are sent unless it is set to versioned or both. Versioned notifications go to the topics in [notifications]/versioned_notifications_topics (default versioned_notifications, nova/conf/notifications.py:86-87).
  • [notifications]/notify_on_state_change (None by default; vm_state or vm_and_task_state, nova/conf/notifications.py:30-40) adds compute.instance.update / instance.update notifications on state transitions.
  • Versioned payloads are nova.notifications.objects.* objects; 141 samples in doc/notification_samples/ (101 instance-*, 15 aggregate-*, 6 keypair-*, 3 flavor-*, 3 server_group-*, 3 service-*, 3 compute_task-*, 2 scheduler-*…). Event types follow <object>.<action>[.<phase>] with phase start/end/error, publisher nova-compute:<host>, nova-api:<host>, etc.
  • Sample envelope (versioned, AMQP body after oslo.messaging unwrapping):
{"priority": "INFO", "event_type": "instance.pause.end",
 "publisher_id": "nova-compute:compute-1", "timestamp": "2026-10-28 10:00:00.000000",
 "message_id": "…",
 "payload": {"nova_object.name": "InstanceActionPayload", "nova_object.namespace": "nova",
             "nova_object.version": "1.9",
             "nova_object.data": {"uuid": "…", "state": "paused", "power_state": "paused",
                                  "task_state": null, "host": "compute-1", "flavor": {"…": "…"},
                                  "fault": null, "action_initiator_user": "…"}}}

1.5 Sample RPC frame

nova-api → conductor, cast schedule_and_build_instances (AMQP body on exchange nova, routing key conductor):

{"oslo.version": "2.0",
 "oslo.message": "{\"method\": \"schedule_and_build_instances\", \"namespace\": \"compute_task\", \"version\": \"1.17\", \"args\": {\"build_requests\": [{\"nova_object.name\": \"BuildRequest\", \"nova_object.version\": \"1.3\", \"nova_object.data\": {…}}], \"request_specs\": [{\"nova_object.name\": \"RequestSpec\", …}], \"image\": {…}, \"admin_password\": \"…\", \"injected_files\": [], \"requested_networks\": {…}, \"block_device_mapping\": [{…}], \"tags\": []}, \"_unique_id\": \"…\", \"_context_request_id\": \"req-…\", \"_context_global_request_id\": null, \"_context_project_id\": \"…\", \"_context_user_id\": \"…\", \"_context_roles\": [\"member\", \"reader\"], \"_context_service_catalog\": [ … ], \"_context_auth_token\": \"gAAAA…\", \"_context_is_admin\": false, \"_context_read_deleted\": \"no\", \"_context_timestamp\": \"…\"}"}

The serialised context carries the service catalog (nova/context.py:195-211) and, through the oslo.context base class, the user token [inferred: auth_token is part of oslo_context.RequestContext.to_dict], so computes can call Neutron/Cinder/Glance on behalf of the user; admin_password travels in clear in the message body.

2. Databases

2.1 Layout (cells v2)

flowchart LR
  api[nova-api] -->|SQL| apidb[(nova_api)]
  api -->|SQL via instance_mappings| cell0[(nova_cell0)]
  api -->|SQL via instance_mappings| cell1[(nova cell1)]
  sc[super-conductor] --> apidb
  sc --> cell0
  sc --> cell1
  sched[nova-scheduler] -->|read| apidb
  sched -->|read compute_nodes| cell1
  cc[cell conductor] --> cell1
  cpu[nova-compute] -.->|RPC object_action| cc
  • API database (nova/db/api/models.py, 20 tables): cell_mappings (name, UUID, transport_url, database_connection, disabled, nova/db/api/models.py:135-147), host_mappings, instance_mappings (instance → cell, queued_for_delete, project/user), build_requests (serialised instance before scheduling), request_specs (serialised RequestSpec reused on every move), flavors, flavor_extra_specs, flavor_projects, aggregates, aggregate_hosts, aggregate_metadata, instance_groups, instance_group_policy, instance_group_member, key_pairs, quotas, project_user_quotas, quota_classes, and the legacy quota_usages / reservations (no longer written: usage is counted). DDL: _rewrite/schema-api-mysql_stable-2026.2.sql.
  • Cell databases (nova/db/main/models.py, 30 tables + shadow_* copies created by the migrations): instances, instance_extra (NUMA, PCI requests, flavor copy, vCPU model, keypairs, trusted certs, resources), instance_system_metadata, instance_metadata, instance_info_caches (network info JSON), instance_faults, instance_actions, instance_actions_events, block_device_mapping, migrations, compute_nodes, services, pci_devices, tags, virtual_interfaces, console_auth_tokens, share_mapping, task_log, volume_usage_cache, instance_id_mappings, s3_images, plus legacy security_groups/security_group_rules/security_group_instance_association, certificates, quotas… DDL: _rewrite/schema-mysql_stable-2026.2.sql.
  • cell0 has the same schema as a cell; it only holds instances that failed scheduling.
  • Migrations: Alembic, nova/db/api/migrations/versions/ (3 revisions) and nova/db/main/migrations/versions/ (10 revisions, the latest adding instances.compute_id, console_auth_tokens.tls_port, share mappings and BDM encryption fields).
  • Soft delete: most cell tables have deleted (= id when deleted) and deleted_at; rows are moved to shadow_* tables by nova-manage db archive_deleted_rows (nova/cmd/manage.py:301) and removed by nova-manage db purge (nova/cmd/manage.py:526).

2.2 Notable transactions and locking

WhereWhatSource
Boot, APIrequest_specs + build_requests + instance_mappings inserted in one API-DB transactionnova/compute/api.py:1256
Boot, conductorinstance created in the cell, then instance_mappings.cell_id set, then build request deleted (three separate steps; the build request deletion is the commit point that detects a concurrent delete)nova/conductor/manager.py:1758, nova/conductor/manager.py:1944, nova/conductor/manager.py:2027
Any state changeInstance.save(expected_task_state=…, expected_vm_state=…): UPDATE instances … WHERE uuid = ? AND task_state IN (…); a mismatch raises UnexpectedTaskStateError / UnexpectedDeletingTaskStateError (compare-and-swap)nova/db/main/api.py:2242 instance_update_and_get_original
Quotasno reservations: usage counted from cell DBs (and Placement when [quota]/count_usage_from_placement) at check time, optional re-check after creation ([quota]/recheck_quota)nova/quota.py
Retries@oslo_db_api.wrap_db_retry(max_retries=5, retry_on_deadlock=True) on hot writes (instance update, BDM update, migrations)nova/db/main/api.py:563, nova/db/main/api.py:869, nova/db/main/api.py:1243

2.3 Cross-cell reads

List and lookup operations scatter-gather over all cells in parallel with a per-cell timeout (nova/context.py:456 scatter_gather_cells, CELL_TIMEOUT = 60 at nova/context.py:51); a cell that does not answer is either skipped or returned as a partial record (01 § 1.6).

3. Outbound REST calls

All clients authenticate with keystoneauth sessions built from the service's config group; when [service_user]/send_service_user_token = true the user token is sent with an extra X-Service-Token so that expired user tokens are still accepted during long operations (nova/service_auth.py:73-91). X-OpenStack-Request-ID carries the global request id.

3.1 Placement (nova/scheduler/client/report.py)

CallMicroversionWhenDefined at
GET /allocation_candidates?…from the request (up to 1.36 for same_subtree)scheduling (select_destinations)nova/scheduler/client/report.py:1719
PUT /allocations/{consumer}1.28 (consumer generation) or the candidates' versionscheduler claim; move/replace allocationsnova/scheduler/client/report.py:2033, nova/scheduler/client/report.py:2255
POST /allocations1.28atomic move of allocations between instance and migration consumersnova/scheduler/client/report.py:2104
GET /allocations/{consumer}1.28compute build, move operationsnova/scheduler/client/report.py:1612
DELETE /allocations/{consumer}—delete, failed build/reschedulenova/scheduler/client/report.py:2201
GET/POST /resource_providers, GET /resource_providers?in_tree=1.14 / 1.20compute node registration and provider-tree refreshnova/scheduler/client/report.py:549, nova/scheduler/client/report.py:594
PUT /resource_providers/{uuid}/inventories1.26resource trackernova/scheduler/client/report.py:989
PUT /resource_providers/{uuid}/traits, GET /traits, PUT /traits/{name}1.6capabilities and custom traitsnova/scheduler/client/report.py:1145, nova/scheduler/client/report.py:1074-1081
PUT /resource_providers/{uuid}/aggregates1.19host aggregate membership mirroringnova/scheduler/client/report.py:1223
PUT /resource_classes/{name}1.7custom resource classesnova/scheduler/client/report.py:1290
POST /reshaper1.30driver reshapes its provider tree (e.g. VGPU, PCPU)nova/scheduler/client/report.py:1332
DELETE /resource_providers/{uuid}—service delete, orphan nodenova/scheduler/client/report.py:736
GET /usages?project_id=…1.9quota counting from Placementnova/scheduler/client/report.py:2610

Generation conflicts (409 placement.concurrent_update) are retried by the retries decorator (nova/scheduler/client/report.py:149); with safe_connect (nova/scheduler/client/report.py:115-140) an unreachable or misconfigured Placement is logged ("Placement API service is not responding.") and the call returns None, so the resource tracker keeps running; a failed claim makes the scheduler try the next host.

3.2 Neutron (nova/network/neutron.py, python-neutronclient v2.0)

OperationCallsWhen
Validate requested networks/portslist_networks, show_network, show_port, list_ports, list_extensions, show_quotaAPI, POST /servers and interface attach
Allocate/bind portscreate_port (when a network is requested), update_port with binding:host_id, device_id, device_owner=compute:<az>, binding:profile (PCI, allocation)compute, build/attach (nova/network/neutron.py:211-253 client setup)
Multiple port bindings (live migration)create_port_binding, show_port_binding, delete_port_binding, activatecompute, live migration
Deallocateupdate_port (unbind) or delete_port for Nova-created portscompute, delete/detach
Network info cachelist_ports(device_id=…), list_subnets, list_floatingipscompute (on events), API (ips)
Legacy proxiessecurity groups (create_security_group, rules…), floating IPsAPI ≤ 2.35

Neutron calls back with POST /os-server-external-events (01 § 3.7). Admin calls use [neutron] credentials; user calls use the user token (nova/network/neutron.py:230 get_client).

3.3 Cinder (nova/volume/cinder.py, python-cinderclient v3)

Minimum version 3.0 (nova/volume/cinder.py:237); the new attachment flow uses 3.44 (attachment_create/update/complete/delete, nova/volume/cinder.py:781-940), multiattach needs 3.48 [inferred], reimage of boot volumes 3.68 (nova/volume/cinder.py:953). Legacy calls (reserve_volume, initialize_connection, attach, detach, begin_detaching, roll_detaching) remain for old BDMs. Cinder calls back with volume-extended/volume-reimaged external events and with /os-assisted-volume-snapshots.

3.4 Glance (nova/image/glance.py, python-glanceclient v2)

show/detail (image metadata, compute and API), download (compute, streamed to the image cache; direct RBD download optional), create/update/upload (snapshot, shelve, backup), delete (backup rotation, failed snapshot), image_import_copy / copy_image_to_store (multi-store), signature verification with Barbican (cursive) when img_signature_verify [inferred].

3.5 Keystone

  • keystonemiddleware.auth_token validates each incoming token (GET /v3/auth/tokens, cached in memcached).
  • PUT /os-quota-sets/{project} checks that the project exists: GET /v3/projects/{id} (nova/api/openstack/identity.py:26-39).
  • Unified limits ([quota]/driver = nova.quota.UnifiedLimitsDriver): registered limits and project limits read through oslo.limit (nova/limit/local.py:18-19, nova/limit/placement.py).

3.6 Cyborg and Manila

  • Cyborg (nova/accelerator/cyborg.py:113-114): GET /v2/device_profiles?name= at boot (API), POST /v2/accelerator_requests and PATCH to bind ARQs (conductor), GET/DELETE ARQs (compute). Cyborg notifies accelerator-request-bound.
  • Manila (nova/share/manila.py): GET /shares/{id}, access rules list, allow/deny access for the compute host (virtiofs shares, 2.97+).

4. Cache (oslo.cache)

KeyValueTTLWriter / readerDefined at
metadata-<fixed_ip> / metadata-<instance_uuid>InstanceMetadata object[api]/metadata_cache_expiration (15 s, nova/conf/api.py:158)metadata APInova/api/metadata/handler.py:63-93
azcache-<host>availability-zone name of a host3600 s (AZ_CACHE_SECONDS, nova/availability_zones.py:26)API, AZ lookups; reset on aggregate changesnova/availability_zones.py:36, nova/availability_zones.py:51-52
EC2 id mappingsmemoised id translations_CACHE_TIMEmetadata API (EC2 ids)nova/objects/ec2.py:43-56

When [cache]/enabled is false, an in-process dictionary is used (nova/cache_utils.py:47-58), so each API worker has its own cache.

5. Other

  • Privileged operations: oslo.privsep daemons (nova/privsep/) for file, network and libvirt helpers on the compute host; rootwrap is no longer used for new code.
  • Console proxies: nova-novncproxy, nova-spicehtml5proxy, nova-serialproxy validate tokens against the cell DB console_auth_tokens (nova/console/websocketproxy.py) and proxy WebSocket ↔ VNC/SPICE/serial on the compute.
  • Hypervisor: libvirt over its UNIX socket (qemu:///system), VMware vCenter SOAP, Ironic REST, z/VM REST — replaced by the KubeVirt API in OpenKeel.

Source: reverse-spec-nova/03-interactions_stable-2026.2.md. The _rewrite/ and _inventory/ files are not published on the site.