chore: record pre-existing uncommitted repository state
Snapshot of the in-flight state that already existed, identically, in both this worktree and the main checkout before this session began: the initial HTTP Client platform implementation (previously untracked), the redis-lab removal, and the JPA / object-storage / notification integration work. Kept separate from this session's HTTP Client review response, which lands in the following commit, so the two bodies of work stay reviewable apart. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
1a3b560678
commit
5f10b791d3
@@ -0,0 +1,66 @@
|
||||
# Storage certification
|
||||
|
||||
## Why a certification is per-volume
|
||||
|
||||
Atomic rename, same-file-store guarantees, and symlink refusal are properties of a specific
|
||||
filesystem behind a specific mount — not of "Kubernetes" or "a PVC". Change the CSI driver, the
|
||||
StorageClass, the access mode, the backend, or the mount options and any of them can differ. A
|
||||
certification that does not name all five is not transferable.
|
||||
|
||||
## What is certified
|
||||
|
||||
| Property | Why it matters |
|
||||
|---|---|
|
||||
| Same file store for staging and content | A rename across stores is a copy, so publication stops being atomic. |
|
||||
| Atomic rename | The publish path's default strategy. |
|
||||
| Atomic create (`O_EXCL`) | Makes a publish create-only rather than a silent overwrite. |
|
||||
| Symlink refusal | Stops a replaced parent from redirecting a write outside the root. |
|
||||
| Ranged read | The download contract depends on it. |
|
||||
|
||||
## Running the certification
|
||||
|
||||
```bash
|
||||
kubectl apply -f infra/fileserver/kubernetes/pvc-certification-job.yaml
|
||||
kubectl logs job/fileserver-pvc-certification
|
||||
```
|
||||
|
||||
The job writes a machine-readable result to the claim itself, carrying the full tuple:
|
||||
|
||||
```json
|
||||
{
|
||||
"kubernetesVersion": "...",
|
||||
"csiDriver": "...",
|
||||
"storageClass": "...",
|
||||
"accessMode": "ReadWriteOnce",
|
||||
"backend": "ext2/ext3",
|
||||
"mountOptions": "rw,relatime",
|
||||
"atomicMove": true,
|
||||
"sameFileStore": true,
|
||||
"atomicCreate": true
|
||||
}
|
||||
```
|
||||
|
||||
The job fails closed: a volume whose staging and content areas are on different stores is not
|
||||
certified, because its publish would silently degrade to a copy.
|
||||
|
||||
## Network filesystems
|
||||
|
||||
```bash
|
||||
docker compose -f infra/fileserver/nfs/compose.yml up -d
|
||||
FILESERVER_NFS_TESTS=true ./gradlew :adapter:outbound:fileserver:test
|
||||
```
|
||||
|
||||
The mount is `hard`, deliberately. A `soft` mount converts a slow server into a short write, which
|
||||
is exactly the corruption this design refuses to accept.
|
||||
|
||||
## Startup enforcement
|
||||
|
||||
`FileserverStartupValidator` re-runs the probe at boot and refuses to accept traffic when a required
|
||||
capability is missing — `ATOMIC_MOVE_REQUIRED` on a filesystem that cannot prove an atomic move
|
||||
fails closed rather than degrading silently.
|
||||
|
||||
## Adding a new store
|
||||
|
||||
Extend `ContentStoreContract` and pass it. A prose claim of compatibility is not accepted; the
|
||||
contract is executable precisely so a future object-storage adapter has to demonstrate the same
|
||||
offset, digest, and create-only behaviour the local store does.
|
||||
Reference in New Issue
Block a user