feat: add dev deploy health skeleton

This commit is contained in:
HWLAB Code Queue
2026-05-21 15:05:29 +00:00
parent 440ef6adaf
commit b666f30747
16 changed files with 1475 additions and 13 deletions
+29
View File
@@ -0,0 +1,29 @@
{
"version": 1,
"name": "hwlab-deploy-skeleton-ci",
"profile": "dev",
"commands": [
{
"name": "contract-check",
"run": "npm run check"
},
{
"name": "parse-deploy-json",
"run": "node -e \"JSON.parse(require('node:fs').readFileSync('deploy/deploy.json','utf8'))\""
},
{
"name": "parse-k8s-json-yaml",
"run": "node -e \"const fs=require('node:fs'); for (const f of fs.readdirSync('deploy/k8s/base').concat(fs.readdirSync('deploy/k8s/dev').map(x=>'../dev/'+x), fs.readdirSync('deploy/k8s/prod').map(x=>'../prod/'+x))) { if (!f.endsWith('.yaml')) continue; const p=f.startsWith('..')?'deploy/k8s/'+f.replace('../',''):'deploy/k8s/base/'+f; JSON.parse(fs.readFileSync(p,'utf8')); }\""
},
{
"name": "parse-frp-toml",
"run": "python3 - <<'PY'\nimport pathlib, tomllib\nfor path in pathlib.Path('deploy/frp').glob('*.toml'):\n tomllib.loads(path.read_text())\nPY"
}
],
"forbidden": [
"prod-deploy",
"secret-material",
"unidesk-runtime-substitute",
"force-push"
]
}
+22
View File
@@ -5,3 +5,25 @@
The MVP acceptance environment is DEV only, with endpoint
`http://74.48.78.17:6667`. PROD profile fields may be represented in schema for
future compatibility, but PROD deployment is not part of MVP acceptance.
## L5 DEV Skeleton
- `deploy/deploy.json` is the DEV-only deploy manifest.
- `deploy/k8s/base` contains parseable k3s resource skeletons for the frozen
HWLAB service IDs.
- `deploy/k8s/dev` contains the DEV health contract and endpoint metadata.
- `deploy/k8s/prod` is a disabled placeholder gate only.
- `deploy/frp` describes the D601-to-master reverse link without secrets.
- `deploy/master-edge` describes public edge ownership and health boundaries.
Next DEV deploy smoke commands, for a separately authorized deployment task:
```sh
npm run check
node -e "JSON.parse(require('node:fs').readFileSync('deploy/deploy.json','utf8'))"
kubectl apply --dry-run=server -k deploy/k8s/dev
curl -fsS http://74.48.78.17:6667/health/live
```
Do not run PROD deployment or substitute UniDesk backend, provider-gateway, or
microservice proxy for HWLAB runtime services.
+143 -13
View File
@@ -1,7 +1,7 @@
{
"manifestVersion": "v1",
"environment": "dev",
"commitId": "6509a35",
"commitId": "24eb3bf",
"namespace": "hwlab-dev",
"endpoint": "http://74.48.78.17:6667",
"profiles": {
@@ -10,42 +10,172 @@
"enabled": true,
"namespace": "hwlab-dev",
"endpoint": "http://74.48.78.17:6667",
"notes": "HWLAB dev deploy manifest with explicit commitId for repo-local skills artifact"
"notes": "DEV-only k3s deployment skeleton. D601 reaches the master edge through frp reverse tunnel."
},
"prod": {
"name": "prod",
"enabled": false,
"namespace": "hwlab-prod",
"notes": "Reserved placeholder only. PROD deployment and acceptance are explicitly out of scope."
}
},
"services": [
{
"serviceId": "hwlab-agent-mgr",
"image": "hwlab-agent-mgr:6509a35",
"serviceId": "hwlab-cloud-api",
"image": "ghcr.io/pikastech/hwlab-cloud-api:24eb3bf",
"namespace": "hwlab-dev",
"healthPath": "/health",
"healthPath": "/health/live",
"profile": "dev",
"replicas": 1,
"env": {
"HWLAB_AGENT_SESSION_MODE": "control-plane"
"HWLAB_ENVIRONMENT": "dev",
"HWLAB_PUBLIC_ENDPOINT": "http://74.48.78.17:6667",
"HWLAB_RUNTIME_SUBSTITUTE_FORBIDDEN": "unidesk-backend,provider-gateway,microservice-proxy"
}
},
{
"serviceId": "hwlab-cloud-web",
"image": "ghcr.io/pikastech/hwlab-cloud-web:24eb3bf",
"namespace": "hwlab-dev",
"healthPath": "/health/live",
"profile": "dev",
"replicas": 1,
"env": {
"HWLAB_ENVIRONMENT": "dev",
"HWLAB_API_BASE_URL": "http://hwlab-cloud-api.hwlab-dev.svc.cluster.local:6667"
}
},
{
"serviceId": "hwlab-agent-mgr",
"image": "ghcr.io/pikastech/hwlab-agent-mgr:24eb3bf",
"namespace": "hwlab-dev",
"healthPath": "/health/live",
"profile": "dev",
"replicas": 1,
"env": {
"HWLAB_AGENT_SESSION_MODE": "control-plane",
"HWLAB_ENVIRONMENT": "dev"
}
},
{
"serviceId": "hwlab-agent-worker",
"image": "hwlab-agent-worker:6509a35",
"image": "ghcr.io/pikastech/hwlab-agent-worker:24eb3bf",
"namespace": "hwlab-dev",
"healthPath": "/health",
"healthPath": "/health/live",
"profile": "dev",
"replicas": 0,
"env": {
"HWLAB_AGENT_SESSION_MODE": "session-scoped"
"HWLAB_AGENT_SESSION_MODE": "session-scoped",
"HWLAB_ENVIRONMENT": "dev"
}
},
{
"serviceId": "hwlab-gateway",
"image": "ghcr.io/pikastech/hwlab-gateway:24eb3bf",
"namespace": "hwlab-dev",
"healthPath": "/health/live",
"profile": "dev",
"replicas": 0,
"env": {
"HWLAB_GATEWAY_MODE": "hardware-boundary",
"HWLAB_ENVIRONMENT": "dev"
}
},
{
"serviceId": "hwlab-gateway-simu",
"image": "ghcr.io/pikastech/hwlab-gateway-simu:24eb3bf",
"namespace": "hwlab-dev",
"healthPath": "/health/live",
"profile": "dev",
"replicas": 1,
"env": {
"HWLAB_GATEWAY_MODE": "simulator",
"HWLAB_BOX_RESOURCES": "res_boxsim_alpha"
}
},
{
"serviceId": "hwlab-box-simu",
"image": "ghcr.io/pikastech/hwlab-box-simu:24eb3bf",
"namespace": "hwlab-dev",
"healthPath": "/health/live",
"profile": "dev",
"replicas": 1,
"env": {
"HWLAB_BOX_ID": "boxsim_alpha",
"HWLAB_ENVIRONMENT": "dev"
}
},
{
"serviceId": "hwlab-patch-panel",
"image": "ghcr.io/pikastech/hwlab-patch-panel:24eb3bf",
"namespace": "hwlab-dev",
"healthPath": "/health/live",
"profile": "dev",
"replicas": 1,
"env": {
"HWLAB_PATCH_PANEL_MODE": "dev-skeleton",
"HWLAB_ENVIRONMENT": "dev"
}
},
{
"serviceId": "hwlab-router",
"image": "ghcr.io/pikastech/hwlab-router:24eb3bf",
"namespace": "hwlab-dev",
"healthPath": "/health/live",
"profile": "dev",
"replicas": 1,
"env": {
"HWLAB_ROUTER_MODE": "edge-reachability",
"HWLAB_EDGE_PROXY_SERVICE": "hwlab-edge-proxy"
}
},
{
"serviceId": "hwlab-tunnel-client",
"image": "ghcr.io/pikastech/hwlab-tunnel-client:24eb3bf",
"namespace": "hwlab-dev",
"healthPath": "/health/live",
"profile": "dev",
"replicas": 1,
"env": {
"HWLAB_TUNNEL_MODE": "frp-client",
"HWLAB_FRP_SERVER_ADDR": "74.48.78.17",
"HWLAB_FRP_PUBLIC_PORT": "6667"
}
},
{
"serviceId": "hwlab-edge-proxy",
"image": "ghcr.io/pikastech/hwlab-edge-proxy:24eb3bf",
"namespace": "hwlab-dev",
"healthPath": "/health/live",
"profile": "dev",
"replicas": 1,
"env": {
"HWLAB_EDGE_LISTEN": "0.0.0.0:6667",
"HWLAB_EDGE_UPSTREAM": "http://hwlab-cloud-api.hwlab-dev.svc.cluster.local:6667"
}
},
{
"serviceId": "hwlab-cli",
"image": "ghcr.io/pikastech/hwlab-cli:24eb3bf",
"namespace": "hwlab-dev",
"healthPath": "/health/live",
"profile": "dev",
"replicas": 0,
"env": {
"HWLAB_CLI_ENDPOINT": "http://74.48.78.17:6667"
}
},
{
"serviceId": "hwlab-agent-skills",
"image": "hwlab-agent-skills:6509a35",
"image": "ghcr.io/pikastech/hwlab-agent-skills:24eb3bf",
"namespace": "hwlab-dev",
"healthPath": "/health",
"healthPath": "/health/live",
"profile": "dev",
"replicas": 1,
"env": {
"HWLAB_SKILLS_COMMIT_ID": "6509a35"
"HWLAB_SKILLS_COMMIT_ID": "24eb3bf"
}
}
]
],
"createdAt": "2026-05-21T00:00:00Z"
}
+11
View File
@@ -0,0 +1,11 @@
# FRP DEV Contract
The DEV reverse link is D601 to master edge through frp.
- Public DEV endpoint: `http://74.48.78.17:6667`
- `hwlab-tunnel-client` owns the frp client health contract.
- `hwlab-edge-proxy` owns public HTTP ingress on port `6667`.
- No secret values are stored in this repository. Operators must provide auth
material out of band before a real deployment.
- UniDesk backend, provider-gateway, and microservice proxy are not HWLAB runtime
substitutes.
+17
View File
@@ -0,0 +1,17 @@
serverAddr = "74.48.78.17"
serverPort = 7000
loginFailExit = true
[[proxies]]
name = "hwlab-dev-edge-proxy"
type = "tcp"
localIP = "hwlab-edge-proxy.hwlab-dev.svc.cluster.local"
localPort = 6667
remotePort = 6667
[[proxies]]
name = "hwlab-dev-tunnel-health"
type = "tcp"
localIP = "hwlab-tunnel-client.hwlab-dev.svc.cluster.local"
localPort = 7402
remotePort = 7402
+10
View File
@@ -0,0 +1,10 @@
bindPort = 7000
vhostHTTPPort = 6667
[[allowPorts]]
start = 6667
end = 6667
[[allowPorts]]
start = 7402
end = 7402
+13
View File
@@ -0,0 +1,13 @@
{
"apiVersion": "kustomize.config.k8s.io/v1beta1",
"kind": "Kustomization",
"resources": [
"namespace.yaml",
"services.yaml",
"workloads.yaml"
],
"commonLabels": {
"app.kubernetes.io/part-of": "hwlab",
"hwlab.pikastech.local/environment": "dev"
}
}
+11
View File
@@ -0,0 +1,11 @@
{
"apiVersion": "v1",
"kind": "Namespace",
"metadata": {
"name": "hwlab-dev",
"labels": {
"app.kubernetes.io/part-of": "hwlab",
"hwlab.pikastech.local/profile": "dev"
}
}
}
+308
View File
@@ -0,0 +1,308 @@
{
"apiVersion": "v1",
"kind": "List",
"items": [
{
"apiVersion": "v1",
"kind": "Service",
"metadata": {
"name": "hwlab-cloud-api",
"namespace": "hwlab-dev",
"labels": {
"app.kubernetes.io/name": "hwlab-cloud-api",
"hwlab.pikastech.local/service-id": "hwlab-cloud-api"
}
},
"spec": {
"type": "ClusterIP",
"selector": {
"app.kubernetes.io/name": "hwlab-cloud-api"
},
"ports": [
{
"name": "http",
"port": 6667,
"targetPort": "http"
}
]
}
},
{
"apiVersion": "v1",
"kind": "Service",
"metadata": {
"name": "hwlab-cloud-web",
"namespace": "hwlab-dev",
"labels": {
"app.kubernetes.io/name": "hwlab-cloud-web",
"hwlab.pikastech.local/service-id": "hwlab-cloud-web"
}
},
"spec": {
"type": "ClusterIP",
"selector": {
"app.kubernetes.io/name": "hwlab-cloud-web"
},
"ports": [
{
"name": "http",
"port": 8080,
"targetPort": "http"
}
]
}
},
{
"apiVersion": "v1",
"kind": "Service",
"metadata": {
"name": "hwlab-gateway",
"namespace": "hwlab-dev",
"labels": {
"app.kubernetes.io/name": "hwlab-gateway",
"hwlab.pikastech.local/service-id": "hwlab-gateway",
"hwlab.pikastech.local/activation": "manual"
}
},
"spec": {
"type": "ClusterIP",
"selector": {
"app.kubernetes.io/name": "hwlab-gateway"
},
"ports": [
{
"name": "http",
"port": 7001,
"targetPort": "http"
}
]
}
},
{
"apiVersion": "v1",
"kind": "Service",
"metadata": {
"name": "hwlab-cli",
"namespace": "hwlab-dev",
"labels": {
"app.kubernetes.io/name": "hwlab-cli",
"hwlab.pikastech.local/service-id": "hwlab-cli",
"hwlab.pikastech.local/activation": "manual"
}
},
"spec": {
"type": "ClusterIP",
"selector": {
"app.kubernetes.io/name": "hwlab-cli"
},
"ports": [
{
"name": "http",
"port": 7501,
"targetPort": "http"
}
]
}
},
{
"apiVersion": "v1",
"kind": "Service",
"metadata": {
"name": "hwlab-agent-skills",
"namespace": "hwlab-dev",
"labels": {
"app.kubernetes.io/name": "hwlab-agent-skills",
"hwlab.pikastech.local/service-id": "hwlab-agent-skills"
}
},
"spec": {
"type": "ClusterIP",
"selector": {
"app.kubernetes.io/name": "hwlab-agent-skills"
},
"ports": [
{
"name": "http",
"port": 7502,
"targetPort": "http"
}
]
}
},
{
"apiVersion": "v1",
"kind": "Service",
"metadata": {
"name": "hwlab-agent-mgr",
"namespace": "hwlab-dev",
"labels": {
"app.kubernetes.io/name": "hwlab-agent-mgr",
"hwlab.pikastech.local/service-id": "hwlab-agent-mgr"
}
},
"spec": {
"type": "ClusterIP",
"selector": {
"app.kubernetes.io/name": "hwlab-agent-mgr"
},
"ports": [
{
"name": "http",
"port": 7410,
"targetPort": "http"
}
]
}
},
{
"apiVersion": "v1",
"kind": "Service",
"metadata": {
"name": "hwlab-gateway-simu",
"namespace": "hwlab-dev",
"labels": {
"app.kubernetes.io/name": "hwlab-gateway-simu",
"hwlab.pikastech.local/service-id": "hwlab-gateway-simu"
}
},
"spec": {
"type": "ClusterIP",
"selector": {
"app.kubernetes.io/name": "hwlab-gateway-simu"
},
"ports": [
{
"name": "http",
"port": 7101,
"targetPort": "http"
}
]
}
},
{
"apiVersion": "v1",
"kind": "Service",
"metadata": {
"name": "hwlab-box-simu",
"namespace": "hwlab-dev",
"labels": {
"app.kubernetes.io/name": "hwlab-box-simu",
"hwlab.pikastech.local/service-id": "hwlab-box-simu"
}
},
"spec": {
"type": "ClusterIP",
"selector": {
"app.kubernetes.io/name": "hwlab-box-simu"
},
"ports": [
{
"name": "http",
"port": 7201,
"targetPort": "http"
}
]
}
},
{
"apiVersion": "v1",
"kind": "Service",
"metadata": {
"name": "hwlab-patch-panel",
"namespace": "hwlab-dev",
"labels": {
"app.kubernetes.io/name": "hwlab-patch-panel",
"hwlab.pikastech.local/service-id": "hwlab-patch-panel"
}
},
"spec": {
"type": "ClusterIP",
"selector": {
"app.kubernetes.io/name": "hwlab-patch-panel"
},
"ports": [
{
"name": "http",
"port": 7301,
"targetPort": "http"
}
]
}
},
{
"apiVersion": "v1",
"kind": "Service",
"metadata": {
"name": "hwlab-router",
"namespace": "hwlab-dev",
"labels": {
"app.kubernetes.io/name": "hwlab-router",
"hwlab.pikastech.local/service-id": "hwlab-router"
}
},
"spec": {
"type": "ClusterIP",
"selector": {
"app.kubernetes.io/name": "hwlab-router"
},
"ports": [
{
"name": "http",
"port": 7401,
"targetPort": "http"
}
]
}
},
{
"apiVersion": "v1",
"kind": "Service",
"metadata": {
"name": "hwlab-tunnel-client",
"namespace": "hwlab-dev",
"labels": {
"app.kubernetes.io/name": "hwlab-tunnel-client",
"hwlab.pikastech.local/service-id": "hwlab-tunnel-client"
}
},
"spec": {
"type": "ClusterIP",
"selector": {
"app.kubernetes.io/name": "hwlab-tunnel-client"
},
"ports": [
{
"name": "http",
"port": 7402,
"targetPort": "http"
}
]
}
},
{
"apiVersion": "v1",
"kind": "Service",
"metadata": {
"name": "hwlab-edge-proxy",
"namespace": "hwlab-dev",
"labels": {
"app.kubernetes.io/name": "hwlab-edge-proxy",
"hwlab.pikastech.local/service-id": "hwlab-edge-proxy"
}
},
"spec": {
"type": "ClusterIP",
"selector": {
"app.kubernetes.io/name": "hwlab-edge-proxy"
},
"ports": [
{
"name": "http",
"port": 6667,
"targetPort": "http"
}
]
}
}
]
}
+758
View File
@@ -0,0 +1,758 @@
{
"apiVersion": "v1",
"kind": "List",
"items": [
{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": {
"name": "hwlab-cloud-api",
"namespace": "hwlab-dev",
"labels": {
"app.kubernetes.io/name": "hwlab-cloud-api",
"hwlab.pikastech.local/service-id": "hwlab-cloud-api"
}
},
"spec": {
"replicas": 1,
"selector": {
"matchLabels": {
"app.kubernetes.io/name": "hwlab-cloud-api"
}
},
"template": {
"metadata": {
"labels": {
"app.kubernetes.io/name": "hwlab-cloud-api",
"hwlab.pikastech.local/service-id": "hwlab-cloud-api"
}
},
"spec": {
"containers": [
{
"name": "hwlab-cloud-api",
"image": "ghcr.io/pikastech/hwlab-cloud-api:24eb3bf",
"ports": [
{
"name": "http",
"containerPort": 6667
}
],
"env": [
{
"name": "HWLAB_ENVIRONMENT",
"value": "dev"
},
{
"name": "HWLAB_PUBLIC_ENDPOINT",
"value": "http://74.48.78.17:6667"
},
{
"name": "HWLAB_RUNTIME_SUBSTITUTE_FORBIDDEN",
"value": "unidesk-backend,provider-gateway,microservice-proxy"
}
],
"readinessProbe": {
"httpGet": {
"path": "/health/live",
"port": "http"
}
},
"livenessProbe": {
"httpGet": {
"path": "/health/live",
"port": "http"
}
}
}
]
}
}
}
},
{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": {
"name": "hwlab-cloud-web",
"namespace": "hwlab-dev",
"labels": {
"app.kubernetes.io/name": "hwlab-cloud-web",
"hwlab.pikastech.local/service-id": "hwlab-cloud-web"
}
},
"spec": {
"replicas": 1,
"selector": {
"matchLabels": {
"app.kubernetes.io/name": "hwlab-cloud-web"
}
},
"template": {
"metadata": {
"labels": {
"app.kubernetes.io/name": "hwlab-cloud-web",
"hwlab.pikastech.local/service-id": "hwlab-cloud-web"
}
},
"spec": {
"containers": [
{
"name": "hwlab-cloud-web",
"image": "ghcr.io/pikastech/hwlab-cloud-web:24eb3bf",
"ports": [
{
"name": "http",
"containerPort": 8080
}
],
"env": [
{
"name": "HWLAB_API_BASE_URL",
"value": "http://hwlab-cloud-api.hwlab-dev.svc.cluster.local:6667"
}
],
"readinessProbe": {
"httpGet": {
"path": "/health/live",
"port": "http"
}
},
"livenessProbe": {
"httpGet": {
"path": "/health/live",
"port": "http"
}
}
}
]
}
}
}
},
{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": {
"name": "hwlab-agent-mgr",
"namespace": "hwlab-dev",
"labels": {
"app.kubernetes.io/name": "hwlab-agent-mgr",
"hwlab.pikastech.local/service-id": "hwlab-agent-mgr"
}
},
"spec": {
"replicas": 1,
"selector": {
"matchLabels": {
"app.kubernetes.io/name": "hwlab-agent-mgr"
}
},
"template": {
"metadata": {
"labels": {
"app.kubernetes.io/name": "hwlab-agent-mgr",
"hwlab.pikastech.local/service-id": "hwlab-agent-mgr"
}
},
"spec": {
"containers": [
{
"name": "hwlab-agent-mgr",
"image": "ghcr.io/pikastech/hwlab-agent-mgr:24eb3bf",
"ports": [
{
"name": "http",
"containerPort": 7410
}
],
"env": [
{
"name": "HWLAB_AGENT_SESSION_MODE",
"value": "control-plane"
}
],
"readinessProbe": {
"httpGet": {
"path": "/health/live",
"port": "http"
}
},
"livenessProbe": {
"httpGet": {
"path": "/health/live",
"port": "http"
}
}
}
]
}
}
}
},
{
"apiVersion": "batch/v1",
"kind": "Job",
"metadata": {
"name": "hwlab-agent-worker-template",
"namespace": "hwlab-dev",
"labels": {
"app.kubernetes.io/name": "hwlab-agent-worker",
"hwlab.pikastech.local/service-id": "hwlab-agent-worker"
}
},
"spec": {
"suspend": true,
"template": {
"metadata": {
"labels": {
"app.kubernetes.io/name": "hwlab-agent-worker",
"hwlab.pikastech.local/service-id": "hwlab-agent-worker"
}
},
"spec": {
"restartPolicy": "Never",
"containers": [
{
"name": "hwlab-agent-worker",
"image": "ghcr.io/pikastech/hwlab-agent-worker:24eb3bf",
"env": [
{
"name": "HWLAB_AGENT_SESSION_MODE",
"value": "session-scoped"
}
]
}
]
}
}
}
},
{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": {
"name": "hwlab-gateway",
"namespace": "hwlab-dev",
"labels": {
"app.kubernetes.io/name": "hwlab-gateway",
"hwlab.pikastech.local/service-id": "hwlab-gateway",
"hwlab.pikastech.local/activation": "manual"
}
},
"spec": {
"replicas": 0,
"selector": {
"matchLabels": {
"app.kubernetes.io/name": "hwlab-gateway"
}
},
"template": {
"metadata": {
"labels": {
"app.kubernetes.io/name": "hwlab-gateway",
"hwlab.pikastech.local/service-id": "hwlab-gateway"
}
},
"spec": {
"containers": [
{
"name": "hwlab-gateway",
"image": "ghcr.io/pikastech/hwlab-gateway:24eb3bf",
"ports": [
{
"name": "http",
"containerPort": 7001
}
],
"env": [
{
"name": "HWLAB_GATEWAY_MODE",
"value": "hardware-boundary"
}
],
"readinessProbe": {
"httpGet": {
"path": "/health/live",
"port": "http"
}
},
"livenessProbe": {
"httpGet": {
"path": "/health/live",
"port": "http"
}
}
}
]
}
}
}
},
{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": {
"name": "hwlab-gateway-simu",
"namespace": "hwlab-dev",
"labels": {
"app.kubernetes.io/name": "hwlab-gateway-simu",
"hwlab.pikastech.local/service-id": "hwlab-gateway-simu"
}
},
"spec": {
"replicas": 1,
"selector": {
"matchLabels": {
"app.kubernetes.io/name": "hwlab-gateway-simu"
}
},
"template": {
"metadata": {
"labels": {
"app.kubernetes.io/name": "hwlab-gateway-simu",
"hwlab.pikastech.local/service-id": "hwlab-gateway-simu"
}
},
"spec": {
"containers": [
{
"name": "hwlab-gateway-simu",
"image": "ghcr.io/pikastech/hwlab-gateway-simu:24eb3bf",
"ports": [
{
"name": "http",
"containerPort": 7101
}
],
"env": [
{
"name": "HWLAB_BOX_RESOURCES",
"value": "res_boxsim_alpha"
}
],
"readinessProbe": {
"httpGet": {
"path": "/health/live",
"port": "http"
}
},
"livenessProbe": {
"httpGet": {
"path": "/health/live",
"port": "http"
}
}
}
]
}
}
}
},
{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": {
"name": "hwlab-box-simu",
"namespace": "hwlab-dev",
"labels": {
"app.kubernetes.io/name": "hwlab-box-simu",
"hwlab.pikastech.local/service-id": "hwlab-box-simu"
}
},
"spec": {
"replicas": 1,
"selector": {
"matchLabels": {
"app.kubernetes.io/name": "hwlab-box-simu"
}
},
"template": {
"metadata": {
"labels": {
"app.kubernetes.io/name": "hwlab-box-simu",
"hwlab.pikastech.local/service-id": "hwlab-box-simu"
}
},
"spec": {
"containers": [
{
"name": "hwlab-box-simu",
"image": "ghcr.io/pikastech/hwlab-box-simu:24eb3bf",
"ports": [
{
"name": "http",
"containerPort": 7201
}
],
"env": [
{
"name": "HWLAB_BOX_ID",
"value": "boxsim_alpha"
}
],
"readinessProbe": {
"httpGet": {
"path": "/health/live",
"port": "http"
}
},
"livenessProbe": {
"httpGet": {
"path": "/health/live",
"port": "http"
}
}
}
]
}
}
}
},
{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": {
"name": "hwlab-patch-panel",
"namespace": "hwlab-dev",
"labels": {
"app.kubernetes.io/name": "hwlab-patch-panel",
"hwlab.pikastech.local/service-id": "hwlab-patch-panel"
}
},
"spec": {
"replicas": 1,
"selector": {
"matchLabels": {
"app.kubernetes.io/name": "hwlab-patch-panel"
}
},
"template": {
"metadata": {
"labels": {
"app.kubernetes.io/name": "hwlab-patch-panel",
"hwlab.pikastech.local/service-id": "hwlab-patch-panel"
}
},
"spec": {
"containers": [
{
"name": "hwlab-patch-panel",
"image": "ghcr.io/pikastech/hwlab-patch-panel:24eb3bf",
"ports": [
{
"name": "http",
"containerPort": 7301
}
],
"readinessProbe": {
"httpGet": {
"path": "/health/live",
"port": "http"
}
},
"livenessProbe": {
"httpGet": {
"path": "/health/live",
"port": "http"
}
}
}
]
}
}
}
},
{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": {
"name": "hwlab-router",
"namespace": "hwlab-dev",
"labels": {
"app.kubernetes.io/name": "hwlab-router",
"hwlab.pikastech.local/service-id": "hwlab-router"
}
},
"spec": {
"replicas": 1,
"selector": {
"matchLabels": {
"app.kubernetes.io/name": "hwlab-router"
}
},
"template": {
"metadata": {
"labels": {
"app.kubernetes.io/name": "hwlab-router",
"hwlab.pikastech.local/service-id": "hwlab-router"
}
},
"spec": {
"containers": [
{
"name": "hwlab-router",
"image": "ghcr.io/pikastech/hwlab-router:24eb3bf",
"ports": [
{
"name": "http",
"containerPort": 7401
}
],
"env": [
{
"name": "HWLAB_EDGE_PROXY_SERVICE",
"value": "hwlab-edge-proxy"
}
],
"readinessProbe": {
"httpGet": {
"path": "/health/live",
"port": "http"
}
},
"livenessProbe": {
"httpGet": {
"path": "/health/live",
"port": "http"
}
}
}
]
}
}
}
},
{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": {
"name": "hwlab-tunnel-client",
"namespace": "hwlab-dev",
"labels": {
"app.kubernetes.io/name": "hwlab-tunnel-client",
"hwlab.pikastech.local/service-id": "hwlab-tunnel-client"
}
},
"spec": {
"replicas": 1,
"selector": {
"matchLabels": {
"app.kubernetes.io/name": "hwlab-tunnel-client"
}
},
"template": {
"metadata": {
"labels": {
"app.kubernetes.io/name": "hwlab-tunnel-client",
"hwlab.pikastech.local/service-id": "hwlab-tunnel-client"
}
},
"spec": {
"containers": [
{
"name": "hwlab-tunnel-client",
"image": "ghcr.io/pikastech/hwlab-tunnel-client:24eb3bf",
"ports": [
{
"name": "http",
"containerPort": 7402
}
],
"env": [
{
"name": "HWLAB_TUNNEL_MODE",
"value": "frp-client"
},
{
"name": "HWLAB_FRP_SERVER_ADDR",
"value": "74.48.78.17"
},
{
"name": "HWLAB_FRP_PUBLIC_PORT",
"value": "6667"
}
],
"readinessProbe": {
"httpGet": {
"path": "/health/live",
"port": "http"
}
},
"livenessProbe": {
"httpGet": {
"path": "/health/live",
"port": "http"
}
}
}
]
}
}
}
},
{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": {
"name": "hwlab-edge-proxy",
"namespace": "hwlab-dev",
"labels": {
"app.kubernetes.io/name": "hwlab-edge-proxy",
"hwlab.pikastech.local/service-id": "hwlab-edge-proxy"
}
},
"spec": {
"replicas": 1,
"selector": {
"matchLabels": {
"app.kubernetes.io/name": "hwlab-edge-proxy"
}
},
"template": {
"metadata": {
"labels": {
"app.kubernetes.io/name": "hwlab-edge-proxy",
"hwlab.pikastech.local/service-id": "hwlab-edge-proxy"
}
},
"spec": {
"containers": [
{
"name": "hwlab-edge-proxy",
"image": "ghcr.io/pikastech/hwlab-edge-proxy:24eb3bf",
"ports": [
{
"name": "http",
"containerPort": 6667
}
],
"env": [
{
"name": "HWLAB_EDGE_LISTEN",
"value": "0.0.0.0:6667"
},
{
"name": "HWLAB_EDGE_UPSTREAM",
"value": "http://hwlab-cloud-api.hwlab-dev.svc.cluster.local:6667"
}
],
"readinessProbe": {
"httpGet": {
"path": "/health/live",
"port": "http"
}
},
"livenessProbe": {
"httpGet": {
"path": "/health/live",
"port": "http"
}
}
}
]
}
}
}
},
{
"apiVersion": "batch/v1",
"kind": "Job",
"metadata": {
"name": "hwlab-cli-template",
"namespace": "hwlab-dev",
"labels": {
"app.kubernetes.io/name": "hwlab-cli",
"hwlab.pikastech.local/service-id": "hwlab-cli",
"hwlab.pikastech.local/activation": "manual"
}
},
"spec": {
"suspend": true,
"template": {
"metadata": {
"labels": {
"app.kubernetes.io/name": "hwlab-cli",
"hwlab.pikastech.local/service-id": "hwlab-cli"
}
},
"spec": {
"restartPolicy": "Never",
"containers": [
{
"name": "hwlab-cli",
"image": "ghcr.io/pikastech/hwlab-cli:24eb3bf",
"env": [
{
"name": "HWLAB_CLI_ENDPOINT",
"value": "http://74.48.78.17:6667"
}
]
}
]
}
}
}
},
{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": {
"name": "hwlab-agent-skills",
"namespace": "hwlab-dev",
"labels": {
"app.kubernetes.io/name": "hwlab-agent-skills",
"hwlab.pikastech.local/service-id": "hwlab-agent-skills"
}
},
"spec": {
"replicas": 1,
"selector": {
"matchLabels": {
"app.kubernetes.io/name": "hwlab-agent-skills"
}
},
"template": {
"metadata": {
"labels": {
"app.kubernetes.io/name": "hwlab-agent-skills",
"hwlab.pikastech.local/service-id": "hwlab-agent-skills"
}
},
"spec": {
"containers": [
{
"name": "hwlab-agent-skills",
"image": "ghcr.io/pikastech/hwlab-agent-skills:24eb3bf",
"ports": [
{
"name": "http",
"containerPort": 7502
}
],
"env": [
{
"name": "HWLAB_SKILLS_COMMIT_ID",
"value": "24eb3bf"
}
],
"readinessProbe": {
"httpGet": {
"path": "/health/live",
"port": "http"
}
},
"livenessProbe": {
"httpGet": {
"path": "/health/live",
"port": "http"
}
}
}
]
}
}
}
}
]
}
+24
View File
@@ -0,0 +1,24 @@
{
"apiVersion": "v1",
"kind": "ConfigMap",
"metadata": {
"name": "hwlab-dev-health-contract",
"namespace": "hwlab-dev",
"labels": {
"app.kubernetes.io/name": "hwlab-dev-health-contract",
"hwlab.pikastech.local/profile": "dev"
}
},
"data": {
"endpoint": "http://74.48.78.17:6667",
"cloud-api": "GET /health/live via hwlab-edge-proxy then hwlab-cloud-api:6667",
"cloud-web": "GET /health/live on hwlab-cloud-web:8080; consumes cloud-api only",
"agent": "hwlab-agent-mgr readiness gates worker template creation; hwlab-agent-worker is suspended until a session is scheduled",
"sim": "hwlab-gateway-simu:7101 and hwlab-box-simu:7201 expose /health/live for DEV smoke",
"patch-panel": "hwlab-patch-panel:7301 exposes /health/live and owns patch panel state",
"router": "hwlab-router:7401 exposes /health/live and owns edge reachability routing",
"tunnel-client": "hwlab-tunnel-client:7402 exposes /health/live and owns D601-to-master frp client state",
"edge-proxy": "hwlab-edge-proxy:6667 exposes /health/live and proxies DEV endpoint traffic to hwlab-cloud-api",
"runtime-substitute-policy": "Do not replace HWLAB runtime with UniDesk backend, provider-gateway, or microservice proxy"
}
}
+12
View File
@@ -0,0 +1,12 @@
{
"apiVersion": "kustomize.config.k8s.io/v1beta1",
"kind": "Kustomization",
"namespace": "hwlab-dev",
"resources": [
"../base",
"health-contract.yaml"
],
"commonLabels": {
"hwlab.pikastech.local/profile": "dev"
}
}
+7
View File
@@ -0,0 +1,7 @@
{
"apiVersion": "kustomize.config.k8s.io/v1beta1",
"kind": "Kustomization",
"resources": [
"prod-disabled.yaml"
]
}
+18
View File
@@ -0,0 +1,18 @@
{
"apiVersion": "v1",
"kind": "ConfigMap",
"metadata": {
"name": "hwlab-prod-disabled",
"namespace": "default",
"labels": {
"app.kubernetes.io/part-of": "hwlab",
"hwlab.pikastech.local/profile": "prod",
"hwlab.pikastech.local/acceptance": "disabled"
}
},
"data": {
"status": "disabled",
"reason": "PROD deployment and acceptance are out of scope for MVP L5",
"allowed-use": "placeholder gate only"
}
}
+22
View File
@@ -0,0 +1,22 @@
# Master Edge DEV Contract
The master edge exposes only the DEV acceptance endpoint for this skeleton:
```text
http://74.48.78.17:6667
```
Health ownership:
- `hwlab-edge-proxy`: accepts public DEV traffic and exposes `/health/live`.
- `hwlab-router`: owns edge reachability routing and exposes `/health/live`.
- `hwlab-tunnel-client`: owns D601-to-master frp client status and exposes
`/health/live`.
- `hwlab-cloud-api`: receives proxied API traffic and exposes `/health/live`.
- `hwlab-cloud-web`: reads cloud APIs only; it does not control hardware.
- `hwlab-agent-mgr` and `hwlab-agent-worker`: own agent session and worker
session health boundaries.
- `hwlab-gateway-simu`, `hwlab-box-simu`, and `hwlab-patch-panel`: own DEV
simulator and patch-panel health boundaries.
PROD is intentionally gated off for this task.
+70
View File
@@ -0,0 +1,70 @@
{
"environment": "dev",
"endpoint": "http://74.48.78.17:6667",
"reverseLink": {
"mode": "frp",
"direction": "d601-to-master",
"client": "hwlab-tunnel-client",
"serverAddress": "74.48.78.17",
"publicPort": 6667
},
"contracts": [
{
"serviceId": "hwlab-edge-proxy",
"owner": "public DEV ingress",
"health": "GET /health/live",
"upstream": "hwlab-cloud-api"
},
{
"serviceId": "hwlab-router",
"owner": "edge reachability routing",
"health": "GET /health/live"
},
{
"serviceId": "hwlab-tunnel-client",
"owner": "frp client reverse link",
"health": "GET /health/live"
},
{
"serviceId": "hwlab-cloud-api",
"owner": "DEV cloud API boundary",
"health": "GET /health/live"
},
{
"serviceId": "hwlab-cloud-web",
"owner": "web frontend boundary",
"health": "GET /health/live"
},
{
"serviceId": "hwlab-agent-mgr",
"owner": "agent session scheduling",
"health": "GET /health/live"
},
{
"serviceId": "hwlab-agent-worker",
"owner": "session-scoped worker execution",
"health": "job exit status or future GET /health/live sidecar"
},
{
"serviceId": "hwlab-gateway-simu",
"owner": "DEV gateway simulator",
"health": "GET /health/live"
},
{
"serviceId": "hwlab-box-simu",
"owner": "DEV box simulator",
"health": "GET /health/live"
},
{
"serviceId": "hwlab-patch-panel",
"owner": "patch panel state",
"health": "GET /health/live"
}
],
"forbiddenRuntimeSubstitutes": [
"unidesk-backend",
"provider-gateway",
"microservice-proxy"
],
"prodAcceptance": false
}