Reverse-specification of swift — branch stable/2026.2
Branch
stable/2026.2@a1bdaeba21bd— repository https://opendev.org/openstack/swift — analysed on 2026-10-29
- Repository: https://opendev.org/openstack/swift (local clone
OpenKeel/swift) — specified branch:stable/2026.2@a1bdaeba21bdcf64e11c7f93a025f24b33f4890c(tag 2.38.3) — analysed on: 2026-10-29 - Scope: the whole service: proxy and its middleware pipeline (tempauth/keystoneauth, s3api, slo/dlo, tempurl, formpost, staticweb, versioning, symlink, encryption, bulk, quotas…), account/container/object servers, all daemons, rings and ring format, on-disk layout, SQLite listings, REPLICATE/SSYNC, erasure coding; rewrite pack (step 8) for OpenKeel Swift in Go, with the clients python-swiftclient, OSC, Glance swift store, Cinder backup, S3 clients and Skyline. Change history (step 7) not run.
Overview
Swift is OpenStack's object store. Clients store objects in containers inside accounts (one per Keystone project, AUTH_<project_id>) through a stateless proxy. The proxy finds the storage nodes of every account, container and object with rings (a consistent-hashing table computed offline and copied to every node), writes N replicas or k+m erasure-coded fragments to object servers, and keeps listings and statistics in per-container and per-account SQLite databases held by container and account servers, themselves replicated through the rings. There is no central database, no message bus and no coordination service: writes succeed on a quorum, and a set of daemons on every storage node (replicators, reconstructor, auditors, updaters, sharder, expirer, reconciler, reaper) repairs, audits and propagates state, which makes the system eventually consistent. Features beyond plain storage (large objects, temporary URLs, versioning, S3 API, encryption…) are WSGI middlewares in the proxy.
Architecture
flowchart LR cl[Clients: swiftclient, OSC, Glance, Cinder backup, Skyline, S3 clients] -->|HTTPS /v1, S3| px[swift-proxy-server + middlewares] px -->|token validation, /v3/s3tokens| ks[Keystone] px -->|cache: info, shard ranges, tokens| mc[(memcached)] px -->|root secret| kms[Barbican / KMIP] px -->|HTTP /dev/part/a| as[account servers] px -->|HTTP /dev/part/a/c| cs[container servers] px -->|HTTP /dev/part/a/c/o, EC MIME| os[object servers] os -->|listing updates, async pendings| cs cs -->|stats| as os --- disk1[(devices: objects/, xattrs, hashes.pkl)] cs --- disk2[(containers/*.db SQLite)] as --- disk3[(accounts/*.db SQLite)] d[replicators, reconstructor, auditors, updaters, sharder, expirer, reconciler, reaper] -->|REPLICATE, SSYNC, rsync| os d -->|REPLICATE JSON RPC, rsync| cs d --> as ring[[rings *.ring.gz + swift.conf]] -.-> px ring -.-> os ring -.-> cs ring -.-> as
Processes
| Process | Entry point | Role | Listens to / consumes |
|---|---|---|---|
| swift-proxy-server | swift.proxy.server:app_factory (setup.cfg:99) | client API, middlewares, quorum logic | HTTP (8080) |
| swift-object-server | swift.obj.server:app_factory (setup.cfg:100) | object files, REPLICATE, SSYNC | HTTP (6200) |
| swift-container-server | swift.container.server:app_factory (setup.cfg:102) | container DBs, listings, REPLICATE | HTTP (6201) |
| swift-account-server | swift.account.server:app_factory (setup.cfg:103) | account DBs, REPLICATE | HTTP (6202) |
| object replicator / reconstructor / auditor / updater / expirer, container replicator / updater / auditor / sharder / reconciler / sync, account replicator / auditor / reaper | setup.cfg:56–setup.cfg:96 | background repair and propagation | timers (05) |
| rsyncd | external | file transfer for replicators | rsync (873) |
| swift-ring-builder and CLI tools | setup.cfg:94 | build rings, inspect data | CLI |
External dependencies
| System | Protocol | Library | Configuration | Usage |
|---|---|---|---|---|
| Devices | local filesystem with user xattrs (XFS) | xattr, os | devices, mount_check | object files, SQLite DBs |
| Peers | HTTP, rsync | bufferedhttp, subprocess | rings, rsync_module | internal protocol |
| memcached | text protocol | swift/common/memcached.py | memcache_servers | proxy caches |
| Keystone | REST | keystonemiddleware, s3token | [filter:authtoken], [filter:s3token] | identity |
| Barbican / KMIP | REST / KMIP | castellan, PyKMIP | keymaster.conf | encryption root secret |
| liberasurecode | C library | PyECLib | [storage-policy:N] ec_type | erasure coding |
| statsd, syslog | UDP | — | log_statsd_* | metrics, logs |
Details: 03-interactions_stable-2026.2.md.
Files
| File | Content |
|---|---|
| 01-rest-api_stable-2026.2.md | conventions, account/container/object API, each middleware's API, internal server API summary, object lifecycle |
| 02-errors_stable-2026.2.md | error bodies, quorum logic, client and backend statuses, exception catalogue, S3 errors, background errors |
| 03-interactions_stable-2026.2.md | ring placement and file format, internal HTTP, REPLICATE, SSYNC, rsync, on-disk layout, xattr pickles, hashes.pkl, SQLite schemas and .pending, memcached, external services |
| 04-scenarios_stable-2026.2.md | 6 sequence diagrams: container creation, EC PUT, degraded GET and repair, Glance DLO, S3 with Keystone, expiry |
| 05-async-processing_stable-2026.2.md | every daemon: trigger, queue, flow, concurrency, errors; container DB lifecycle; Kubernetes notes |
| 07-rewrite-pack_stable-2026.2.md | rewrite pack: formal algorithms, safe pickle reading, mixed Go/Python cluster contract, client expectations, conformance strategy, checklist |
_rewrite/ | routes, OpenAPI, SQLite DDL, config, pipeline, /info, ring/disk/pickle/timestamp/replication vectors with sample rings, stdlib reference implementation (153/153), 75 930 recorded exchanges |
_inventory/inventory_stable-2026.2.{md,json} | automated reconnaissance (196 exception classes, 50 HTTP conversions) |
_verification_stable-2026.2.md | each file:line reference with the function it lands in |
Key figures
- 177 Python modules; 41 console scripts; 31 paste filters; 5 apps.
- 79 routes (proxy 25 operations, s3api 17, storage servers 37).
- 1009 configuration options in 105 sections of 15 sample files.
- Functional run: 1080 tests (225 skipped); 15 981 client exchanges (15 069 Swift, 912 S3) and 59 949 internal exchanges.
Points of attention
- Pickles on disk and on the wire (xattr metadata,
hashes.pkl,.pending, async pendings, REPLICATE responses): any non-Python node needs a restricted pickle codec; ring.builderfiles are loaded with an unrestrictedpickle.load(swift/common/ring/builder.py:1794) — never feed untrusted builder files to the tool. - No authentication between nodes: the storage network must be isolated.
- Handoff order, suffix hashes and the
chexorDB hash are compared across nodes: a rewrite that differs in any of them causes endless replication. - Ring format v2 is only readable by Swift ≥ 2.36.0.
- 5xx never wins a quorum: 507s turn into 503 for clients.
- Expired objects disappear from reads before the expirer deletes them; listings lag behind.
- Recorder artefacts: buffering bodies broke 15 tests that pass without it (07 § 8).
Blind spots / [inferred]
- EC encode/decode and the reconstructor's rebuild were not executed (no liberasurecode on the analysis host); fragment format from liberasurecode headers.
- Daemons were analysed from code only (probe tests need a multi-node cluster).
- keystoneauth, s3token and kms_keymaster were read, not run.
xprofile,list_endpoints,cname_lookup, dark-data watchers,swift-object-relinkerdescribed briefly.- The change history of the branch (step 7) was not produced.
Source: reverse-spec-swift/00-summary_stable-2026.2.md. The _rewrite/ and _inventory/ files are not published on the site.