diff --git a/deploy/artifact-catalog.dev.json b/deploy/artifact-catalog.dev.json index 9c176a2b..6abcf71f 100644 --- a/deploy/artifact-catalog.dev.json +++ b/deploy/artifact-catalog.dev.json @@ -271,181 +271,6 @@ }, "reusedFrom": "6c97b4f8e49ba46148dde9126a21f475356bfdd4d6826326799d03d68212002e" }, - { - "serviceId": "hwlab-gateway-simu", - "commitId": "278bbe1", - "image": "127.0.0.1:5000/hwlab/hwlab-gateway-simu:278bbe1", - "imageTag": "278bbe1", - "digest": "not_published", - "publishState": "skeleton-only", - "profile": "dev", - "namespace": "hwlab-dev", - "healthPath": "/health/live", - "sourceState": "source-present", - "publishEnabled": true, - "artifactRequired": true, - "artifactScope": "required", - "notPublishedReason": "publish_not_run", - "buildCreatedAt": null, - "buildSource": null, - "componentCommitId": "a56ea7e33ef67040cc9a8748c3759b4f9c87ca46", - "componentInputHash": "184706b960dc00c23d6aacf35bde93558d422329635752cfb85796c6fe5e4820", - "dockerfileHash": "8b2595a09276479b8809e70e99516c1539a6a7cc200e73266d247176b56be962", - "baseImageReference": "127.0.0.1:5000/hwlab/hwlab-node20-base:20-bookworm-slim", - "baseImageDigest": null, - "buildArgsHash": "79c757588262d875c61a2542e37c9a849000d54d8bb58e8bf19c597114956f5f", - "ciAffected": false, - "ciReason": [ - "component-inputs-unchanged" - ], - "reuse": { - "status": "ready", - "image": "127.0.0.1:5000/hwlab/hwlab-gateway-simu:af46386", - "digest": "sha256:9b65bfff46f5fa206e7887340b9e7df2647eb4d0c186f9ad9796636551cd121b", - "reusedFrom": "184706b960dc00c23d6aacf35bde93558d422329635752cfb85796c6fe5e4820" - }, - "reusedFrom": "184706b960dc00c23d6aacf35bde93558d422329635752cfb85796c6fe5e4820" - }, - { - "serviceId": "hwlab-box-simu", - "commitId": "278bbe1", - "image": "127.0.0.1:5000/hwlab/hwlab-box-simu:278bbe1", - "imageTag": "278bbe1", - "digest": "not_published", - "publishState": "skeleton-only", - "profile": "dev", - "namespace": "hwlab-dev", - "healthPath": "/health/live", - "sourceState": "source-present", - "publishEnabled": true, - "artifactRequired": true, - "artifactScope": "required", - "notPublishedReason": "publish_not_run", - "buildCreatedAt": null, - "buildSource": null, - "componentCommitId": "a56ea7e33ef67040cc9a8748c3759b4f9c87ca46", - "componentInputHash": "1dfe5c35338d049b996a27f628d8d7b64ddacfa51de07e4c1cbd4a0f19c289bf", - "dockerfileHash": "8b2595a09276479b8809e70e99516c1539a6a7cc200e73266d247176b56be962", - "baseImageReference": "127.0.0.1:5000/hwlab/hwlab-node20-base:20-bookworm-slim", - "baseImageDigest": null, - "buildArgsHash": "2b321eec447decb8ca22b30a42dffa467405af983aa06e487b66a45c6ecbd0e9", - "ciAffected": false, - "ciReason": [ - "component-inputs-unchanged" - ], - "reuse": { - "status": "ready", - "image": "127.0.0.1:5000/hwlab/hwlab-box-simu:af46386", - "digest": "sha256:909fd838bf6fa7dc2b2eb7b2a868bde4d110aab1640272ee63dbcf6ae488b330", - "reusedFrom": "1dfe5c35338d049b996a27f628d8d7b64ddacfa51de07e4c1cbd4a0f19c289bf" - }, - "reusedFrom": "1dfe5c35338d049b996a27f628d8d7b64ddacfa51de07e4c1cbd4a0f19c289bf" - }, - { - "serviceId": "hwlab-patch-panel", - "commitId": "278bbe1", - "image": "127.0.0.1:5000/hwlab/hwlab-patch-panel:278bbe1", - "imageTag": "278bbe1", - "digest": "not_published", - "publishState": "skeleton-only", - "profile": "dev", - "namespace": "hwlab-dev", - "healthPath": "/health/live", - "sourceState": "source-present", - "publishEnabled": true, - "artifactRequired": true, - "artifactScope": "required", - "notPublishedReason": "publish_not_run", - "buildCreatedAt": null, - "buildSource": null, - "componentCommitId": "a56ea7e33ef67040cc9a8748c3759b4f9c87ca46", - "componentInputHash": "4b84d74569d7d847c886695014aa84236c678b19ceeaa7df1f80ff7aa06c00ed", - "dockerfileHash": "8b2595a09276479b8809e70e99516c1539a6a7cc200e73266d247176b56be962", - "baseImageReference": "127.0.0.1:5000/hwlab/hwlab-node20-base:20-bookworm-slim", - "baseImageDigest": null, - "buildArgsHash": "bea7ca0cf1e6f84b11a7848e3dff6dfe4aa613f1df2c51e9ab4807fffe718128", - "ciAffected": false, - "ciReason": [ - "component-inputs-unchanged" - ], - "reuse": { - "status": "ready", - "image": "127.0.0.1:5000/hwlab/hwlab-patch-panel:af46386", - "digest": "sha256:5d49ba34c8dc1e71eb5fedc769ea0759b4ab66d7665086fc773c2020fcd11a2b", - "reusedFrom": "4b84d74569d7d847c886695014aa84236c678b19ceeaa7df1f80ff7aa06c00ed" - }, - "reusedFrom": "4b84d74569d7d847c886695014aa84236c678b19ceeaa7df1f80ff7aa06c00ed" - }, - { - "serviceId": "hwlab-router", - "commitId": "278bbe1", - "image": "127.0.0.1:5000/hwlab/hwlab-router:278bbe1", - "imageTag": "278bbe1", - "digest": "not_published", - "publishState": "skeleton-only", - "profile": "dev", - "namespace": "hwlab-dev", - "healthPath": "/health/live", - "sourceState": "source-present", - "publishEnabled": true, - "artifactRequired": true, - "artifactScope": "required", - "notPublishedReason": "publish_not_run", - "buildCreatedAt": null, - "buildSource": null, - "componentCommitId": "a56ea7e33ef67040cc9a8748c3759b4f9c87ca46", - "componentInputHash": "a2e72fca1d0acb7b5db4ecf77ff5ffacae7e897e8d50920cae8b17fcb6e1e6fb", - "dockerfileHash": "8b2595a09276479b8809e70e99516c1539a6a7cc200e73266d247176b56be962", - "baseImageReference": "127.0.0.1:5000/hwlab/hwlab-node20-base:20-bookworm-slim", - "baseImageDigest": null, - "buildArgsHash": "31f0f27ef0e4375ac141f0d54c2c9449bd5dce14df0bb6469704245d1cf86b09", - "ciAffected": false, - "ciReason": [ - "component-inputs-unchanged" - ], - "reuse": { - "status": "ready", - "image": "127.0.0.1:5000/hwlab/hwlab-router:af46386", - "digest": "sha256:074539cf5a9aef2330c6dc8df96d0be76f5fbb940f8d0ad20f1d67cb1f299666", - "reusedFrom": "a2e72fca1d0acb7b5db4ecf77ff5ffacae7e897e8d50920cae8b17fcb6e1e6fb" - }, - "reusedFrom": "a2e72fca1d0acb7b5db4ecf77ff5ffacae7e897e8d50920cae8b17fcb6e1e6fb" - }, - { - "serviceId": "hwlab-tunnel-client", - "commitId": "278bbe1", - "image": "127.0.0.1:5000/hwlab/hwlab-tunnel-client:278bbe1", - "imageTag": "278bbe1", - "digest": "not_published", - "publishState": "skeleton-only", - "profile": "dev", - "namespace": "hwlab-dev", - "healthPath": "/health/live", - "sourceState": "source-present", - "publishEnabled": true, - "artifactRequired": true, - "artifactScope": "required", - "notPublishedReason": "publish_not_run", - "buildCreatedAt": null, - "buildSource": null, - "componentCommitId": "a56ea7e33ef67040cc9a8748c3759b4f9c87ca46", - "componentInputHash": "58f4fc6f1b56c6074cdeae1d33bfe22f54072ef0d45351d3186cdcf15a3f1573", - "dockerfileHash": "8b2595a09276479b8809e70e99516c1539a6a7cc200e73266d247176b56be962", - "baseImageReference": "127.0.0.1:5000/hwlab/hwlab-node20-base:20-bookworm-slim", - "baseImageDigest": null, - "buildArgsHash": "c49a07574a1d4fe74642170efcbb231c2c59436e1d3d2434c285349d23a35fcb", - "ciAffected": false, - "ciReason": [ - "component-inputs-unchanged" - ], - "reuse": { - "status": "ready", - "image": "127.0.0.1:5000/hwlab/hwlab-tunnel-client:af46386", - "digest": "sha256:f1f200009731ba832dc26258b01c3abb4de711237728a95124822e0d056c70fe", - "reusedFrom": "58f4fc6f1b56c6074cdeae1d33bfe22f54072ef0d45351d3186cdcf15a3f1573" - }, - "reusedFrom": "58f4fc6f1b56c6074cdeae1d33bfe22f54072ef0d45351d3186cdcf15a3f1573" - }, { "serviceId": "hwlab-edge-proxy", "commitId": "278bbe1", @@ -554,8 +379,8 @@ ], "serviceInventory": { "version": "v2", - "serviceCount": 14, - "requiredServiceCount": 14, + "serviceCount": 9, + "requiredServiceCount": 9, "disabledServiceCount": 0, "requiredServiceIds": [ "hwlab-cloud-api", @@ -564,11 +389,6 @@ "hwlab-agent-worker", "hwlab-device-pod", "hwlab-gateway", - "hwlab-gateway-simu", - "hwlab-box-simu", - "hwlab-patch-panel", - "hwlab-router", - "hwlab-tunnel-client", "hwlab-edge-proxy", "hwlab-cli", "hwlab-agent-skills" @@ -641,61 +461,6 @@ "entrypoint": "cmd/hwlab-gateway/main.mjs", "disabledReason": null }, - { - "serviceId": "hwlab-gateway-simu", - "publishEnabled": true, - "artifactRequired": true, - "artifactScope": "required", - "runtimeKind": "node-command", - "implementationState": "repo-entrypoint", - "sourceState": "source-present", - "entrypoint": "cmd/hwlab-gateway-simu/main.mjs", - "disabledReason": null - }, - { - "serviceId": "hwlab-box-simu", - "publishEnabled": true, - "artifactRequired": true, - "artifactScope": "required", - "runtimeKind": "node-command", - "implementationState": "repo-entrypoint", - "sourceState": "source-present", - "entrypoint": "cmd/hwlab-box-simu/main.mjs", - "disabledReason": null - }, - { - "serviceId": "hwlab-patch-panel", - "publishEnabled": true, - "artifactRequired": true, - "artifactScope": "required", - "runtimeKind": "node-command", - "implementationState": "repo-entrypoint", - "sourceState": "source-present", - "entrypoint": "cmd/hwlab-patch-panel/main.mjs", - "disabledReason": null - }, - { - "serviceId": "hwlab-router", - "publishEnabled": true, - "artifactRequired": true, - "artifactScope": "required", - "runtimeKind": "node-command", - "implementationState": "repo-entrypoint", - "sourceState": "source-present", - "entrypoint": "cmd/hwlab-router/main.mjs", - "disabledReason": null - }, - { - "serviceId": "hwlab-tunnel-client", - "publishEnabled": true, - "artifactRequired": true, - "artifactScope": "required", - "runtimeKind": "node-command", - "implementationState": "repo-entrypoint", - "sourceState": "source-present", - "entrypoint": "cmd/hwlab-tunnel-client/main.mjs", - "disabledReason": null - }, { "serviceId": "hwlab-edge-proxy", "publishEnabled": true, diff --git a/deploy/deploy.json b/deploy/deploy.json index 03f67e46..5610f965 100644 --- a/deploy/deploy.json +++ b/deploy/deploy.json @@ -49,14 +49,6 @@ "localHost": "hwlab-edge-proxy.hwlab-dev.svc.cluster.local", "localPort": 6667, "remotePort": 16667 - }, - { - "name": "hwlab-dev-tunnel-health", - "type": "tcp", - "localServiceId": "hwlab-tunnel-client", - "localHost": "hwlab-tunnel-client.hwlab-dev.svc.cluster.local", - "localPort": 7402, - "remotePort": 7402 } ] }, @@ -111,55 +103,6 @@ "port": 7601, "targetPort": "http" }, - { - "serviceId": "hwlab-gateway-simu", - "name": "hwlab-gateway-simu-1", - "namespace": "hwlab-dev", - "port": 7101, - "targetPort": "http" - }, - { - "serviceId": "hwlab-box-simu", - "name": "hwlab-box-simu-1", - "namespace": "hwlab-dev", - "port": 7201, - "targetPort": "http" - }, - { - "serviceId": "hwlab-gateway-simu", - "name": "hwlab-gateway-simu-2", - "namespace": "hwlab-dev", - "port": 7101, - "targetPort": "http" - }, - { - "serviceId": "hwlab-box-simu", - "name": "hwlab-box-simu-2", - "namespace": "hwlab-dev", - "port": 7201, - "targetPort": "http" - }, - { - "serviceId": "hwlab-patch-panel", - "name": "hwlab-patch-panel", - "namespace": "hwlab-dev", - "port": 7301, - "targetPort": "http" - }, - { - "serviceId": "hwlab-router", - "name": "hwlab-router", - "namespace": "hwlab-dev", - "port": 7401, - "targetPort": "http" - }, - { - "serviceId": "hwlab-tunnel-client", - "name": "hwlab-tunnel-client", - "namespace": "hwlab-dev", - "port": 7402, - "targetPort": "http" - }, { "serviceId": "hwlab-edge-proxy", "name": "hwlab-edge-proxy", @@ -231,15 +174,11 @@ "HWLAB_CLOUD_DB_CONTRACT": "dev-redacted-presence-only", "HWLAB_CLOUD_RUNTIME_ADAPTER": "postgres", "HWLAB_CLOUD_RUNTIME_DURABLE": "true", - "HWLAB_M3_IO_CONTROL_ENABLED": "true", - "HWLAB_M3_GATEWAY_SIMU_1_URL": "http://hwlab-gateway-simu-1.hwlab-dev.svc.cluster.local:7101", - "HWLAB_M3_GATEWAY_SIMU_2_URL": "http://hwlab-gateway-simu-2.hwlab-dev.svc.cluster.local:7101", - "HWLAB_M3_PATCH_PANEL_URL": "http://hwlab-patch-panel.hwlab-dev.svc.cluster.local:7301", + "HWLAB_M3_IO_CONTROL_ENABLED": "false", "HWLAB_CODE_AGENT_PROVIDER": "codex-stdio", "HWLAB_CODE_AGENT_MODEL": "gpt-5.5", "HWLAB_CODE_AGENT_TIMEOUT_MS": "1200000", "HWLAB_CODE_AGENT_OPENAI_BASE_URL": "http://127.0.0.1:49280/responses", - "HWLAB_CODE_AGENT_HWLAB_API_BASE_URL": "http://hwlab-cloud-api.hwlab-dev.svc.cluster.local:6667", "HWLAB_CODE_AGENT_CODEX_STDIO_ENABLED": "1", "HWLAB_CODE_AGENT_CODEX_STDIO_SUPERVISOR": "repo-owned", "HWLAB_CODE_AGENT_WORKSPACE": "/workspace/hwlab", @@ -319,87 +258,6 @@ "HWLAB_ENVIRONMENT": "dev" } }, - { - "serviceId": "hwlab-gateway-simu", - "namespace": "hwlab-dev", - "healthPath": "/health/live", - "profile": "dev", - "replicas": 2, - "instanceNames": [ - "hwlab-gateway-simu-1", - "hwlab-gateway-simu-2" - ], - "identityStrategy": "indexed-workloads", - "env": { - "HWLAB_GATEWAY_MODE": "simulator", - "HWLAB_GATEWAY_ID": "gwsimu_1,gwsimu_2", - "HWLAB_BOX_IDS": "boxsimu_1,boxsimu_2", - "HWLAB_BOX_RESOURCES": "res_boxsimu_1,res_boxsimu_2", - "HWLAB_BOX_URLS": "http://hwlab-box-simu-1.hwlab-dev.svc.cluster.local:7201,http://hwlab-box-simu-2.hwlab-dev.svc.cluster.local:7201" - } - }, - { - "serviceId": "hwlab-box-simu", - "namespace": "hwlab-dev", - "healthPath": "/health/live", - "profile": "dev", - "replicas": 2, - "instanceNames": [ - "hwlab-box-simu-1", - "hwlab-box-simu-2" - ], - "identityStrategy": "indexed-workloads", - "env": { - "HWLAB_BOX_ID": "boxsimu_1,boxsimu_2", - "HWLAB_BOX_RESOURCE_ID": "res_boxsimu_1,res_boxsimu_2", - "HWLAB_GATEWAY_SESSION_ID": "gws_gwsimu_1,gws_gwsimu_2", - "HWLAB_ENVIRONMENT": "dev" - } - }, - { - "serviceId": "hwlab-patch-panel", - "namespace": "hwlab-dev", - "healthPath": "/health/live", - "profile": "dev", - "replicas": 1, - "m3Route": { - "fromResourceId": "res_boxsimu_1", - "fromPort": "DO1", - "patchPanelServiceId": "hwlab-patch-panel", - "toResourceId": "res_boxsimu_2", - "toPort": "DI1" - }, - "env": { - "HWLAB_PATCH_PANEL_MODE": "dev-skeleton", - "HWLAB_PATCH_PANEL_ENDPOINT_MAP": "{\"res_boxsimu_2\":\"http://hwlab-box-simu-2.hwlab-dev.svc.cluster.local:7201\"}", - "HWLAB_PATCH_PANEL_WIRING_CONFIG": "{\"wiringConfigId\":\"wir_m3_do1_di1\",\"projectId\":\"prj_m3_hardware_loop\",\"gatewaySessionId\":\"gws_gwsimu_1\",\"name\":\"M3 simulated DO1 to DI1 patch wiring\",\"status\":\"active\",\"connections\":[{\"from\":{\"resourceId\":\"res_boxsimu_1\",\"port\":\"DO1\"},\"to\":{\"resourceId\":\"res_boxsimu_2\",\"port\":\"DI1\"},\"mode\":\"exclusive\"}],\"constraints\":{\"propagation\":\"patch-panel-only\",\"localLoopbackSubstituteAllowed\":false},\"createdAt\":\"2026-05-21T00:00:00.000Z\",\"updatedAt\":\"2026-05-21T00:00:00.000Z\"}", - "HWLAB_ENVIRONMENT": "dev" - } - }, - { - "serviceId": "hwlab-router", - "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", - "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": "16667", - "HWLAB_FRP_WEB_PUBLIC_PORT": "16666" - } - }, { "serviceId": "hwlab-edge-proxy", "namespace": "hwlab-dev", diff --git a/deploy/deploy.schema.json b/deploy/deploy.schema.json index 1d632a7b..74b4c097 100644 --- a/deploy/deploy.schema.json +++ b/deploy/deploy.schema.json @@ -71,11 +71,6 @@ "hwlab-agent-worker", "hwlab-device-pod", "hwlab-gateway", - "hwlab-gateway-simu", - "hwlab-box-simu", - "hwlab-patch-panel", - "hwlab-router", - "hwlab-tunnel-client", "hwlab-edge-proxy", "hwlab-cli", "hwlab-agent-skills" @@ -346,33 +341,6 @@ "type": "string", "enum": ["indexed-workloads"] }, - "m3Route": { - "type": "object", - "required": ["fromResourceId", "fromPort", "patchPanelServiceId", "toResourceId", "toPort"], - "properties": { - "fromResourceId": { - "type": "string", - "const": "res_boxsimu_1" - }, - "fromPort": { - "type": "string", - "const": "DO1" - }, - "patchPanelServiceId": { - "type": "string", - "const": "hwlab-patch-panel" - }, - "toResourceId": { - "type": "string", - "const": "res_boxsimu_2" - }, - "toPort": { - "type": "string", - "const": "DI1" - } - }, - "additionalProperties": false - }, "env": { "type": "object", "additionalProperties": { @@ -439,10 +407,6 @@ "type": "string", "const": "http://127.0.0.1:49280/responses" }, - "HWLAB_CODE_AGENT_HWLAB_API_BASE_URL": { - "type": "string", - "const": "http://hwlab-cloud-api.hwlab-dev.svc.cluster.local:6667" - }, "HWLAB_CODE_AGENT_CODEX_STDIO_ENABLED": { "type": "string", "const": "1" diff --git a/deploy/frp/README.md b/deploy/frp/README.md index 30987e71..bcf7e0bb 100644 --- a/deploy/frp/README.md +++ b/deploy/frp/README.md @@ -4,10 +4,9 @@ The DEV reverse link is D601 to master edge through frp. - Public API/edge endpoint: `http://74.48.78.17:16667` - Public browser endpoint: `http://74.48.78.17:16666` -- `hwlab-tunnel-client` owns the frp client health contract. - `hwlab-cloud-web` owns the public browser entry on port `16666`. - `hwlab-edge-proxy` owns public API/health ingress on port `16667`. -- `frps.dev.toml` reserves D601 `16666` / `16667`, G14 DEV `17666` / `17667`, G14 PROD `18666` / `18667`, and tunnel health `7402` +- `frps.dev.toml` reserves D601 `16666` / `16667`, G14 DEV `17666` / `17667`, and G14 PROD `18666` / `18667` as TCP `remotePort` values; do not also bind them as `vhostHTTPPort`, because that collides with the DEV TCP proxy. - `deploy/deploy.json` is the source for the public endpoints and FRP proxy @@ -35,7 +34,7 @@ G14 uses separate preview port ranges and must not reuse D601's `16666` / `16667 - G14 PROD frpc local template: `deploy/frp/frpc.g14-prod.toml` Only `hwlab-cloud-web:8080` and `hwlab-edge-proxy:6667` are exposed through FRP. -Internal services, Tekton, Argo CD, registry, database, and simulator services stay ClusterIP-only. +Internal services, Tekton, Argo CD, registry, and database stay ClusterIP-only. The master-side `/opt/hwlab-frp/frps.dev.toml` and active `/etc/frp/frps.toml` may need a manual allow-list update matching `deploy/frp/frps.dev.toml` before the G14 frpc Deployments can register `17666` / `17667` and `18666` / `18667`; this is an edge operation, not a D601 client change. diff --git a/deploy/frp/frpc.dev.toml b/deploy/frp/frpc.dev.toml index fc56f75d..b3dcb0a6 100644 --- a/deploy/frp/frpc.dev.toml +++ b/deploy/frp/frpc.dev.toml @@ -15,10 +15,3 @@ type = "tcp" localIP = "hwlab-edge-proxy.hwlab-dev.svc.cluster.local" localPort = 6667 remotePort = 16667 - -[[proxies]] -name = "hwlab-dev-tunnel-health" -type = "tcp" -localIP = "hwlab-tunnel-client.hwlab-dev.svc.cluster.local" -localPort = 7402 -remotePort = 7402 diff --git a/deploy/frp/frps.dev.toml b/deploy/frp/frps.dev.toml index faaf3767..f83720b1 100644 --- a/deploy/frp/frps.dev.toml +++ b/deploy/frp/frps.dev.toml @@ -23,7 +23,3 @@ end = 18666 [[allowPorts]] start = 18667 end = 18667 - -[[allowPorts]] -start = 7402 -end = 7402 diff --git a/deploy/k8s/base/services.yaml b/deploy/k8s/base/services.yaml index 7d70ea76..58735a14 100644 --- a/deploy/k8s/base/services.yaml +++ b/deploy/k8s/base/services.yaml @@ -27,58 +27,6 @@ ] } }, - { - "apiVersion": "v1", - "kind": "Service", - "metadata": { - "name": "hwlab-gateway-simu-1", - "namespace": "hwlab-dev", - "labels": { - "app.kubernetes.io/name": "hwlab-gateway-simu", - "hwlab.pikastech.local/service-id": "hwlab-gateway-simu", - "hwlab.pikastech.local/instance-id": "gwsimu_1" - } - }, - "spec": { - "type": "ClusterIP", - "selector": { - "statefulset.kubernetes.io/pod-name": "hwlab-gateway-simu-0" - }, - "ports": [ - { - "name": "http", - "port": 7101, - "targetPort": "http" - } - ] - } - }, - { - "apiVersion": "v1", - "kind": "Service", - "metadata": { - "name": "hwlab-gateway-simu-2", - "namespace": "hwlab-dev", - "labels": { - "app.kubernetes.io/name": "hwlab-gateway-simu", - "hwlab.pikastech.local/service-id": "hwlab-gateway-simu", - "hwlab.pikastech.local/instance-id": "gwsimu_2" - } - }, - "spec": { - "type": "ClusterIP", - "selector": { - "statefulset.kubernetes.io/pod-name": "hwlab-gateway-simu-1" - }, - "ports": [ - { - "name": "http", - "port": 7101, - "targetPort": "http" - } - ] - } - }, { "apiVersion": "v1", "kind": "Service", @@ -104,58 +52,6 @@ ] } }, - { - "apiVersion": "v1", - "kind": "Service", - "metadata": { - "name": "hwlab-box-simu-1", - "namespace": "hwlab-dev", - "labels": { - "app.kubernetes.io/name": "hwlab-box-simu", - "hwlab.pikastech.local/service-id": "hwlab-box-simu", - "hwlab.pikastech.local/instance-id": "res_boxsimu_1" - } - }, - "spec": { - "type": "ClusterIP", - "selector": { - "statefulset.kubernetes.io/pod-name": "hwlab-box-simu-0" - }, - "ports": [ - { - "name": "http", - "port": 7201, - "targetPort": "http" - } - ] - } - }, - { - "apiVersion": "v1", - "kind": "Service", - "metadata": { - "name": "hwlab-box-simu-2", - "namespace": "hwlab-dev", - "labels": { - "app.kubernetes.io/name": "hwlab-box-simu", - "hwlab.pikastech.local/service-id": "hwlab-box-simu", - "hwlab.pikastech.local/instance-id": "res_boxsimu_2" - } - }, - "spec": { - "type": "ClusterIP", - "selector": { - "statefulset.kubernetes.io/pod-name": "hwlab-box-simu-1" - }, - "ports": [ - { - "name": "http", - "port": 7201, - "targetPort": "http" - } - ] - } - }, { "apiVersion": "v1", "kind": "Service", @@ -283,131 +179,6 @@ ] } }, - { - "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", diff --git a/deploy/k8s/base/workloads.yaml b/deploy/k8s/base/workloads.yaml index e8037c3c..1df83852 100644 --- a/deploy/k8s/base/workloads.yaml +++ b/deploy/k8s/base/workloads.yaml @@ -144,19 +144,7 @@ }, { "name": "HWLAB_M3_IO_CONTROL_ENABLED", - "value": "true" - }, - { - "name": "HWLAB_M3_GATEWAY_SIMU_1_URL", - "value": "http://hwlab-gateway-simu-1.hwlab-dev.svc.cluster.local:7101" - }, - { - "name": "HWLAB_M3_GATEWAY_SIMU_2_URL", - "value": "http://hwlab-gateway-simu-2.hwlab-dev.svc.cluster.local:7101" - }, - { - "name": "HWLAB_M3_PATCH_PANEL_URL", - "value": "http://hwlab-patch-panel.hwlab-dev.svc.cluster.local:7301" + "value": "false" }, { "name": "HWLAB_CODE_AGENT_PROVIDER", @@ -174,10 +162,6 @@ "name": "HWLAB_CODE_AGENT_OPENAI_BASE_URL", "value": "http://127.0.0.1:49280/responses" }, - { - "name": "HWLAB_CODE_AGENT_HWLAB_API_BASE_URL", - "value": "http://hwlab-cloud-api.hwlab-dev.svc.cluster.local:6667" - }, { "name": "HWLAB_CODE_AGENT_CODEX_STDIO_ENABLED", "value": "1" @@ -330,6 +314,10 @@ { "name": "no_proxy", "value": "hyueapi.com,.hyueapi.com,hyui.com,.hyui.com,127.0.0.1,localhost,::1,api.minimaxi.com,.minimaxi.com" + }, + { + "name": "HWLAB_M3_IO_CONTROL_ENABLED", + "value": "false" } ], "readinessProbe": { @@ -697,344 +685,6 @@ } } }, - { - "apiVersion": "apps/v1", - "kind": "StatefulSet", - "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": { - "serviceName": "hwlab-gateway-simu", - "replicas": 2, - "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": "127.0.0.1:5000/hwlab/hwlab-gateway-simu:af46386", - "ports": [ - { - "name": "http", - "containerPort": 7101 - } - ], - "env": [ - { - "name": "HWLAB_GATEWAY_ID", - "value": "gwsimu_1,gwsimu_2" - }, - { - "name": "HWLAB_BOX_IDS", - "value": "boxsimu_1,boxsimu_2" - }, - { - "name": "HWLAB_BOX_RESOURCES", - "value": "res_boxsimu_1,res_boxsimu_2" - }, - { - "name": "HWLAB_BOX_URLS", - "value": "http://hwlab-box-simu-1.hwlab-dev.svc.cluster.local:7201,http://hwlab-box-simu-2.hwlab-dev.svc.cluster.local:7201" - } - ], - "readinessProbe": { - "httpGet": { - "path": "/health/live", - "port": "http" - } - }, - "livenessProbe": { - "httpGet": { - "path": "/health/live", - "port": "http" - } - } - } - ] - } - } - } - }, - { - "apiVersion": "apps/v1", - "kind": "StatefulSet", - "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": { - "serviceName": "hwlab-box-simu", - "replicas": 2, - "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": "127.0.0.1:5000/hwlab/hwlab-box-simu:af46386", - "ports": [ - { - "name": "http", - "containerPort": 7201 - } - ], - "env": [ - { - "name": "HWLAB_BOX_ID", - "value": "boxsimu_1,boxsimu_2" - }, - { - "name": "HWLAB_BOX_RESOURCE_ID", - "value": "res_boxsimu_1,res_boxsimu_2" - }, - { - "name": "HWLAB_GATEWAY_SESSION_ID", - "value": "gws_gwsimu_1,gws_gwsimu_2" - } - ], - "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": "127.0.0.1:5000/hwlab/hwlab-patch-panel:af46386", - "ports": [ - { - "name": "http", - "containerPort": 7301 - } - ], - "env": [ - { - "name": "HWLAB_PATCH_PANEL_ENDPOINT_MAP", - "value": "{\"res_boxsimu_2\":\"http://hwlab-box-simu-2.hwlab-dev.svc.cluster.local:7201\"}" - }, - { - "name": "HWLAB_PATCH_PANEL_WIRING_CONFIG", - "value": "{\"wiringConfigId\":\"wir_m3_do1_di1\",\"projectId\":\"prj_m3_hardware_loop\",\"gatewaySessionId\":\"gws_gwsimu_1\",\"name\":\"M3 simulated DO1 to DI1 patch wiring\",\"status\":\"active\",\"connections\":[{\"from\":{\"resourceId\":\"res_boxsimu_1\",\"port\":\"DO1\"},\"to\":{\"resourceId\":\"res_boxsimu_2\",\"port\":\"DI1\"},\"mode\":\"exclusive\"}],\"constraints\":{\"propagation\":\"patch-panel-only\",\"localLoopbackSubstituteAllowed\":false},\"createdAt\":\"2026-05-21T00:00:00.000Z\",\"updatedAt\":\"2026-05-21T00:00:00.000Z\"}" - } - ], - "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": "127.0.0.1:5000/hwlab/hwlab-router:af46386", - "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": "127.0.0.1:5000/hwlab/hwlab-tunnel-client:af46386", - "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": "16667" - }, - { - "name": "HWLAB_FRP_WEB_PUBLIC_PORT", - "value": "16666" - } - ], - "readinessProbe": { - "httpGet": { - "path": "/health/live", - "port": "http" - } - }, - "livenessProbe": { - "httpGet": { - "path": "/health/live", - "port": "http" - } - } - } - ] - } - } - } - }, { "apiVersion": "apps/v1", "kind": "Deployment", diff --git a/deploy/k8s/dev/health-contract.yaml b/deploy/k8s/dev/health-contract.yaml index 35e684df..bd73b177 100644 --- a/deploy/k8s/dev/health-contract.yaml +++ b/deploy/k8s/dev/health-contract.yaml @@ -15,12 +15,8 @@ "cloud-api-db": "DEV DB config gate requires HWLAB_CLOUD_DB_URL from Secret hwlab-cloud-api-dev-db/database-url and HWLAB_CLOUD_DB_SSL_MODE=disable. Runtime readiness dials the redacted host parsed from the Secret URL and reports endpointSource=secret-url-host. cloud-api-db is an optional desired alias only until this repo owns Service plus Endpoint or EndpointSlice manifests and rollout/apply contract; health reports env presence, env injection, redacted connection attempt/result, and liveConnected without exposing secret values", "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", - "device-pod": "hwlab-device-pod:7601 exposes /health/live and serves fake Device Pod summary/events for the Cloud Workbench right sidebar" + "device-pod": "hwlab-device-pod:7601 exposes /health/live and serves Device Pod profile/job state through cloud-api authority" } } diff --git a/deploy/master-edge/README.md b/deploy/master-edge/README.md index 900629f9..033d5b4d 100644 --- a/deploy/master-edge/README.md +++ b/deploy/master-edge/README.md @@ -10,15 +10,13 @@ api/edge: http://74.48.78.17:16667 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. +- `hwlab-device-pod` and `hwlab-gateway`: own the current hardware-facing + runtime boundaries; removed simulator/router/tunnel services are not part of + the default DEV/v0.2 runtime contract. PROD is intentionally gated off for this task. diff --git a/deploy/master-edge/health-contract.json b/deploy/master-edge/health-contract.json index 1dc01e26..1089cb0a 100644 --- a/deploy/master-edge/health-contract.json +++ b/deploy/master-edge/health-contract.json @@ -3,8 +3,7 @@ "endpoint": "http://74.48.78.17:16667", "reverseLink": { "mode": "frp", - "direction": "d601-to-master", - "client": "hwlab-tunnel-client", + "direction": "edge-proxy-only", "serverAddress": "74.48.78.17", "publicPort": 16667, "webPublicPort": 16666 @@ -16,16 +15,6 @@ "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", @@ -45,21 +34,6 @@ "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": [ diff --git a/internal/cloud/m3-io-control.ts b/internal/cloud/m3-io-control.ts index ff144aad..481314bf 100644 --- a/internal/cloud/m3-io-control.ts +++ b/internal/cloud/m3-io-control.ts @@ -79,9 +79,9 @@ export const M3_IO_BLOCKER_CODES = Object.freeze({ export const DEFAULT_TIMEOUT_MS = 2200; const DEV_SERVICE_ENDPOINTS = Object.freeze({ - gateway1: "http://hwlab-gateway-simu-1.hwlab-dev.svc.cluster.local:7101", - gateway2: "http://hwlab-gateway-simu-2.hwlab-dev.svc.cluster.local:7101", - patchPanel: "http://hwlab-patch-panel.hwlab-dev.svc.cluster.local:7301" + gateway1: "", + gateway2: "", + patchPanel: "" }); const ACTIONS = new Set(["do.write", "di.read"]); @@ -703,7 +703,7 @@ export async function handleM3IoRpc(action, params = {}, envelope = {}, context } export function buildM3IoConfig(env = process.env) { - const enabledValue = String(env.HWLAB_M3_IO_CONTROL_ENABLED ?? env.HWLAB_M3_CONTROL_ENABLED ?? "true").toLowerCase(); + const enabledValue = String(env.HWLAB_M3_IO_CONTROL_ENABLED ?? env.HWLAB_M3_CONTROL_ENABLED ?? "false").toLowerCase(); return { enabled: !["0", "false", "no", "disabled"].includes(enabledValue), gateway1Url: trimUrl(env.HWLAB_M3_GATEWAY_SIMU_1_URL) ?? DEV_SERVICE_ENDPOINTS.gateway1, diff --git a/internal/cloud/server-rest-payloads.ts b/internal/cloud/server-rest-payloads.ts index 17e98011..0816217b 100644 --- a/internal/cloud/server-rest-payloads.ts +++ b/internal/cloud/server-rest-payloads.ts @@ -20,11 +20,6 @@ const LIVE_BUILD_SERVICE_DEFAULTS = Object.freeze({ "hwlab-agent-worker": Object.freeze({ urlEnv: "HWLAB_AGENT_WORKER_URL", defaultUrl: "http://hwlab-agent-worker.hwlab-dev.svc.cluster.local:7411" }), "hwlab-device-pod": Object.freeze({ urlEnv: "HWLAB_DEVICE_POD_URL", defaultUrl: "http://hwlab-device-pod.hwlab-dev.svc.cluster.local:7601" }), "hwlab-gateway": Object.freeze({ urlEnv: "HWLAB_GATEWAY_URL", defaultUrl: "http://hwlab-gateway.hwlab-dev.svc.cluster.local:7001" }), - "hwlab-gateway-simu": Object.freeze({ urlEnv: "HWLAB_GATEWAY_SIMU_URL", defaultUrl: "http://hwlab-gateway-simu.hwlab-dev.svc.cluster.local:7101" }), - "hwlab-box-simu": Object.freeze({ urlEnv: "HWLAB_BOX_SIMU_URL", defaultUrl: "http://hwlab-box-simu.hwlab-dev.svc.cluster.local:7201" }), - "hwlab-patch-panel": Object.freeze({ urlEnv: "HWLAB_PATCH_PANEL_URL", defaultUrl: "http://hwlab-patch-panel.hwlab-dev.svc.cluster.local:7301" }), - "hwlab-router": Object.freeze({ urlEnv: "HWLAB_ROUTER_URL", defaultUrl: "http://hwlab-router.hwlab-dev.svc.cluster.local:7401" }), - "hwlab-tunnel-client": Object.freeze({ urlEnv: "HWLAB_TUNNEL_CLIENT_URL", defaultUrl: "http://hwlab-tunnel-client.hwlab-dev.svc.cluster.local:7402" }), "hwlab-edge-proxy": Object.freeze({ urlEnv: "HWLAB_EDGE_PROXY_URL", defaultUrl: "http://hwlab-edge-proxy.hwlab-dev.svc.cluster.local:6667", healthPath: "/health" }), "hwlab-cli": Object.freeze({ urlEnv: "HWLAB_CLI_URL", defaultUrl: "http://hwlab-cli.hwlab-dev.svc.cluster.local:7501" }), "hwlab-agent-skills": Object.freeze({ urlEnv: "HWLAB_AGENT_SKILLS_URL", defaultUrl: "http://hwlab-agent-skills.hwlab-dev.svc.cluster.local:7430" }) @@ -771,12 +766,8 @@ function serviceDefaultUrl(serviceId) { "hwlab-cloud-web": 8080, "hwlab-agent-mgr": 7410, "hwlab-agent-worker": 7411, + "hwlab-device-pod": 7601, "hwlab-gateway": 7001, - "hwlab-gateway-simu": 7101, - "hwlab-box-simu": 7201, - "hwlab-patch-panel": 7301, - "hwlab-router": 7401, - "hwlab-tunnel-client": 7402, "hwlab-edge-proxy": 6667, "hwlab-cli": 7501, "hwlab-agent-skills": 7430 diff --git a/internal/protocol/index.mjs b/internal/protocol/index.mjs index aaf1d90b..b25b324d 100644 --- a/internal/protocol/index.mjs +++ b/internal/protocol/index.mjs @@ -10,11 +10,6 @@ export const SERVICE_IDS = Object.freeze([ "hwlab-agent-worker", "hwlab-device-pod", "hwlab-gateway", - "hwlab-gateway-simu", - "hwlab-box-simu", - "hwlab-patch-panel", - "hwlab-router", - "hwlab-tunnel-client", "hwlab-edge-proxy", "hwlab-cli", "hwlab-agent-skills" diff --git a/protocol/schemas/common.json b/protocol/schemas/common.json index dbd8a77c..dff0a3b1 100644 --- a/protocol/schemas/common.json +++ b/protocol/schemas/common.json @@ -27,11 +27,6 @@ "hwlab-agent-worker", "hwlab-device-pod", "hwlab-gateway", - "hwlab-gateway-simu", - "hwlab-box-simu", - "hwlab-patch-panel", - "hwlab-router", - "hwlab-tunnel-client", "hwlab-edge-proxy", "hwlab-cli", "hwlab-agent-skills" diff --git a/scripts/artifact-publish.mjs b/scripts/artifact-publish.mjs index ca1e28a1..d02e66ab 100644 --- a/scripts/artifact-publish.mjs +++ b/scripts/artifact-publish.mjs @@ -62,12 +62,8 @@ const servicePorts = new Map([ ["hwlab-cloud-web", 8080], ["hwlab-agent-mgr", 7410], ["hwlab-agent-worker", 7411], + ["hwlab-device-pod", 7601], ["hwlab-gateway", 7001], - ["hwlab-gateway-simu", 7101], - ["hwlab-box-simu", 7201], - ["hwlab-patch-panel", 7301], - ["hwlab-router", 7401], - ["hwlab-tunnel-client", 7402], ["hwlab-edge-proxy", 6667], ["hwlab-cli", 7420], ["hwlab-agent-skills", 7430] diff --git a/scripts/deploy-contract-plan.test.mjs b/scripts/deploy-contract-plan.test.mjs index eeaef8bb..4cc23d82 100644 --- a/scripts/deploy-contract-plan.test.mjs +++ b/scripts/deploy-contract-plan.test.mjs @@ -81,6 +81,6 @@ test("deploy contract check does not require python3 tomllib", async () => { const plan = JSON.parse(result.stdout); assert.equal(plan.status, "pass"); - assert.equal(plan.summary.frpProxies, 3); + assert.equal(plan.summary.frpProxies, 2); assert.deepEqual(plan.diagnostics, []); }); diff --git a/scripts/g14-gitops-render.mjs b/scripts/g14-gitops-render.mjs index 3ed65a36..2008c0a2 100644 --- a/scripts/g14-gitops-render.mjs +++ b/scripts/g14-gitops-render.mjs @@ -34,11 +34,6 @@ const defaultServiceIds = Object.freeze([ "hwlab-agent-worker", "hwlab-device-pod", "hwlab-gateway", - "hwlab-gateway-simu", - "hwlab-box-simu", - "hwlab-patch-panel", - "hwlab-router", - "hwlab-tunnel-client", "hwlab-edge-proxy", "hwlab-cli", "hwlab-agent-skills" @@ -688,10 +683,6 @@ function transformWorkloads({ workloads, deploy, catalog, source, registryPrefix }); } } - if (serviceIdForWorkload(item, null) === "hwlab-tunnel-client" && typeof item.spec?.replicas === "number") { - item.spec.replicas = 0; - } - const podTemplate = item?.spec?.template; if (!podTemplate?.spec?.containers) continue; const templateServiceId = serviceIdForWorkload(item, podTemplate.spec.containers[0]); @@ -771,12 +762,6 @@ function transformWorkloads({ workloads, deploy, catalog, source, registryPrefix if (serviceId === "hwlab-cli") { upsertEnv(container.env, "HWLAB_CLI_ENDPOINT", runtimeEndpoint); } - if (serviceId === "hwlab-tunnel-client") { - upsertEnv(container.env, "HWLAB_TUNNEL_MODE", "disabled-g14-gitops"); - upsertEnv(container.env, "HWLAB_FRP_SERVER_ADDR", ""); - upsertEnv(container.env, "HWLAB_FRP_PUBLIC_PORT", "0"); - upsertEnv(container.env, "HWLAB_FRP_WEB_PUBLIC_PORT", "0"); - } } rewritePodSecretRefs(podTemplate.spec, profile); } diff --git a/scripts/src/check-plan.mjs b/scripts/src/check-plan.mjs index 8eecc9f9..8f89af26 100644 --- a/scripts/src/check-plan.mjs +++ b/scripts/src/check-plan.mjs @@ -71,9 +71,7 @@ export const checkProfiles = Object.freeze({ { id: "check-046-cloud-api-run-bun", group: "cloud-api", command: ["node","scripts/run-bun.mjs","build","cmd/hwlab-cloud-api/provision.ts","--target=bun","--packages=external","--outdir=/tmp/hwlab-ts-check"] }, { id: "check-047-cloud-api-run-bun", group: "cloud-api", command: ["node","scripts/run-bun.mjs","build","cmd/hwlab-cloud-api/migrate.ts","--target=bun","--packages=external","--outdir=/tmp/hwlab-ts-check"] }, { id: "check-048-runtime-services-run-bun", group: "runtime-services", command: ["node","scripts/run-bun.mjs","test","cmd/hwlab-edge-proxy/main.test.ts","cmd/hwlab-device-pod/main.test.ts","cmd/hwlab-agent-mgr/main.test.ts","cmd/hwlab-agent-worker/main.test.ts","cmd/hwlab-codex-api-responses-forwarder/main.test.ts","cmd/hwlab-deepseek-responses-bridge/main.test.ts"] }, - { id: "check-055-repo-main", group: "repo", command: ["node","--check","cmd/hwlab-box-simu/main.mjs"] }, { id: "check-056-repo-main", group: "repo", command: ["node","--check","cmd/hwlab-gateway/main.mjs"] }, - { id: "check-057-repo-main", group: "repo", command: ["node","--check","cmd/hwlab-gateway-simu/main.mjs"] }, { id: "check-058-tools-hwlab-gateway-shell", group: "tools", command: ["node","--check","tools/hwlab-gateway-shell.mjs"] }, { id: "check-059-tools-hwlab-gateway-tran", group: "tools", command: ["node","--check","tools/hwlab-gateway-tran.mjs"] }, { id: "check-060-tools-tran", group: "tools", command: ["node","--check","tools/tran.mjs"] }, @@ -105,8 +103,6 @@ export const checkProfiles = Object.freeze({ { id: "check-084-smoke-rpt004-mvp-e2e-harness", group: "smoke", command: ["node","--check","scripts/rpt004-mvp-e2e-harness.mjs"] }, { id: "check-085-smoke-run-bun", group: "smoke", command: ["node","scripts/run-bun.mjs","build","scripts/src/rpt004-mvp-e2e-harness.mjs","--target=bun","--packages=external","--outdir=/tmp/hwlab-ts-check"] }, { id: "check-086-smoke-rpt004-mvp-e2e-harness-test", group: "smoke", command: ["node","--check","scripts/src/rpt004-mvp-e2e-harness.test.mjs"] }, - { id: "check-087-smoke-validate-dev-m3-cardinality", group: "smoke", command: ["node","--check","scripts/validate-dev-m3-cardinality.mjs"] }, - { id: "check-088-smoke-validate-dev-m3-cardinality-test", group: "smoke", command: ["node","--check","scripts/validate-dev-m3-cardinality.test.mjs"] }, { id: "check-089-deploy-validate-artifact-catalog", group: "deploy", command: ["node","--check","scripts/validate-artifact-catalog.mjs"] }, { id: "check-090-deploy-refresh-artifact-catalog", group: "deploy", command: ["node","--check","scripts/refresh-artifact-catalog.mjs"] }, { id: "check-091-deploy-refresh-artifact-catalog-test", group: "deploy", command: ["node","--check","scripts/refresh-artifact-catalog.test.mjs"] }, @@ -138,7 +134,6 @@ export const checkProfiles = Object.freeze({ { id: "check-116-dev-runtime-dev-runtime-hotfix-audit-test", group: "dev-runtime", command: ["node","--check","scripts/src/dev-runtime-hotfix-audit.test.mjs"] }, { id: "check-117-dev-runtime-dev-runtime-hotfix-audit-test", group: "dev-runtime", command: ["node","--test","scripts/src/dev-runtime-hotfix-audit.test.mjs"] }, { id: "check-118-smoke-l2-runtime-contract-smoke", group: "smoke", command: ["node","--check","scripts/l2-runtime-contract-smoke.mjs"] }, - { id: "check-119-smoke-patch-panel-runtime-smoke", group: "smoke", command: ["node","--check","scripts/patch-panel-runtime-smoke.mjs"] }, { id: "check-120-smoke-l6-cli-web-smoke", group: "smoke", command: ["node","--check","scripts/l6-cli-web-smoke.mjs"] }, { id: "check-121-tools-hwlab-agent-runtime-cli", group: "tools", command: ["node","--check","skills/hwlab-agent-runtime/scripts/hwlab-agent-runtime-cli.mjs"] }, { id: "check-122-smoke-m3-io-skill-client", group: "smoke", command: ["node","--check","skills/hwlab-agent-runtime/scripts/src/m3-io-skill-client.mjs"] }, @@ -149,7 +144,6 @@ export const checkProfiles = Object.freeze({ { id: "check-127-repo-run-bun", group: "repo", command: ["node","scripts/run-bun.mjs","scripts/validate-contract.mjs"] }, { id: "check-128-dev-runtime-validate-dev-gate-report", group: "dev-runtime", command: ["node","scripts/validate-dev-gate-report.mjs"] }, { id: "check-129-repo-report-lifecycle-test", group: "repo", command: ["node","scripts/report-lifecycle.test.mjs"] }, - { id: "check-130-smoke-validate-dev-m3-cardinality", group: "smoke", command: ["node","scripts/validate-dev-m3-cardinality.mjs"] }, { id: "check-131-deploy-validate-artifact-catalog", group: "deploy", command: ["node","scripts/validate-artifact-catalog.mjs"] }, { id: "check-132-deploy-run-bun", group: "deploy", command: ["node","scripts/run-bun.mjs","scripts/deploy-desired-state-plan.mjs","--check"] }, { id: "check-133-dev-runtime-run-bun", group: "dev-runtime", command: ["node","scripts/run-bun.mjs","scripts/dev-runtime-provisioning.mjs","--check"] }, diff --git a/scripts/src/deploy-contract-plan.mjs b/scripts/src/deploy-contract-plan.mjs index 7e56f246..9cc9d03c 100644 --- a/scripts/src/deploy-contract-plan.mjs +++ b/scripts/src/deploy-contract-plan.mjs @@ -6,17 +6,13 @@ import { DEV_CODE_AGENT_PROVIDER_CONTRACT, codeAgentSecretRefPlaceholder } from "../../internal/cloud/code-agent-contract.ts"; -import { - HWLAB_M3_IO_API_BASE_URL_ENV, - HWLAB_M3_IO_DEV_SERVICE_BASE_URL -} from "../../skills/hwlab-agent-runtime/scripts/src/m3-io-skill-client.mjs"; +import { HWLAB_M3_IO_API_BASE_URL_ENV } from "../../skills/hwlab-agent-runtime/scripts/src/m3-io-skill-client.mjs"; const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../.."); const expectedPorts = Object.freeze({ frontend: 16666, api: 16667 }); const codeAgentBackendTimeoutMs = "1200000"; const codeAgentTransportTimeoutMs = "1260000"; const legacyPublicPorts = new Set([6666, 6667]); -const duplicateMappingAllowed = new Set(["hwlab-box-simu", "hwlab-gateway-simu"]); const tomlBareKeyPattern = /^[A-Za-z0-9_-]+$/u; function parseArgs(argv) { @@ -226,19 +222,14 @@ function validateSource(ctx, manifest) { expectEqual(ctx, manifest.profiles?.dev?.endpoint, endpoints.api?.url, "$.profiles.dev.endpoint", "DEV profile endpoint"); const cloudApi = servicesById.get("hwlab-cloud-api"); - const tunnelClient = servicesById.get("hwlab-tunnel-client"); const cli = servicesById.get("hwlab-cli"); - const patchPanel = servicesById.get("hwlab-patch-panel"); const cloudWeb = servicesById.get("hwlab-cloud-web"); const edgeProxy = servicesById.get("hwlab-edge-proxy"); expectEqual(ctx, cloudApi?.env?.HWLAB_PUBLIC_ENDPOINT, endpoints.api?.url, "$.services.hwlab-cloud-api.env.HWLAB_PUBLIC_ENDPOINT", "cloud API public endpoint env"); validateCloudApiDbSource(ctx, cloudApi?.env ?? {}); validateCloudApiCodeAgentSource(ctx, cloudApi?.env ?? {}); validateCodeAgentProxyTimeoutSource(ctx, { cloudApi, cloudWeb, edgeProxy }); - validateM3PatchPanelSource(ctx, patchPanel); expectEqual(ctx, cli?.env?.HWLAB_CLI_ENDPOINT, endpoints.api?.url, "$.services.hwlab-cli.env.HWLAB_CLI_ENDPOINT", "CLI endpoint env"); - expectEqual(ctx, tunnelClient?.env?.HWLAB_FRP_PUBLIC_PORT, String(expectedPorts.api), "$.services.hwlab-tunnel-client.env.HWLAB_FRP_PUBLIC_PORT", "tunnel API public port env"); - expectEqual(ctx, tunnelClient?.env?.HWLAB_FRP_WEB_PUBLIC_PORT, String(expectedPorts.frontend), "$.services.hwlab-tunnel-client.env.HWLAB_FRP_WEB_PUBLIC_PORT", "tunnel frontend public port env"); const proxies = manifest.frp?.proxies ?? []; const proxyNames = new Set(); @@ -265,7 +256,7 @@ function validateSource(ctx, manifest) { mappingNames.add(mapping.name); expect( ctx, - !mappingIds.has(mapping.serviceId) || duplicateMappingAllowed.has(mapping.serviceId), + !mappingIds.has(mapping.serviceId), "duplicate_source", `${basePath}.serviceId`, `duplicate k3s mapping ${mapping.serviceId}` @@ -278,78 +269,6 @@ function validateSource(ctx, manifest) { return { manifest, endpoints, servicesById, proxies, serviceMappings, healthPath: manifest.health?.path }; } -function requiredM3Route() { - return { - fromResourceId: "res_boxsimu_1", - fromPort: "DO1", - patchPanelServiceId: "hwlab-patch-panel", - toResourceId: "res_boxsimu_2", - toPort: "DI1" - }; -} - -function parseJsonEnv(ctx, value, jsonPath, label) { - try { - return JSON.parse(String(value ?? "")); - } catch (error) { - addDiagnostic(ctx, "invalid_json", jsonPath, `${label} must be JSON`, { - actual: error instanceof Error ? error.message : String(error) - }); - return null; - } -} - -function validateM3PatchPanelSource(ctx, patchPanel) { - const route = requiredM3Route(); - expectEqual(ctx, patchPanel?.m3Route?.fromResourceId, route.fromResourceId, "$.services.hwlab-patch-panel.m3Route.fromResourceId", "patch panel first-class M3 source resource"); - expectEqual(ctx, patchPanel?.m3Route?.fromPort, route.fromPort, "$.services.hwlab-patch-panel.m3Route.fromPort", "patch panel first-class M3 source port"); - expectEqual(ctx, patchPanel?.m3Route?.patchPanelServiceId, route.patchPanelServiceId, "$.services.hwlab-patch-panel.m3Route.patchPanelServiceId", "patch panel first-class M3 route owner"); - expectEqual(ctx, patchPanel?.m3Route?.toResourceId, route.toResourceId, "$.services.hwlab-patch-panel.m3Route.toResourceId", "patch panel first-class M3 target resource"); - expectEqual(ctx, patchPanel?.m3Route?.toPort, route.toPort, "$.services.hwlab-patch-panel.m3Route.toPort", "patch panel first-class M3 target port"); - - const endpointMap = parseJsonEnv( - ctx, - patchPanel?.env?.HWLAB_PATCH_PANEL_ENDPOINT_MAP, - "$.services.hwlab-patch-panel.env.HWLAB_PATCH_PANEL_ENDPOINT_MAP", - "patch panel endpoint map" - ); - expectEqual( - ctx, - endpointMap?.res_boxsimu_2, - "http://hwlab-box-simu-2.hwlab-dev.svc.cluster.local:7201", - "$.services.hwlab-patch-panel.env.HWLAB_PATCH_PANEL_ENDPOINT_MAP.res_boxsimu_2", - "patch panel M3 target endpoint" - ); - - const wiring = parseJsonEnv( - ctx, - patchPanel?.env?.HWLAB_PATCH_PANEL_WIRING_CONFIG, - "$.services.hwlab-patch-panel.env.HWLAB_PATCH_PANEL_WIRING_CONFIG", - "patch panel wiring config" - ); - const connection = wiring?.connections?.[0]; - expectEqual(ctx, wiring?.status, "active", "$.services.hwlab-patch-panel.env.HWLAB_PATCH_PANEL_WIRING_CONFIG.status", "patch panel M3 wiring status"); - expectEqual( - ctx, - wiring?.constraints?.propagation, - "patch-panel-only", - "$.services.hwlab-patch-panel.env.HWLAB_PATCH_PANEL_WIRING_CONFIG.constraints.propagation", - "patch panel M3 wiring propagation" - ); - expectEqual( - ctx, - wiring?.constraints?.localLoopbackSubstituteAllowed, - false, - "$.services.hwlab-patch-panel.env.HWLAB_PATCH_PANEL_WIRING_CONFIG.constraints.localLoopbackSubstituteAllowed", - "patch panel M3 wiring forbids loopback substitute" - ); - expectEqual(ctx, connection?.from?.resourceId, route.fromResourceId, "$.services.hwlab-patch-panel.env.HWLAB_PATCH_PANEL_WIRING_CONFIG.connections[0].from.resourceId", "patch panel M3 source resource"); - expectEqual(ctx, connection?.from?.port, route.fromPort, "$.services.hwlab-patch-panel.env.HWLAB_PATCH_PANEL_WIRING_CONFIG.connections[0].from.port", "patch panel M3 source port"); - expectEqual(ctx, connection?.to?.resourceId, route.toResourceId, "$.services.hwlab-patch-panel.env.HWLAB_PATCH_PANEL_WIRING_CONFIG.connections[0].to.resourceId", "patch panel M3 target resource"); - expectEqual(ctx, connection?.to?.port, route.toPort, "$.services.hwlab-patch-panel.env.HWLAB_PATCH_PANEL_WIRING_CONFIG.connections[0].to.port", "patch panel M3 target port"); - expectEqual(ctx, connection?.mode, "exclusive", "$.services.hwlab-patch-panel.env.HWLAB_PATCH_PANEL_WIRING_CONFIG.connections[0].mode", "patch panel M3 route mode"); -} - function validateCloudApiDbSource(ctx, env) { const alias = DEV_DB_ENV_CONTRACT.dns; expectEqual(ctx, env.HWLAB_CLOUD_DB_URL, "secretRef:hwlab-cloud-api-dev-db/database-url", "$.services.hwlab-cloud-api.env.HWLAB_CLOUD_DB_URL", "cloud API DB URL Secret reference"); @@ -397,9 +316,9 @@ function validateCloudApiCodeAgentSource(ctx, env) { expectEqual( ctx, env[HWLAB_M3_IO_API_BASE_URL_ENV], - HWLAB_M3_IO_DEV_SERVICE_BASE_URL, + undefined, `$.services.hwlab-cloud-api.env.${HWLAB_M3_IO_API_BASE_URL_ENV}`, - "cloud API Code Agent Skill CLI HWLAB API service-local base URL" + "legacy M3 Skill CLI HWLAB API base URL is removed from default cloud-api config" ); expectEqual(ctx, env.HWLAB_CODE_AGENT_CODEX_STDIO_ENABLED, "1", "$.services.hwlab-cloud-api.env.HWLAB_CODE_AGENT_CODEX_STDIO_ENABLED", "cloud API Codex stdio adapter enabled flag"); expectEqual(ctx, env.HWLAB_CODE_AGENT_CODEX_STDIO_SUPERVISOR, "repo-owned", "$.services.hwlab-cloud-api.env.HWLAB_CODE_AGENT_CODEX_STDIO_SUPERVISOR", "cloud API Codex stdio supervisor mode"); @@ -548,6 +467,8 @@ function validateK3sArtifacts(ctx, source, rendered, services, workloads, health expectEqual(ctx, masterEdge.endpoint, source.endpoints.api?.url, "deploy/master-edge/health-contract.json.endpoint", "master edge endpoint"); flagLegacyPublicPort(ctx, "deploy/master-edge/health-contract.json.reverseLink.publicPort", masterEdge.reverseLink?.publicPort, expectedPorts.api, "master edge API"); flagLegacyPublicPort(ctx, "deploy/master-edge/health-contract.json.reverseLink.webPublicPort", masterEdge.reverseLink?.webPublicPort, expectedPorts.frontend, "master edge frontend"); + expectEqual(ctx, masterEdge.reverseLink?.direction, "edge-proxy-only", "deploy/master-edge/health-contract.json.reverseLink.direction", "master edge reverse link no longer models a tunnel-client service"); + expectEqual(ctx, masterEdge.reverseLink?.client, undefined, "deploy/master-edge/health-contract.json.reverseLink.client", "master edge reverse link does not name removed tunnel-client"); expectEqual(ctx, masterEdge.prodAcceptance, false, "deploy/master-edge/health-contract.json.prodAcceptance", "master edge PROD acceptance"); } @@ -606,9 +527,9 @@ function validateCloudApiCodeAgentArtifacts(ctx, workloads) { expectEqual( ctx, env.get(HWLAB_M3_IO_API_BASE_URL_ENV)?.value, - HWLAB_M3_IO_DEV_SERVICE_BASE_URL, + undefined, `deploy/k8s/base/workloads.yaml.hwlab-cloud-api.env.${HWLAB_M3_IO_API_BASE_URL_ENV}`, - "cloud API workload Code Agent Skill CLI HWLAB API service-local base URL" + "legacy M3 Skill CLI HWLAB API base URL is removed from default cloud-api workload" ); expectEqual(ctx, env.get("HWLAB_CODE_AGENT_CODEX_STDIO_ENABLED")?.value, "1", "deploy/k8s/base/workloads.yaml.hwlab-cloud-api.env.HWLAB_CODE_AGENT_CODEX_STDIO_ENABLED", "cloud API workload Codex stdio adapter enabled flag"); expectEqual(ctx, env.get("HWLAB_CODE_AGENT_CODEX_STDIO_SUPERVISOR")?.value, "repo-owned", "deploy/k8s/base/workloads.yaml.hwlab-cloud-api.env.HWLAB_CODE_AGENT_CODEX_STDIO_SUPERVISOR", "cloud API workload Codex stdio supervisor mode"); diff --git a/scripts/src/g14-ci-plan-lib.mjs b/scripts/src/g14-ci-plan-lib.mjs index 3f0d47c4..62512ac0 100644 --- a/scripts/src/g14-ci-plan-lib.mjs +++ b/scripts/src/g14-ci-plan-lib.mjs @@ -54,11 +54,6 @@ const serviceSpecificPaths = Object.freeze({ "hwlab-agent-worker": ["cmd/hwlab-agent-worker/", "internal/agent/", "internal/db/", "internal/audit/", "skills/"], "hwlab-device-pod": ["cmd/hwlab-device-pod/", "internal/device-pod/"], "hwlab-gateway": ["cmd/hwlab-gateway/"], - "hwlab-gateway-simu": ["cmd/hwlab-gateway-simu/", "internal/sim/"], - "hwlab-box-simu": ["cmd/hwlab-box-simu/", "internal/sim/"], - "hwlab-patch-panel": ["cmd/hwlab-patch-panel/", "internal/patchpanel/"], - "hwlab-router": ["cmd/hwlab-router/"], - "hwlab-tunnel-client": ["cmd/hwlab-tunnel-client/"], "hwlab-edge-proxy": ["cmd/hwlab-edge-proxy/", "internal/dev-entrypoint/"], "hwlab-cli": ["tools/hwlab-cli/"], "hwlab-agent-skills": ["skills/"] diff --git a/scripts/validate-contract.mjs b/scripts/validate-contract.mjs index feb3c71c..50d8fe33 100644 --- a/scripts/validate-contract.mjs +++ b/scripts/validate-contract.mjs @@ -11,10 +11,7 @@ import { DEV_CODE_AGENT_PROVIDER_CONTRACT, codeAgentSecretRefPlaceholder } from "../internal/cloud/code-agent-contract.ts"; -import { - HWLAB_M3_IO_API_BASE_URL_ENV, - HWLAB_M3_IO_DEV_SERVICE_BASE_URL -} from "../skills/hwlab-agent-runtime/scripts/src/m3-io-skill-client.mjs"; +import { HWLAB_M3_IO_API_BASE_URL_ENV } from "../skills/hwlab-agent-runtime/scripts/src/m3-io-skill-client.mjs"; import { ENVIRONMENT_DEV, SERVICE_IDS, @@ -170,9 +167,13 @@ const deployServicesById = new Map(deployManifest.services.map((service) => [ser assert.equal(deployServicesById.has("hwlab-agent-mgr"), true); assert.equal(deployServicesById.has("hwlab-agent-worker"), true); assert.equal(deployServicesById.has("hwlab-agent-skills"), true); +for (const removedServiceId of ["hwlab-gateway-simu", "hwlab-box-simu", "hwlab-patch-panel", "hwlab-router", "hwlab-tunnel-client"]) { + assert.equal(deployServicesById.has(removedServiceId), false, `${removedServiceId} is removed from default deploy services`); + assert.equal(getWorkload(k8sWorkloads, removedServiceId), null, `${removedServiceId} is removed from default workload manifests`); + assert.equal(listItems(k8sServices).some((item) => item?.metadata?.labels?.["hwlab.pikastech.local/service-id"] === removedServiceId), false, `${removedServiceId} is removed from default service manifests`); +} const cloudApi = deployServicesById.get("hwlab-cloud-api"); -const patchPanel = deployServicesById.get("hwlab-patch-panel"); const cloudApiWorkload = getWorkload(k8sWorkloads, "hwlab-cloud-api"); const cloudApiContainer = cloudApiWorkload?.spec?.template?.spec?.containers?.find((entry) => entry.name === "hwlab-cloud-api"); const cloudApiWorkloadEnv = getWorkloadEnv(k8sWorkloads, "hwlab-cloud-api"); @@ -182,7 +183,6 @@ cloudApiWorkloadEnv.__podContainers = cloudApiWorkload?.spec?.template?.spec?.co cloudApiWorkloadEnv.__initContainers = cloudApiWorkload?.spec?.template?.spec?.initContainers ?? []; cloudApiWorkloadEnv.__deploymentStrategy = cloudApiWorkload?.spec?.strategy ?? null; cloudApiWorkloadEnv.__workspacePvc = getWorkload(k8sWorkloads, DEV_CODE_AGENT_PROVIDER_CONTRACT.workspace.claimName); -const patchPanelWorkloadEnv = getWorkloadEnv(k8sWorkloads, "hwlab-patch-panel"); assert.equal(deployManifest.health.path, "/health/live", "deploy health source path"); assert.equal(deployManifest.publicEndpoints.frontend.url, "http://74.48.78.17:16666", "deploy frontend endpoint"); assert.equal(deployManifest.publicEndpoints.api.url, "http://74.48.78.17:16667", "deploy api endpoint"); @@ -203,6 +203,10 @@ assert.equal( assert.equal(cloudApi.env.HWLAB_CLOUD_DB_CONTRACT, "dev-redacted-presence-only", "cloud-api DB contract marker"); assert.equal(cloudApi.env.HWLAB_CLOUD_RUNTIME_ADAPTER, "postgres", "cloud-api runtime durable adapter"); assert.equal(cloudApi.env.HWLAB_CLOUD_RUNTIME_DURABLE, "true", "cloud-api runtime durable flag"); +assert.equal(cloudApi.env.HWLAB_M3_IO_CONTROL_ENABLED, "false", "legacy M3 IO control is disabled in default deploy config"); +assert.equal(cloudApi.env.HWLAB_M3_GATEWAY_SIMU_1_URL, undefined, "legacy gateway simulator URL is removed from default deploy config"); +assert.equal(cloudApi.env.HWLAB_M3_GATEWAY_SIMU_2_URL, undefined, "legacy gateway simulator URL is removed from default deploy config"); +assert.equal(cloudApi.env.HWLAB_M3_PATCH_PANEL_URL, undefined, "legacy patch-panel URL is removed from default deploy config"); assert.equal( cloudApiWorkloadEnv.HWLAB_CLOUD_DB_SSL_MODE?.value, DEV_DB_ENV_CONTRACT.nonSecretDefaults.HWLAB_CLOUD_DB_SSL_MODE, @@ -210,6 +214,10 @@ assert.equal( ); assert.equal(cloudApiWorkloadEnv.HWLAB_CLOUD_RUNTIME_ADAPTER?.value, "postgres", "cloud-api workload runtime durable adapter"); assert.equal(cloudApiWorkloadEnv.HWLAB_CLOUD_RUNTIME_DURABLE?.value, "true", "cloud-api workload runtime durable flag"); +assert.equal(cloudApiWorkloadEnv.HWLAB_M3_IO_CONTROL_ENABLED?.value, "false", "legacy M3 IO control is disabled in default workload config"); +assert.equal(cloudApiWorkloadEnv.HWLAB_M3_GATEWAY_SIMU_1_URL, undefined, "legacy gateway simulator URL is removed from default workload config"); +assert.equal(cloudApiWorkloadEnv.HWLAB_M3_GATEWAY_SIMU_2_URL, undefined, "legacy gateway simulator URL is removed from default workload config"); +assert.equal(cloudApiWorkloadEnv.HWLAB_M3_PATCH_PANEL_URL, undefined, "legacy patch-panel URL is removed from default workload config"); assert.equal(cloudApi.env.HWLAB_CLOUD_DB_SERVICE_NAME, undefined, "cloud-api DB alias service name is optional"); assert.equal(cloudApi.env.HWLAB_CLOUD_DB_SERVICE_NAMESPACE, undefined, "cloud-api DB alias namespace is optional"); assert.equal(cloudApi.env.HWLAB_CLOUD_DB_HOST, undefined, "cloud-api DB alias host is optional"); @@ -235,8 +243,8 @@ assert.equal( ); assert.equal( cloudApi.env[HWLAB_M3_IO_API_BASE_URL_ENV], - HWLAB_M3_IO_DEV_SERVICE_BASE_URL, - "cloud-api Code Agent Skill CLI HWLAB API base URL must use service-local cloud-api DNS" + undefined, + "legacy M3 Skill CLI HWLAB API base URL is removed from default cloud-api config" ); assert.equal(cloudApi.env.HWLAB_CODE_AGENT_CODEX_STDIO_ENABLED, "1", "cloud-api Codex stdio adapter enabled flag"); assert.equal(cloudApi.env.HWLAB_CODE_AGENT_CODEX_STDIO_SUPERVISOR, "repo-owned", "cloud-api Codex stdio supervisor mode"); @@ -254,7 +262,6 @@ assert.notEqual( ); assert.equal(cloudApi.env.OPENAI_API_KEY, codeAgentSecretRefPlaceholder(), "cloud-api Code Agent OpenAI key must be a Secret reference placeholder"); assertCodeAgentProviderWorkloadContract(cloudApiWorkloadEnv); -assertM3PatchPanelDeployContract(patchPanel, patchPanelWorkloadEnv); assertDbForbiddenInvalidHostContract(); assertValidationDoesNotExposeSecretValues(cloudApi.env, cloudApiWorkloadEnv); @@ -314,8 +321,8 @@ function assertCodeAgentProviderWorkloadContract(env) { ); assert.equal( env[HWLAB_M3_IO_API_BASE_URL_ENV]?.value, - HWLAB_M3_IO_DEV_SERVICE_BASE_URL, - "cloud-api workload Code Agent Skill CLI HWLAB API base URL must use service-local cloud-api DNS" + undefined, + "legacy M3 Skill CLI HWLAB API base URL is removed from default cloud-api workload" ); assert.equal(env.HWLAB_CODE_AGENT_CODEX_STDIO_ENABLED?.value, "1", "cloud-api workload Codex stdio adapter enabled flag"); assert.equal(env.HWLAB_CODE_AGENT_CODEX_STDIO_SUPERVISOR?.value, "repo-owned", "cloud-api workload Codex stdio supervisor mode"); @@ -439,49 +446,6 @@ function assertCodeAgentWorkspaceContract(env, contract) { assert.equal(env.__deploymentStrategy?.type, workspace.rolloutStrategy, "cloud-api uses Recreate rollout for single-writer workspace PVC"); } -function assertM3PatchPanelDeployContract(manifestService, workloadEnv) { - const route = { - fromResourceId: "res_boxsimu_1", - fromPort: "DO1", - patchPanelServiceId: "hwlab-patch-panel", - toResourceId: "res_boxsimu_2", - toPort: "DI1" - }; - assert.deepEqual(manifestService.m3Route, route, "patch-panel deploy manifest first-class M3 route"); - const manifestEndpointMap = JSON.parse(manifestService.env.HWLAB_PATCH_PANEL_ENDPOINT_MAP); - const workloadEndpointMap = JSON.parse(workloadEnv.HWLAB_PATCH_PANEL_ENDPOINT_MAP?.value ?? "{}"); - assert.equal( - manifestEndpointMap.res_boxsimu_2, - "http://hwlab-box-simu-2.hwlab-dev.svc.cluster.local:7201", - "patch-panel deploy manifest M3 endpoint" - ); - assert.deepEqual(workloadEndpointMap, manifestEndpointMap, "patch-panel workload M3 endpoint map"); - - const manifestWiring = JSON.parse(manifestService.env.HWLAB_PATCH_PANEL_WIRING_CONFIG); - const workloadWiring = JSON.parse(workloadEnv.HWLAB_PATCH_PANEL_WIRING_CONFIG?.value ?? "{}"); - assert.deepEqual(workloadWiring, manifestWiring, "patch-panel workload first-class M3 wiring config"); - assert.equal(manifestWiring.status, "active", "patch-panel M3 wiring status"); - assert.equal(manifestWiring.constraints.propagation, "patch-panel-only", "patch-panel M3 wiring propagation"); - assert.equal( - manifestWiring.constraints.localLoopbackSubstituteAllowed, - false, - "patch-panel M3 wiring loopback substitute" - ); - assert.deepEqual(manifestWiring.connections, [ - { - from: { - resourceId: route.fromResourceId, - port: route.fromPort - }, - to: { - resourceId: route.toResourceId, - port: route.toPort - }, - mode: "exclusive" - } - ], "patch-panel M3 wiring route"); -} - function assertDbForbiddenInvalidHostContract() { const invalidHost = parseDbUrlContract("postgres://user:password@hwlab-dev-db.invalid:5432/hwlab"); assert.equal(invalidHost.ok, false, "DEV DB contract must reject .invalid runtime hosts");