generated from coulomb/repo-seed
Align naming with coulomb.social reuse-surface conventions
Some checks failed
ci / validate-registry (push) Has been cancelled
Some checks failed
ci / validate-registry (push) Has been cancelled
Use reuse.coulomb.social, REUSE_SURFACE_URL/TOKEN env vars, reuse-surface image and reuse-surface-env secret. Replace reuse-surface-hub entrypoint with reuse-surface serve; CLI uses --base-url.
This commit is contained in:
@@ -130,11 +130,11 @@ artifacts.
|
||||
.venv/bin/reuse-surface federation compose
|
||||
.venv/bin/reuse-surface graph --check
|
||||
|
||||
# Federation hub service (local)
|
||||
# REUSE_SURFACE_HUB_TOKEN=dev-token reuse-surface-hub
|
||||
# Federation service (local)
|
||||
# REUSE_SURFACE_TOKEN=dev-token reuse-surface serve
|
||||
|
||||
# Hub CLI (against deployed or local hub)
|
||||
# REUSE_SURFACE_HUB_URL=http://127.0.0.1:8000 reuse-surface hub status
|
||||
# Hub CLI (against deployed or local service)
|
||||
# REUSE_SURFACE_URL=http://127.0.0.1:8000 reuse-surface hub status
|
||||
|
||||
# Automated tests
|
||||
.venv/bin/pytest -q
|
||||
|
||||
10
Dockerfile
10
Dockerfile
@@ -8,11 +8,11 @@ COPY schemas ./schemas
|
||||
|
||||
RUN pip install --no-cache-dir .
|
||||
|
||||
ENV REUSE_SURFACE_HUB_HOST=0.0.0.0
|
||||
ENV REUSE_SURFACE_HUB_PORT=8000
|
||||
ENV REUSE_SURFACE_HUB_DB=/data/hub.db
|
||||
ENV REUSE_SURFACE_HUB_CACHE_DIR=/data/cache
|
||||
ENV REUSE_SURFACE_HOST=0.0.0.0
|
||||
ENV REUSE_SURFACE_PORT=8000
|
||||
ENV REUSE_SURFACE_DB=/data/reuse.db
|
||||
ENV REUSE_SURFACE_CACHE_DIR=/data/cache
|
||||
|
||||
EXPOSE 8000
|
||||
|
||||
CMD ["reuse-surface-hub"]
|
||||
CMD ["reuse-surface", "serve"]
|
||||
@@ -1,32 +0,0 @@
|
||||
# Federation Hub — Kubernetes Deployment
|
||||
|
||||
Companion to **RAILIANCE-WP-0007** (`railiance-apps` Helm release).
|
||||
|
||||
## Image
|
||||
|
||||
```bash
|
||||
docker build -t gitea.coulomb.social/coulomb/reuse-surface-hub:<tag> .
|
||||
docker push gitea.coulomb.social/coulomb/reuse-surface-hub:<tag>
|
||||
```
|
||||
|
||||
## Required environment
|
||||
|
||||
| Variable | Purpose |
|
||||
|---|---|
|
||||
| `REUSE_SURFACE_HUB_TOKEN` | Bearer token for write API |
|
||||
| `REUSE_SURFACE_HUB_DB` | SQLite path (default `/data/hub.db`) |
|
||||
| `REUSE_SURFACE_HUB_CACHE_DIR` | Remote index cache (default `/data/cache`) |
|
||||
|
||||
Mount a PVC at `/data` for persistence.
|
||||
|
||||
## Probes
|
||||
|
||||
- Liveness/readiness: `GET /health` on port `8000`
|
||||
|
||||
## Client configuration
|
||||
|
||||
```bash
|
||||
export REUSE_SURFACE_HUB_URL=https://reuse-hub.whywhynot.de
|
||||
export REUSE_SURFACE_HUB_TOKEN=<write-token>
|
||||
reuse-surface hub status
|
||||
```
|
||||
39
docs/deploy/reuse-kubernetes.md
Normal file
39
docs/deploy/reuse-kubernetes.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# reuse-surface Service — Kubernetes Deployment
|
||||
|
||||
Companion to **RAILIANCE-WP-0007** (`railiance-apps` Helm release).
|
||||
|
||||
## Image
|
||||
|
||||
Repository: `gitea.coulomb.social/coulomb/reuse-surface` (Gitea org `coulomb`, repo `reuse-surface`).
|
||||
|
||||
```bash
|
||||
docker build -t gitea.coulomb.social/coulomb/reuse-surface:<tag> .
|
||||
docker push gitea.coulomb.social/coulomb/reuse-surface:<tag>
|
||||
```
|
||||
|
||||
## Required environment
|
||||
|
||||
| Variable | Purpose |
|
||||
|---|---|
|
||||
| `REUSE_SURFACE_TOKEN` | Bearer token for write API |
|
||||
| `REUSE_SURFACE_DB` | SQLite path (default `/data/reuse.db`) |
|
||||
| `REUSE_SURFACE_CACHE_DIR` | Remote index cache (default `/data/cache`) |
|
||||
|
||||
Mount a PVC at `/data` for persistence. Inject secrets via Kubernetes Secret
|
||||
`reuse-surface-env`.
|
||||
|
||||
## Probes
|
||||
|
||||
- Liveness/readiness: `GET /health` on port `8000`
|
||||
|
||||
## Public URL
|
||||
|
||||
`https://reuse.coulomb.social`
|
||||
|
||||
## Client configuration
|
||||
|
||||
```bash
|
||||
export REUSE_SURFACE_URL=https://reuse.coulomb.social
|
||||
export REUSE_SURFACE_TOKEN=<write-token>
|
||||
reuse-surface hub status
|
||||
```
|
||||
@@ -23,7 +23,6 @@ dev = [
|
||||
|
||||
[project.scripts]
|
||||
reuse-surface = "reuse_surface.cli:main"
|
||||
reuse-surface-hub = "reuse_surface.hub.app:main"
|
||||
|
||||
[tool.setuptools.packages.find]
|
||||
where = ["."]
|
||||
|
||||
@@ -192,13 +192,20 @@ def cmd_catalog(args: argparse.Namespace) -> int:
|
||||
return 0
|
||||
|
||||
|
||||
def _hub_url(args: argparse.Namespace) -> str | None:
|
||||
return getattr(args, "hub_url", None)
|
||||
def _service_url(args: argparse.Namespace) -> str | None:
|
||||
return getattr(args, "base_url", None)
|
||||
|
||||
|
||||
def cmd_serve(args: argparse.Namespace) -> int:
|
||||
from reuse_surface.hub.app import main as serve_main
|
||||
|
||||
serve_main()
|
||||
return 0
|
||||
|
||||
|
||||
def cmd_hub_status(args: argparse.Namespace) -> int:
|
||||
try:
|
||||
status, payload = hub_client.hub_status(_hub_url(args))
|
||||
status, payload = hub_client.hub_status(_service_url(args))
|
||||
except ValueError as exc:
|
||||
print(f"error: {exc}", file=sys.stderr)
|
||||
return 1
|
||||
@@ -211,7 +218,7 @@ def cmd_hub_status(args: argparse.Namespace) -> int:
|
||||
|
||||
def cmd_hub_list(args: argparse.Namespace) -> int:
|
||||
try:
|
||||
status, payload = hub_client.hub_list(_hub_url(args))
|
||||
status, payload = hub_client.hub_list(_service_url(args))
|
||||
except ValueError as exc:
|
||||
print(f"error: {exc}", file=sys.stderr)
|
||||
return 1
|
||||
@@ -227,7 +234,7 @@ def cmd_hub_list(args: argparse.Namespace) -> int:
|
||||
|
||||
def cmd_hub_show(args: argparse.Namespace) -> int:
|
||||
try:
|
||||
status, payload = hub_client.hub_show(args.repo, _hub_url(args))
|
||||
status, payload = hub_client.hub_show(args.repo, _service_url(args))
|
||||
except ValueError as exc:
|
||||
print(f"error: {exc}", file=sys.stderr)
|
||||
return 1
|
||||
@@ -249,7 +256,7 @@ def cmd_hub_register(args: argparse.Namespace) -> int:
|
||||
if args.description:
|
||||
body["description"] = args.description
|
||||
try:
|
||||
status, payload = hub_client.hub_register(body, _hub_url(args))
|
||||
status, payload = hub_client.hub_register(body, _service_url(args))
|
||||
except ValueError as exc:
|
||||
print(f"error: {exc}", file=sys.stderr)
|
||||
return 1
|
||||
@@ -276,7 +283,7 @@ def cmd_hub_update(args: argparse.Namespace) -> int:
|
||||
print("error: no fields to update", file=sys.stderr)
|
||||
return 1
|
||||
try:
|
||||
status, payload = hub_client.hub_update(args.repo, body, _hub_url(args))
|
||||
status, payload = hub_client.hub_update(args.repo, body, _service_url(args))
|
||||
except ValueError as exc:
|
||||
print(f"error: {exc}", file=sys.stderr)
|
||||
return 1
|
||||
@@ -412,10 +419,13 @@ def main(argv: list[str] | None = None) -> int:
|
||||
)
|
||||
graph.set_defaults(func=cmd_graph)
|
||||
|
||||
hub = subparsers.add_parser("hub", help="federation hub client")
|
||||
serve = subparsers.add_parser("serve", help="run federation service API")
|
||||
serve.set_defaults(func=cmd_serve)
|
||||
|
||||
hub = subparsers.add_parser("hub", help="federation service client")
|
||||
hub.add_argument(
|
||||
"--hub-url",
|
||||
help="hub base URL (or set REUSE_SURFACE_HUB_URL)",
|
||||
"--base-url",
|
||||
help="service base URL (or set REUSE_SURFACE_URL)",
|
||||
)
|
||||
hub_sub = hub.add_subparsers(dest="hub_command", required=True)
|
||||
|
||||
|
||||
@@ -15,15 +15,15 @@ HUB_VERSION = "0.1.0"
|
||||
|
||||
|
||||
def _db_path() -> Path:
|
||||
return Path(os.environ.get("REUSE_SURFACE_HUB_DB", "/data/hub.db"))
|
||||
return Path(os.environ.get("REUSE_SURFACE_DB", "/data/reuse.db"))
|
||||
|
||||
|
||||
def _cache_dir() -> Path:
|
||||
return Path(os.environ.get("REUSE_SURFACE_HUB_CACHE_DIR", "/data/cache"))
|
||||
return Path(os.environ.get("REUSE_SURFACE_CACHE_DIR", "/data/cache"))
|
||||
|
||||
|
||||
def _write_token() -> str:
|
||||
return os.environ.get("REUSE_SURFACE_HUB_TOKEN", "")
|
||||
return os.environ.get("REUSE_SURFACE_TOKEN", "")
|
||||
|
||||
|
||||
def _store() -> HubStore:
|
||||
@@ -41,7 +41,7 @@ def _require_auth(authorization: str | None = Header(default=None)) -> None:
|
||||
write_token = _write_token()
|
||||
if not write_token:
|
||||
raise _http_error(
|
||||
503, "misconfigured", "REUSE_SURFACE_HUB_TOKEN is not configured"
|
||||
503, "misconfigured", "REUSE_SURFACE_TOKEN is not configured"
|
||||
)
|
||||
if not authorization or not authorization.startswith("Bearer "):
|
||||
raise _http_error(401, "unauthorized", "Bearer token required")
|
||||
@@ -56,7 +56,7 @@ def create_app() -> FastAPI:
|
||||
|
||||
@app.get("/health")
|
||||
def health() -> dict[str, str]:
|
||||
return {"status": "ok", "service": "reuse-surface-hub", "version": HUB_VERSION}
|
||||
return {"status": "ok", "service": "reuse-surface", "version": HUB_VERSION}
|
||||
|
||||
@app.get("/v1/repos")
|
||||
def list_repos() -> dict[str, Any]:
|
||||
@@ -138,6 +138,6 @@ def create_app() -> FastAPI:
|
||||
def main() -> None:
|
||||
import uvicorn
|
||||
|
||||
host = os.environ.get("REUSE_SURFACE_HUB_HOST", "0.0.0.0")
|
||||
port = int(os.environ.get("REUSE_SURFACE_HUB_PORT", "8000"))
|
||||
host = os.environ.get("REUSE_SURFACE_HOST", "0.0.0.0")
|
||||
port = int(os.environ.get("REUSE_SURFACE_PORT", "8000"))
|
||||
uvicorn.run(create_app(), host=host, port=port, reload=False)
|
||||
@@ -7,7 +7,7 @@ from typing import Any
|
||||
from reuse_surface.federation import compose_federated_index
|
||||
from reuse_surface.hub.store import HubStore
|
||||
|
||||
DEFAULT_DOMAIN = os.environ.get("REUSE_SURFACE_HUB_DOMAIN", "helix_forge")
|
||||
DEFAULT_DOMAIN = os.environ.get("REUSE_SURFACE_DOMAIN", "helix_forge")
|
||||
|
||||
|
||||
def registrations_to_manifest(
|
||||
|
||||
@@ -7,17 +7,17 @@ import urllib.request
|
||||
from typing import Any
|
||||
|
||||
|
||||
def hub_base_url(explicit: str | None = None) -> str:
|
||||
base = (explicit or os.environ.get("REUSE_SURFACE_HUB_URL", "")).rstrip("/")
|
||||
def service_base_url(explicit: str | None = None) -> str:
|
||||
base = (explicit or os.environ.get("REUSE_SURFACE_URL", "")).rstrip("/")
|
||||
if not base:
|
||||
raise ValueError(
|
||||
"hub URL not configured; set REUSE_SURFACE_HUB_URL or pass --hub-url"
|
||||
"service URL not configured; set REUSE_SURFACE_URL or pass --base-url"
|
||||
)
|
||||
return base
|
||||
|
||||
|
||||
def hub_token() -> str | None:
|
||||
return os.environ.get("REUSE_SURFACE_HUB_TOKEN")
|
||||
def service_token() -> str | None:
|
||||
return os.environ.get("REUSE_SURFACE_TOKEN")
|
||||
|
||||
|
||||
def _request(
|
||||
@@ -49,24 +49,24 @@ def _request(
|
||||
|
||||
|
||||
def hub_status(base_url: str | None = None) -> tuple[int, Any]:
|
||||
return _request("GET", f"{hub_base_url(base_url)}/health")
|
||||
return _request("GET", f"{service_base_url(base_url)}/health")
|
||||
|
||||
|
||||
def hub_list(base_url: str | None = None) -> tuple[int, Any]:
|
||||
return _request("GET", f"{hub_base_url(base_url)}/v1/repos")
|
||||
return _request("GET", f"{service_base_url(base_url)}/v1/repos")
|
||||
|
||||
|
||||
def hub_show(repo: str, base_url: str | None = None) -> tuple[int, Any]:
|
||||
return _request("GET", f"{hub_base_url(base_url)}/v1/repos/{repo}")
|
||||
return _request("GET", f"{service_base_url(base_url)}/v1/repos/{repo}")
|
||||
|
||||
|
||||
def hub_register(payload: dict[str, Any], base_url: str | None = None) -> tuple[int, Any]:
|
||||
token = hub_token()
|
||||
token = service_token()
|
||||
if not token:
|
||||
raise ValueError("REUSE_SURFACE_HUB_TOKEN is required for register")
|
||||
raise ValueError("REUSE_SURFACE_TOKEN is required for register")
|
||||
return _request(
|
||||
"POST",
|
||||
f"{hub_base_url(base_url)}/v1/repos",
|
||||
f"{service_base_url(base_url)}/v1/repos",
|
||||
token=token,
|
||||
body=payload,
|
||||
)
|
||||
@@ -75,12 +75,12 @@ def hub_register(payload: dict[str, Any], base_url: str | None = None) -> tuple[
|
||||
def hub_update(
|
||||
repo: str, payload: dict[str, Any], base_url: str | None = None
|
||||
) -> tuple[int, Any]:
|
||||
token = hub_token()
|
||||
token = service_token()
|
||||
if not token:
|
||||
raise ValueError("REUSE_SURFACE_HUB_TOKEN is required for update")
|
||||
raise ValueError("REUSE_SURFACE_TOKEN is required for update")
|
||||
return _request(
|
||||
"PATCH",
|
||||
f"{hub_base_url(base_url)}/v1/repos/{repo}",
|
||||
f"{service_base_url(base_url)}/v1/repos/{repo}",
|
||||
token=token,
|
||||
body=payload,
|
||||
)
|
||||
@@ -21,7 +21,7 @@ Companion deployment workplan: `railiance-apps` **RAILIANCE-WP-0007**.
|
||||
|
||||
| Item | Value |
|
||||
|---|---|
|
||||
| Default production URL | `https://reuse-hub.whywhynot.de` (confirm at deploy) |
|
||||
| Default production URL | `https://reuse.coulomb.social` |
|
||||
| API prefix | `/v1` |
|
||||
| Read formats | JSON (default), YAML via `Accept: application/yaml` or `?format=yaml` |
|
||||
| Write content type | `application/json` |
|
||||
@@ -30,8 +30,8 @@ Environment variables for clients:
|
||||
|
||||
| Variable | Purpose |
|
||||
|---|---|
|
||||
| `REUSE_SURFACE_HUB_URL` | Hub base URL (no trailing slash) |
|
||||
| `REUSE_SURFACE_HUB_TOKEN` | Bearer token for write operations |
|
||||
| `REUSE_SURFACE_URL` | Service base URL (no trailing slash) |
|
||||
| `REUSE_SURFACE_TOKEN` | Bearer token for write operations |
|
||||
|
||||
---
|
||||
|
||||
@@ -45,7 +45,7 @@ Environment variables for clients:
|
||||
Write requests must include:
|
||||
|
||||
```http
|
||||
Authorization: Bearer <REUSE_SURFACE_HUB_TOKEN>
|
||||
Authorization: Bearer <REUSE_SURFACE_TOKEN>
|
||||
```
|
||||
|
||||
Missing or invalid token → `401 Unauthorized`.
|
||||
@@ -88,7 +88,7 @@ Liveness/readiness probe.
|
||||
```json
|
||||
{
|
||||
"status": "ok",
|
||||
"service": "reuse-surface-hub",
|
||||
"service": "reuse-surface",
|
||||
"version": "0.1.0"
|
||||
}
|
||||
```
|
||||
@@ -232,10 +232,10 @@ Non-2xx responses use:
|
||||
|
||||
| Env var | Required | Purpose |
|
||||
|---|---|---|
|
||||
| `REUSE_SURFACE_HUB_TOKEN` | yes | Write API bearer token |
|
||||
| `REUSE_SURFACE_HUB_DB` | no | SQLite path (default `/data/hub.db`) |
|
||||
| `REUSE_SURFACE_HUB_CACHE_DIR` | no | Remote index cache (default `/data/cache`) |
|
||||
| `REUSE_SURFACE_HUB_DOMAIN` | no | Default federated `domain` (default `helix_forge`) |
|
||||
| `REUSE_SURFACE_TOKEN` | yes | Write API bearer token |
|
||||
| `REUSE_SURFACE_DB` | no | SQLite path (default `/data/reuse.db`) |
|
||||
| `REUSE_SURFACE_CACHE_DIR` | no | Remote index cache (default `/data/cache`) |
|
||||
| `REUSE_SURFACE_DOMAIN` | no | Default federated `domain` (default `helix_forge`) |
|
||||
|
||||
---
|
||||
|
||||
@@ -249,13 +249,16 @@ Non-2xx responses use:
|
||||
| `reuse-surface hub register ...` | `POST /v1/repos` |
|
||||
| `reuse-surface hub update ...` | `PATCH /v1/repos/{repo}` |
|
||||
|
||||
Global flags: `--hub-url`, env `REUSE_SURFACE_HUB_URL`, `REUSE_SURFACE_HUB_TOKEN`.
|
||||
Run locally: `reuse-surface serve`. Global client flags: `--base-url`, env
|
||||
`REUSE_SURFACE_URL`, `REUSE_SURFACE_TOKEN`.
|
||||
|
||||
---
|
||||
|
||||
## 9. Deployment reference
|
||||
|
||||
- Image: `gitea.coulomb.social/coulomb/reuse-surface-hub:<tag>`
|
||||
- Image: `gitea.coulomb.social/coulomb/reuse-surface:<tag>`
|
||||
- Public URL: `https://reuse.coulomb.social`
|
||||
- Secret: `reuse-surface-env` with `REUSE_SURFACE_TOKEN`
|
||||
- Probe path: `/health`
|
||||
- Persistence: PVC at `/data` (SQLite + fetch cache)
|
||||
- Helm release: `railiance-apps` RAILIANCE-WP-0007
|
||||
@@ -32,9 +32,9 @@ capabilities:
|
||||
def hub_client(tmp_path, monkeypatch):
|
||||
db_path = tmp_path / "hub.db"
|
||||
cache_dir = tmp_path / "cache"
|
||||
monkeypatch.setenv("REUSE_SURFACE_HUB_TOKEN", "test-token")
|
||||
monkeypatch.setenv("REUSE_SURFACE_HUB_DB", str(db_path))
|
||||
monkeypatch.setenv("REUSE_SURFACE_HUB_CACHE_DIR", str(cache_dir))
|
||||
monkeypatch.setenv("REUSE_SURFACE_TOKEN", "test-token")
|
||||
monkeypatch.setenv("REUSE_SURFACE_DB", str(db_path))
|
||||
monkeypatch.setenv("REUSE_SURFACE_CACHE_DIR", str(cache_dir))
|
||||
app = create_app()
|
||||
with TestClient(app) as client:
|
||||
yield client
|
||||
|
||||
@@ -92,15 +92,15 @@ Writes `docs/graph/capability-graph.mmd` and `docs/graph/index.html`.
|
||||
Client for the federation hub service (REUSE-WP-0011).
|
||||
|
||||
```bash
|
||||
export REUSE_SURFACE_HUB_URL=https://reuse-hub.whywhynot.de
|
||||
export REUSE_SURFACE_HUB_TOKEN=<write-token>
|
||||
export REUSE_SURFACE_URL=https://reuse.coulomb.social
|
||||
export REUSE_SURFACE_TOKEN=<write-token>
|
||||
reuse-surface hub status
|
||||
reuse-surface hub list
|
||||
reuse-surface hub register --repo state-hub --url https://.../capabilities.yaml
|
||||
reuse-surface hub update --repo state-hub --enabled true
|
||||
```
|
||||
|
||||
Run the hub service locally: `reuse-surface-hub` (requires `REUSE_SURFACE_HUB_TOKEN`).
|
||||
Run the service locally: `REUSE_SURFACE_TOKEN=dev-token reuse-surface serve`
|
||||
|
||||
## Export format
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ for discovery without cloning every repo.
|
||||
| Operations | Container image, deployment manifests, TLS ingress, documented runbook |
|
||||
| Dogfood | `reuse-surface` and at least one sibling repo registered via the hub |
|
||||
|
||||
**Proposed public URL (confirm in T05):** `https://reuse-hub.whywhynot.de`
|
||||
**Public URL:** `https://reuse.coulomb.social`
|
||||
|
||||
## Design decisions (draft)
|
||||
|
||||
@@ -59,7 +59,7 @@ for discovery without cloning every repo.
|
||||
`url` sources (reuse WP-0010 fetch/cache logic) and merges into
|
||||
`GET /v1/federated` output. Local-only `index` paths are **not** valid hub
|
||||
registrations unless expressed as published raw URLs.
|
||||
- **Auth (MVP):** Token-based write access via `REUSE_SURFACE_HUB_TOKEN` /
|
||||
- **Auth (MVP):** Token-based write access via `REUSE_SURFACE_TOKEN` /
|
||||
`Authorization: Bearer`; read endpoints public for agent discovery.
|
||||
- **Persistence (MVP):** SQLite on a PVC inside the hub container. Postgres
|
||||
via cnpg is a follow-up if multi-replica or backup requirements emerge.
|
||||
@@ -100,7 +100,7 @@ plus hub metadata (`registered_at`, `updated_at`, `registered_by`).
|
||||
## CLI sketch (T03 refines)
|
||||
|
||||
```bash
|
||||
# Configure hub endpoint (env REUSE_SURFACE_HUB_URL or --hub-url)
|
||||
# Configure service URL (env REUSE_SURFACE_URL or --base-url)
|
||||
reuse-surface hub status
|
||||
reuse-surface hub list
|
||||
reuse-surface hub register --repo state-hub \
|
||||
@@ -167,8 +167,9 @@ state_hub_task_id: "38fec6ce-23c0-4157-8350-7d112b9e8264"
|
||||
Extend `reuse-surface` CLI with `hub` subcommands:
|
||||
|
||||
- `register`, `update`, `show`, `list`, `status`
|
||||
- `--hub-url` flag and `REUSE_SURFACE_HUB_URL` env support
|
||||
- `REUSE_SURFACE_HUB_TOKEN` for authenticated writes
|
||||
- `--base-url` flag and `REUSE_SURFACE_URL` env support
|
||||
- `REUSE_SURFACE_TOKEN` for authenticated writes
|
||||
- `reuse-surface serve` to run the API locally or in container
|
||||
- Document in `tools/README.md` and `AGENTS.md`
|
||||
|
||||
## Containerize And Publish Deployment Artifacts
|
||||
@@ -183,8 +184,8 @@ state_hub_task_id: "24eec9ad-21fc-4f0b-8671-72d955b15e68"
|
||||
Provide:
|
||||
|
||||
- `Dockerfile` for the hub service
|
||||
- Example k8s manifests or Helm values template under `deploy/` or `docs/deploy/`
|
||||
- Image naming convention: `gitea.coulomb.social/coulomb/reuse-surface-hub:<tag>`
|
||||
- Example k8s manifests or Helm values template under `docs/deploy/`
|
||||
- Image: `gitea.coulomb.social/coulomb/reuse-surface:<tag>`
|
||||
- CI job or documented build/push steps (coordinate with `railiance-forge`
|
||||
registry guidance)
|
||||
|
||||
@@ -199,10 +200,10 @@ state_hub_task_id: "7f26a70f-7b7d-413d-8162-931c6dffef6a"
|
||||
|
||||
Deploy the hub as a governed release on `railiance01`:
|
||||
|
||||
- Confirm hostname (default `reuse-hub.whywhynot.de`) and DNS A record
|
||||
- Confirm DNS for `reuse.coulomb.social` (coulomb.social zone)
|
||||
- Traefik ingress + cert-manager TLS
|
||||
- PVC for SQLite data
|
||||
- Inject hub write token via SOPS/sealed secret
|
||||
- Inject `REUSE_SURFACE_TOKEN` via Secret `reuse-surface-env` (SOPS handoff)
|
||||
- Verify `GET /health` and `GET /v1/federated` from workstation and from cluster
|
||||
|
||||
**Blocked on:** DNS decision, operator secret provisioning, and
|
||||
|
||||
Reference in New Issue
Block a user