feat(railiance): adopt state-hub edge relay beachhead for WP-0015
Deploy actcore-statehub-edge-relay, point STATE_HUB_URL at it, retire the bespoke state-hub bridge, and accept edge-relay queued write receipts in report and ops evidence sinks.
This commit is contained in:
parent
1a0636845a
commit
cdbe4de2bf
13 changed files with 256 additions and 136 deletions
|
|
@ -10,7 +10,7 @@ data:
|
|||
TEMPORAL_HOST: actcore-temporal:7233
|
||||
TEMPORAL_NAMESPACE: default
|
||||
NATS_URL: nats://actcore-nats:4222
|
||||
STATE_HUB_URL: http://state-hub.state-hub.svc.cluster.local:8000
|
||||
STATE_HUB_URL: http://actcore-statehub-edge-relay:8000
|
||||
LLM_CONNECT_URL: http://llm-connect.activity-core.svc.cluster.local:8080
|
||||
LLM_CONNECT_TIMEOUT_SECONDS: "300"
|
||||
REPO_SCOPING_URL: http://repo-scoping.repo-scoping.svc.cluster.local:8020
|
||||
|
|
@ -572,28 +572,29 @@ data:
|
|||
kind: coordination-service
|
||||
lifecycle_state: observed
|
||||
health_status: observed_ok
|
||||
environment: local
|
||||
environment: railiance01
|
||||
owner_repos:
|
||||
- state-hub
|
||||
- the-custodian
|
||||
runtime:
|
||||
type: local-process
|
||||
host: local-workstation
|
||||
type: k3s
|
||||
cluster: railiance01-k3s
|
||||
namespace: state-hub
|
||||
endpoints:
|
||||
- id: state-hub-local-api
|
||||
- id: state-hub-edge-relay-health
|
||||
type: http
|
||||
url: "http://actcore-state-hub-bridge:8000/state/health"
|
||||
url: "http://actcore-statehub-edge-relay:8000/edge/health"
|
||||
expected_status: 200
|
||||
expected_signal: "health response"
|
||||
expected_signal: "edge relay health"
|
||||
backing_stores:
|
||||
- "postgresql:state-hub"
|
||||
access_paths:
|
||||
- type: http
|
||||
target: "http://actcore-state-hub-bridge:8000"
|
||||
target: "http://actcore-statehub-edge-relay:8000"
|
||||
status: observed_ok
|
||||
evidence: []
|
||||
gaps:
|
||||
- "Future cluster deployment readiness still needs ops evidence."
|
||||
- "Overnight triage proof after relay deploy still needs operator evidence."
|
||||
- id: inter-hub
|
||||
name: "Inter-Hub"
|
||||
kind: governance-service
|
||||
|
|
@ -774,16 +775,31 @@ spec:
|
|||
storage: 1Gi
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: actcore-state-hub-bridge
|
||||
name: actcore-statehub-edge-outbox
|
||||
namespace: activity-core
|
||||
labels:
|
||||
app.kubernetes.io/name: actcore-state-hub-bridge
|
||||
app.kubernetes.io/name: actcore-statehub-edge-relay
|
||||
app.kubernetes.io/part-of: activity-core
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 1Gi
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: actcore-statehub-edge-relay
|
||||
namespace: activity-core
|
||||
labels:
|
||||
app.kubernetes.io/name: actcore-statehub-edge-relay
|
||||
app.kubernetes.io/part-of: activity-core
|
||||
spec:
|
||||
selector:
|
||||
app.kubernetes.io/name: actcore-state-hub-bridge
|
||||
app.kubernetes.io/name: actcore-statehub-edge-relay
|
||||
ports:
|
||||
- name: http
|
||||
port: 8000
|
||||
|
|
@ -792,97 +808,75 @@ spec:
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: actcore-state-hub-bridge
|
||||
name: actcore-statehub-edge-relay
|
||||
namespace: activity-core
|
||||
labels:
|
||||
app.kubernetes.io/name: actcore-state-hub-bridge
|
||||
app.kubernetes.io/name: actcore-statehub-edge-relay
|
||||
app.kubernetes.io/part-of: activity-core
|
||||
spec:
|
||||
replicas: 0
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: actcore-state-hub-bridge
|
||||
app.kubernetes.io/name: actcore-statehub-edge-relay
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/name: actcore-state-hub-bridge
|
||||
app.kubernetes.io/name: actcore-statehub-edge-relay
|
||||
app.kubernetes.io/part-of: activity-core
|
||||
spec:
|
||||
hostNetwork: true
|
||||
dnsPolicy: ClusterFirstWithHostNet
|
||||
containers:
|
||||
- name: proxy
|
||||
image: activity-core:railiance01-prod
|
||||
imagePullPolicy: Never
|
||||
- name: relay
|
||||
# Published by Forgejo CI on state-hub main (edge read-cache, 1cf949b).
|
||||
image: forgejo.coulomb.social/coulomb/state-hub:main-1cf949b
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 18080
|
||||
containerPort: 8000
|
||||
env:
|
||||
- name: STATEHUB_UPSTREAM_URL
|
||||
value: http://state-hub.state-hub.svc.cluster.local:8000
|
||||
- name: STATEHUB_OUTBOX_PATH
|
||||
value: /var/statehub/edge-outbox.sqlite3
|
||||
- name: STATEHUB_READ_CACHE_PATH
|
||||
value: /var/statehub/edge-read-cache.sqlite3
|
||||
command:
|
||||
- python
|
||||
- -c
|
||||
- |
|
||||
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
|
||||
from urllib.error import HTTPError, URLError
|
||||
from urllib.request import Request, urlopen
|
||||
|
||||
TARGET = "http://127.0.0.1:18000"
|
||||
HOP_HEADERS = {"connection", "host", "keep-alive", "proxy-authenticate",
|
||||
"proxy-authorization", "te", "trailers",
|
||||
"transfer-encoding", "upgrade"}
|
||||
|
||||
class Proxy(BaseHTTPRequestHandler):
|
||||
def do_GET(self):
|
||||
self._proxy()
|
||||
|
||||
def do_POST(self):
|
||||
self._proxy()
|
||||
|
||||
def do_PATCH(self):
|
||||
self._proxy()
|
||||
|
||||
def _proxy(self):
|
||||
length = int(self.headers.get("content-length", "0") or "0")
|
||||
body = self.rfile.read(length) if length else None
|
||||
headers = {
|
||||
key: value
|
||||
for key, value in self.headers.items()
|
||||
if key.lower() not in HOP_HEADERS
|
||||
}
|
||||
request = Request(
|
||||
TARGET + self.path,
|
||||
data=body,
|
||||
headers=headers,
|
||||
method=self.command,
|
||||
)
|
||||
try:
|
||||
timeout = 360 if self.command == "POST" else 30
|
||||
with urlopen(request, timeout=timeout) as response:
|
||||
payload = response.read()
|
||||
self.send_response(response.status)
|
||||
for key, value in response.headers.items():
|
||||
if key.lower() not in HOP_HEADERS:
|
||||
self.send_header(key, value)
|
||||
self.end_headers()
|
||||
self.wfile.write(payload)
|
||||
except HTTPError as exc:
|
||||
payload = exc.read()
|
||||
self.send_response(exc.code)
|
||||
self.end_headers()
|
||||
self.wfile.write(payload)
|
||||
except URLError as exc:
|
||||
self.send_response(502)
|
||||
self.end_headers()
|
||||
self.wfile.write(str(exc).encode())
|
||||
|
||||
ThreadingHTTPServer(("0.0.0.0", 18080), Proxy).serve_forever()
|
||||
- uvicorn
|
||||
- api.edge.relay:app
|
||||
- --host
|
||||
- 0.0.0.0
|
||||
- --port
|
||||
- "8000"
|
||||
volumeMounts:
|
||||
- name: edge-outbox
|
||||
mountPath: /var/statehub
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /state/health
|
||||
path: /edge/health
|
||||
port: http
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 6
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /edge/health
|
||||
port: http
|
||||
initialDelaySeconds: 15
|
||||
periodSeconds: 30
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 3
|
||||
resources:
|
||||
requests:
|
||||
cpu: 50m
|
||||
memory: 128Mi
|
||||
limits:
|
||||
cpu: 500m
|
||||
memory: 512Mi
|
||||
volumes:
|
||||
- name: edge-outbox
|
||||
persistentVolumeClaim:
|
||||
claimName: actcore-statehub-edge-outbox
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
|
|
|
|||
|
|
@ -43,8 +43,11 @@ and a persistent working-memory volume mounted at
|
|||
Before trusting the daily 07:20
|
||||
Europe/Berlin schedule, verify both runtime dependencies:
|
||||
|
||||
- `actcore-state-hub-bridge` can reach the State Hub API through the node-local
|
||||
tunnel expected at `127.0.0.1:18000`.
|
||||
- `actcore-statehub-edge-relay` is ready and reports upstream reachability at
|
||||
`GET /edge/health` (upstream is the in-cluster State Hub API at
|
||||
`state-hub.state-hub.svc.cluster.local:8000`). `STATE_HUB_URL` points at the
|
||||
relay so allowlisted `GET` reads can be served from cache during brief upstream
|
||||
outages and queueable writes survive until replay.
|
||||
- `LLM_CONNECT_URL` points at the verified in-namespace llm-connect Service,
|
||||
`http://llm-connect.activity-core.svc.cluster.local:8080`, and the
|
||||
operator-owned provider Secret lets that Service serve the
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue