initial: Steam-Cloud-style per-user state sync skeleton
HTTP API + on-disk storage + auth-service token verification + dev mode. 31 tests pass, vet clean. See DESIGN.md for the architecture and README.md for the operator surface. Pending: pg-backed per-user quota override, snapshot retention / blob GC, tarball-vs-manifest content cross-check, end-to-end deploy on john.
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
# cloud-svc
|
||||
|
||||
Steam-Cloud-style per-user file sync for Minecraft clients. Pull on launch, push on exit, with per-file mtime conflict resolution + N-snapshot history.
|
||||
|
||||
Part of the automc platform. See [`DESIGN.md`](DESIGN.md) for architecture.
|
||||
|
||||
## Status
|
||||
|
||||
**Skeleton.** Code, tests, build all working. Not yet deployed.
|
||||
|
||||
- ✅ HTTP API (7 endpoints)
|
||||
- ✅ On-disk blob + tarball + manifest storage
|
||||
- ✅ Token verification via auth-service (with 60s cache)
|
||||
- ✅ Dev mode (accept any bearer)
|
||||
- ✅ Quota enforcement
|
||||
- ⏳ Pg-backed per-user quota override (currently DefaultQuota only)
|
||||
- ⏳ Snapshot retention / GC of unreferenced blobs
|
||||
- ⏳ Tarball-vs-manifest content cross-check on push
|
||||
|
||||
## Build + test
|
||||
|
||||
```fish
|
||||
make build
|
||||
make test
|
||||
make vet
|
||||
```
|
||||
|
||||
31 tests, 0 fails.
|
||||
|
||||
## Run locally (dev mode)
|
||||
|
||||
```fish
|
||||
make dev
|
||||
```
|
||||
|
||||
Listens on `127.0.0.1:9091`. Accepts ANY non-empty bearer token; the token becomes the user ID. Files land under `./data/`.
|
||||
|
||||
## Run against real auth-service
|
||||
|
||||
```fish
|
||||
CLOUD_LISTEN=127.0.0.1:9091 \
|
||||
CLOUD_STORAGE_ROOT=/var/lib/cloud-svc/data \
|
||||
CLOUD_AUTH_SERVICE_URL=http://auth-service:9090 \
|
||||
CLOUD_SERVICE_KEY=$(cat /etc/cloud-svc/service-key) \
|
||||
CLOUD_DEFAULT_QUOTA_MB=200 \
|
||||
./cloud-svc
|
||||
```
|
||||
|
||||
## API quick reference
|
||||
|
||||
| Method | Path | Purpose |
|
||||
|---|---|---|
|
||||
| `GET` | `/v1/manifest` | Latest manifest for caller |
|
||||
| `GET` | `/v1/blob/{sha256}` | Raw file content |
|
||||
| `POST` | `/v1/snapshot` | Multipart upload: `manifest` + `tarball` |
|
||||
| `GET` | `/v1/snapshots` | List caller's snapshot history |
|
||||
| `GET` | `/v1/snapshot/{id}` | Historical tarball |
|
||||
| `DELETE` | `/v1/snapshot/{id}` | Remove (latest protected) |
|
||||
| `GET` | `/v1/quota` | `{used_bytes, limit_bytes, snapshots}` |
|
||||
| `GET` | `/healthz` | Unauthenticated liveness probe |
|
||||
|
||||
All authenticated endpoints require `Authorization: Bearer <token>` with `cloud:rw` scope.
|
||||
|
||||
See [`DESIGN.md`](DESIGN.md) for full details + on-disk layout + conflict semantics.
|
||||
|
||||
## Configuration (env)
|
||||
|
||||
| Var | Default | Purpose |
|
||||
|---|---|---|
|
||||
| `CLOUD_LISTEN` | `127.0.0.1:9091` | HTTP bind address |
|
||||
| `CLOUD_STORAGE_ROOT` | `/data` | Root dir for blobs + snapshots |
|
||||
| `CLOUD_AUTH_SERVICE_URL` | `http://auth-service:9090` | auth-service base URL |
|
||||
| `CLOUD_SERVICE_KEY` | (required when not dev) | cloud-svc's own X-API-Key for calling auth-service |
|
||||
| `CLOUD_AUTH_CACHE_TTL` | `60s` | Verified-token cache TTL |
|
||||
| `CLOUD_DEFAULT_QUOTA_MB` | `200` | Per-user quota (MB) |
|
||||
| `CLOUD_DEV_MODE` | unset | If `1`: accept any bearer; bypass auth-service |
|
||||
Reference in New Issue
Block a user