@agentunion/fastaun-browser 0.5.4 → 0.5.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +130 -94
- package/_packed_docs/AUN/347/246/273/347/272/277/346/216/250/351/200/201/346/216/245/345/205/245/344/270/216/346/274/224/347/244/272/346/214/207/345/215/227.md +290 -0
- package/_packed_docs/AUN/347/246/273/347/272/277/346/216/250/351/200/201/346/234/215/345/212/241/346/236/266/346/236/204/344/270/216/350/257/246/347/273/206/345/256/236/347/216/260/350/256/241/345/210/222-codex.md +994 -0
- package/_packed_docs/AUN/347/246/273/347/272/277/346/216/250/351/200/201/346/234/215/345/212/241/350/277/220/347/273/264/344/270/216/345/217/221/345/270/203/346/214/207/345/215/227.md +144 -0
- package/_packed_docs/CHANGELOG.md +130 -94
- package/_packed_docs/INDEX.md +127 -69
- package/_packed_docs/KITE_DOCS_GUIDE.md +63 -29
- package/_packed_docs/audit/AUN/346/234/215/345/212/241Go/345/214/226/351/207/215/346/236/204/347/262/276/347/273/206/345/214/226/346/272/220/347/240/201/345/256/241/346/237/245-20260718.md +366 -0
- package/_packed_docs/aun/345/205/254/347/275/221/346/265/213/350/257/225/350/277/220/350/241/214/346/214/207/345/215/227.md +227 -0
- package/_packed_docs/aun/345/210/206/345/270/203/345/274/217/346/265/213/350/257/225/350/277/220/350/241/214/346/214/207/345/215/227.md +1004 -0
- package/_packed_docs/aun/346/265/213/350/257/225/350/277/220/350/241/214/346/214/207/345/215/227.md +999 -0
- package/_packed_docs/cli/CLI/346/211/213/345/206/214.md +6 -4
- package/_packed_docs/protocol/06-/346/234/215/345/212/241/345/215/217/350/256/256.md +58 -20
- package/_packed_docs/protocol/10-Group-/345/255/220/345/215/217/350/256/256.md +219 -247
- package/_packed_docs/protocol/12-Stream-/345/255/220/345/215/217/350/256/256.md +14 -14
- package/_packed_docs/protocol/13-Agent/350/241/214/344/270/272/350/247/204/350/214/203.md +3 -3
- package/_packed_docs/protocol/15-/347/246/273/347/272/277/346/216/250/351/200/201/351/200/232/347/237/245/345/215/217/350/256/256.md +165 -421
- package/_packed_docs/protocol/README.md +1 -0
- package/_packed_docs/protocol/aun-docs-guide.md +7 -4
- package/_packed_docs/protocol/index.md +25 -19
- package/_packed_docs/sdk/02-WebSocket/345/215/217/350/256/256.md +62 -17
- package/_packed_docs/sdk/03-/346/240/270/345/277/203/346/246/202/345/277/265.md +22 -0
- package/_packed_docs/sdk/04-/350/277/236/346/216/245/344/270/216/350/256/244/350/257/201.md +67 -78
- package/_packed_docs/sdk/05-E2EE/345/212/240/345/257/206/351/200/232/344/277/241.md +6 -2
- package/_packed_docs/sdk/06-API/346/211/213/345/206/214.md +50 -14
- package/_packed_docs/sdk/08-/346/234/200/344/275/263/345/256/236/350/267/265.md +18 -5
- package/_packed_docs/sdk/09-group-rpc-manual.md +312 -282
- package/_packed_docs/sdk/09-message-rpc-manual.md +142 -103
- package/_packed_docs/sdk/09-payload-reference.md +1 -1
- package/_packed_docs/sdk/09-stream-rpc-manual.md +8 -8
- package/_packed_docs/sdk/AUN_DOCS_GUIDE.md +26 -17
- package/_packed_docs/sdk/INDEX.md +42 -34
- package/_packed_docs/sdk/README.md +7 -6
- package/_packed_docs//346/266/210/346/201/257/345/220/214/346/255/245/344/270/216/345/216/206/345/217/262/346/213/211/345/217/226/344/273/243/347/240/201/345/256/241/346/237/245/351/227/256/351/242/230/346/270/205/345/215/225.md +229 -0
- package/_packed_docs//346/266/210/346/201/257/345/220/214/346/255/245/344/270/216/345/216/206/345/217/262/346/213/211/345/217/226/346/224/271/351/200/240/346/226/271/346/241/210.md +750 -0
- package/dist/agent-md.d.ts +4 -5
- package/dist/agent-md.d.ts.map +1 -1
- package/dist/agent-md.js +66 -43
- package/dist/agent-md.js.map +1 -1
- package/dist/aid-store.d.ts +2 -6
- package/dist/aid-store.d.ts.map +1 -1
- package/dist/aid-store.js +20 -14
- package/dist/aid-store.js.map +1 -1
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +30 -11
- package/dist/auth.js.map +1 -1
- package/dist/bundle.js +3297 -1023
- package/dist/client/delivery.d.ts +75 -8
- package/dist/client/delivery.d.ts.map +1 -1
- package/dist/client/delivery.js +1419 -245
- package/dist/client/delivery.js.map +1 -1
- package/dist/client/group-state.d.ts.map +1 -1
- package/dist/client/group-state.js +27 -24
- package/dist/client/group-state.js.map +1 -1
- package/dist/client/lifecycle.d.ts.map +1 -1
- package/dist/client/lifecycle.js +48 -4
- package/dist/client/lifecycle.js.map +1 -1
- package/dist/client/mention-mode.d.ts +7 -0
- package/dist/client/mention-mode.d.ts.map +1 -0
- package/dist/client/mention-mode.js +184 -0
- package/dist/client/mention-mode.js.map +1 -0
- package/dist/client/peers.d.ts +1 -1
- package/dist/client/peers.d.ts.map +1 -1
- package/dist/client/peers.js +26 -3
- package/dist/client/peers.js.map +1 -1
- package/dist/client/rpc-pipeline.d.ts +22 -1
- package/dist/client/rpc-pipeline.d.ts.map +1 -1
- package/dist/client/rpc-pipeline.js +309 -74
- package/dist/client/rpc-pipeline.js.map +1 -1
- package/dist/client/v2-e2ee.d.ts +25 -2
- package/dist/client/v2-e2ee.d.ts.map +1 -1
- package/dist/client/v2-e2ee.js +606 -97
- package/dist/client/v2-e2ee.js.map +1 -1
- package/dist/client.d.ts +24 -5
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +404 -215
- package/dist/client.js.map +1 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +4 -1
- package/dist/errors.js.map +1 -1
- package/dist/facades.d.ts +3 -0
- package/dist/facades.d.ts.map +1 -1
- package/dist/facades.js +91 -53
- package/dist/facades.js.map +1 -1
- package/dist/group-index.d.ts +6 -1
- package/dist/group-index.d.ts.map +1 -1
- package/dist/group-index.js +44 -25
- package/dist/group-index.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/keystore/index.d.ts +10 -5
- package/dist/keystore/index.d.ts.map +1 -1
- package/dist/keystore/indexeddb-identity-store.d.ts +0 -12
- package/dist/keystore/indexeddb-identity-store.d.ts.map +1 -1
- package/dist/keystore/indexeddb-identity-store.js +0 -60
- package/dist/keystore/indexeddb-identity-store.js.map +1 -1
- package/dist/keystore/indexeddb-shared.d.ts.map +1 -1
- package/dist/keystore/indexeddb-shared.js +9 -5
- package/dist/keystore/indexeddb-shared.js.map +1 -1
- package/dist/keystore/indexeddb-token-store.d.ts +3 -1
- package/dist/keystore/indexeddb-token-store.d.ts.map +1 -1
- package/dist/keystore/indexeddb-token-store.js +47 -2
- package/dist/keystore/indexeddb-token-store.js.map +1 -1
- package/dist/register-flow.d.ts.map +1 -1
- package/dist/register-flow.js +28 -3
- package/dist/register-flow.js.map +1 -1
- package/dist/seq-tracker.d.ts +28 -8
- package/dist/seq-tracker.d.ts.map +1 -1
- package/dist/seq-tracker.js +218 -61
- package/dist/seq-tracker.js.map +1 -1
- package/dist/storage/vfs.d.ts +1 -0
- package/dist/storage/vfs.d.ts.map +1 -1
- package/dist/storage/vfs.js +26 -2
- package/dist/storage/vfs.js.map +1 -1
- package/dist/tools/cross-sdk-agent.js +376 -10
- package/dist/tools/cross-sdk-agent.js.map +1 -1
- package/dist/transport.d.ts +12 -0
- package/dist/transport.d.ts.map +1 -1
- package/dist/transport.js +218 -101
- package/dist/transport.js.map +1 -1
- package/dist/v2/session/session.d.ts.map +1 -1
- package/dist/v2/session/session.js +3 -4
- package/dist/v2/session/session.js.map +1 -1
- package/dist/v2/state/commitment.d.ts.map +1 -1
- package/dist/v2/state/commitment.js +1 -2
- package/dist/v2/state/commitment.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +6 -5
- package/dist/group-resources.d.ts +0 -98
- package/dist/group-resources.d.ts.map +0 -1
- package/dist/group-resources.js +0 -635
- package/dist/group-resources.js.map +0 -1
- package/dist/keystore/indexeddb.d.ts +0 -179
- package/dist/keystore/indexeddb.d.ts.map +0 -1
- package/dist/keystore/indexeddb.js +0 -2031
- package/dist/keystore/indexeddb.js.map +0 -1
- package/dist/namespaces/auth.d.ts +0 -98
- package/dist/namespaces/auth.d.ts.map +0 -1
- package/dist/namespaces/auth.js +0 -992
- package/dist/namespaces/auth.js.map +0 -1
- package/dist/namespaces/custody.d.ts +0 -51
- package/dist/namespaces/custody.d.ts.map +0 -1
- package/dist/namespaces/custody.js +0 -302
- package/dist/namespaces/custody.js.map +0 -1
- package/dist/namespaces/meta.d.ts +0 -109
- package/dist/namespaces/meta.d.ts.map +0 -1
- package/dist/namespaces/meta.js +0 -549
- package/dist/namespaces/meta.js.map +0 -1
|
@@ -0,0 +1,1004 @@
|
|
|
1
|
+
# AUN 分布式测试运行指南
|
|
2
|
+
|
|
3
|
+
本文档负责三套本地 Docker 环境:三节点单域、本地真实域名双域 `agentid.pub/agentid.cn`、隔离双域 federation `dist-aid.com/dist-aid.net`。默认 `agentid.pub` 单域、默认四语言 Tester 和默认 cross-SDK 统一见 [AUN 测试运行指南](aun测试运行指南.md)。公网 `agentid.pub/agentid.cn` 复测是本地跨域通过后的独立验证层,不属于本地双域 Docker。
|
|
4
|
+
|
|
5
|
+
本指南只认当前 worktree `D:\modelunion\kite`。当前分支已经包含完整的默认单实例、三节点分布式、两套双域环境、服务端源码和四语言 SDK;服务端镜像、Tester、Cross-SDK、`data-dist` 与部署包都必须从这个 worktree 生成和运行。
|
|
6
|
+
|
|
7
|
+
其他分支或相邻 worktree 各自维护自己的 Compose、数据和产物,当前分支不得引用。当前 worktree 固定使用 `kite-main-dist-*` 命名空间、`172.31.89.0/24` 网段和 38xxx/39xxx/40xxx/41xxx/42xxx 宿主端口;相邻 `aun-distributed` worktree 保留 `kite-dist-*`、`172.31.88.0/24` 和旧端口。两套环境可以同时存在,不得共享 project、容器名、网络、子网、端口、可变镜像 tag、Redis 卷或 bind mount。当前 worktree 的服务端/Tester 分支产物使用 `*-main-dist:*` tag;MySQL、Redis、PostgreSQL、Node、Go 等固定版本基础镜像可以共享。目录名、镜像 tag 和容器名不能单独证明来源;运行时以 Compose label、bind mount、镜像 ID 和源码哈希为最终证据。
|
|
8
|
+
|
|
9
|
+
节点角色、节点启动、服务启停、注册发现和配置恢复的系统性流程见
|
|
10
|
+
[分布式 AUN 节点与服务启动流程](../../extensions/services/docs/分布式AUN节点与服务启动流程.md)。
|
|
11
|
+
|
|
12
|
+
## 适用范围
|
|
13
|
+
|
|
14
|
+
- 当前 worktree:`D:\modelunion\kite`
|
|
15
|
+
- 三节点单域集群:`D:\modelunion\kite\docker-deploy\docker-compose.distributed.yml`
|
|
16
|
+
- 本地真实域名双域:两域基础 Compose + 域覆盖 + `D:\modelunion\kite\docker-deploy\docker-compose.agentid-federation.yml`
|
|
17
|
+
- 隔离双域 federation:`D:\modelunion\kite\docker-deploy\federation-test\docker-compose.yml`
|
|
18
|
+
- 分布式 Tester:`D:\modelunion\kite\docker-deploy\docker-compose.distributed-testers.yml`
|
|
19
|
+
- 分布式 Cross-SDK:`D:\modelunion\kite\aun-sdk-core\tests\cross-sdk\docker-compose.cross-sdk.distributed.yml`
|
|
20
|
+
- 本地 TLS 证书:只用于本地测试,SDK 侧统一 `AUN_ENV=development`、`AUN_VERIFY_SSL=0`
|
|
21
|
+
- 本阶段仅跳过文件名包含 `reconnect` 或 `mail` 的测试;其余发现到的 Python SDK integration/E2E 文件均必须运行并通过。
|
|
22
|
+
- 带 `if __name__ == "__main__"` 的脚本使用 `python <file>` 直接执行,纯 pytest 文件使用 `python -m pytest -q <file>`;每个文件分别记录日志、退出码和运行方式。pytest 退出码 `5` 表示未收集到测试,必须先核对 runner 选择与测试清单,不能直接归因于服务失败。
|
|
23
|
+
|
|
24
|
+
身份数据保护、禁止清库、禁止重建固定 AID、断网测试和 Go 1.24 规则继承主指南,在分布式环境中同样是硬约束。
|
|
25
|
+
|
|
26
|
+
### Git 与产物边界
|
|
27
|
+
|
|
28
|
+
不能忽略整个 `docker-deploy/`,因为 Dockerfile、Compose、环境示例、部署脚本模板和材料校验脚本都是需要随分支维护的源码。根 `.gitignore` 必须精确忽略以下本地资产:
|
|
29
|
+
|
|
30
|
+
- `docker-deploy/data-dist/`、`docker-deploy/federation-test/data-dist/`:分布式 CA、AID、数据库和 Tester 状态
|
|
31
|
+
- `docker-deploy/data/`、`docker-deploy/data-agentid-cn/`:本地真实域名双域的固定材料和数据库
|
|
32
|
+
- `docker-deploy/offline-images/`、`docker-deploy/agentid.pub/online/go/`、`docker-deploy/agentid.pub/online/bootstrap-materials.tar.gz`:生成的线上三文件替换包与一次性辅助归档
|
|
33
|
+
- `docker-deploy/*/local.env`、`docker-deploy/*/materials.json`、日志和临时构建目录:本机环境、材料指纹与运行产物
|
|
34
|
+
|
|
35
|
+
`docker-deploy/agentid.pub/online/go/docker-compose.yml`、`docker-deploy/agentid.pub/online/go/unpack.sh`、`docker-deploy/scripts/domain_materials.py` 和各 Compose 文件不得被忽略。提交前用 `git check-ignore -v` 核对具体材料路径,不能用目录名或 `git status` 没展开来推断。
|
|
36
|
+
|
|
37
|
+
## 本地真实域名双域与公网环境边界
|
|
38
|
+
|
|
39
|
+
`agentid.pub` 与 `agentid.cn` 在本机各运行一套“分布式控制模型的单节点形态”,共同组成当前真实域名双域 Docker 跨域环境。两域复用同一服务镜像,但各自拥有独立 Issuer CA、10 个服务 AID、MySQL、Redis、workspace、Compose project 和宿主端口;只共享 `kite-agentid-federation-net` 上的 Kite 业务节点。
|
|
40
|
+
|
|
41
|
+
- `D:\modelunion\kite\docker-deploy\agentid.pub`:引用固定 `data`,project 为 `kite-single`,应用容器为 `kite-app`。
|
|
42
|
+
- `D:\modelunion\kite\docker-deploy\agentid.cn`:引用固定 `data-agentid-cn`,project 为 `kite-agentid-cn-local`,应用容器为 `kite-agentid-cn-local-app`。
|
|
43
|
+
- `D:\modelunion\kite\docker-deploy\docker-compose.agentid-federation.yml`:只给两域 `kite` service 增加共享网络和 `{svc}.{issuer}` alias,不共享或代理 MySQL、Redis。
|
|
44
|
+
- `docker-deploy/agentid.pub/online/go/` 与 `docker-deploy/agentid.cn/online/go/`:分别用于公网主机部署;线上机器不加载本地 federation overlay。
|
|
45
|
+
|
|
46
|
+
本地 Docker 与公网服务器使用相同域名,但不是同一运行环境。测试证据必须记录目标层:本地以 Compose label、容器镜像 ID、mount 和 `docker logs` 为准;公网以实际 DNS/TLS、公网 RPC 结果及两域采集日志为准。不得因为域名相同,把本地成功写成线上成功。
|
|
47
|
+
|
|
48
|
+
这两个真实域不得使用 `prepare_dist_materials.py`、`federation-test/setup_certs.py` 或 `federation-test/tests/setup_aids.py`。这些脚本只用于获准创建 `dist-*` 隔离身份;拿它们补真实域材料会改变身份根。任何真实域固定身份、证书、数据库的新增、覆盖、删除或补登记都必须先取得明确授权。
|
|
49
|
+
|
|
50
|
+
## 环境命名
|
|
51
|
+
|
|
52
|
+
| 环境 | 域名 | 数据目录 | Compose project | 主要容器 | 宿主机入口 |
|
|
53
|
+
| --- | --- | --- | --- | --- | --- |
|
|
54
|
+
| 三节点分布式 | `dist-agentid.pub` | `D:\modelunion\kite\docker-deploy\data-dist` | `kite-main-dist-worktree` | `kite-main-dist-aun-control`, `kite-main-dist-aun-node-a`, `kite-main-dist-aun-node-b` | `https://localhost:39876` |
|
|
55
|
+
| 分布式 SDK Tester | `dist-agentid.pub` | `...\data-dist\sdk-testers` | `kite-main-dist-sdk-testers` | `main-dist-python-sdk-tester`, `main-dist-go-sdk-tester`, `main-dist-ts-sdk-tester`, `main-dist-js-sdk-tester` | Docker internal |
|
|
56
|
+
| 分布式 cross-SDK | `dist-agentid.pub` | `...\aun-sdk-core\tests\cross-sdk\data-dist` | `kite-main-dist-cross-sdk` | `main-dist-cross-sdk-*` | Docker internal |
|
|
57
|
+
| 本地真实域名双域 A | `agentid.pub` | `...\docker-deploy\data` | `kite-single` | `kite-app`, `kite-mysql`, `kite-redis` | Gateway `20001`、Console `19876` |
|
|
58
|
+
| 本地真实域名双域 B | `agentid.cn` | `...\docker-deploy\data-agentid-cn` | `kite-agentid-cn-local` | `kite-agentid-cn-local-app`, `-mysql`, `-redis` | Gateway `42001`、Console `42876`、NameService `42443`、Storage `42470`、Group `42480`、MySQL `8406` |
|
|
59
|
+
| 隔离双域 federation | `dist-aid.com`, `dist-aid.net` | `...\docker-deploy\federation-test\data-dist` | `kite-main-dist-federation` | `main-dist-federation-kite-a`, `main-dist-federation-kite-b`, `main-dist-client-a`, `main-dist-client-b` | `41876`, `42876` |
|
|
60
|
+
|
|
61
|
+
`dist-*` 环境使用全新域名,默认不复制真实域数据库。其 CA、AID、TLS 材料只生成或复制到当前 worktree 的 `data-dist`,不要与 `docker-deploy/data`、`docker-deploy/data-agentid-cn` 或其他 worktree 共享运行时目录。
|
|
62
|
+
|
|
63
|
+
### 从其他 worktree 接管既有 `data-dist`
|
|
64
|
+
|
|
65
|
+
如果当前 worktree 尚无 `data-dist`,但其他 worktree 已有通过验收的固定分布式环境,优先采用停写后的整套冷克隆,而不是用既有证书搭配空数据库重新启动。固定服务证书必须在同一快照的 `aun_cert.agentid_cert` 中存在有效记录;MySQL、PostgreSQL、节点本地 WAL/状态、共享存储和 SDK Tester 身份也可能互相引用。
|
|
66
|
+
|
|
67
|
+
接管必须同时满足以下边界:
|
|
68
|
+
|
|
69
|
+
- 先停止来源 worktree 的分布式服务、Tester 和 cross-SDK project,确认没有容器继续挂载来源目录;严禁在线复制正在写入的 MySQL、PostgreSQL 或节点目录。
|
|
70
|
+
- 目标 `data-dist` 必须不存在或为空。整套冷克隆至少包含 `mysql`、`postgres`、`CA`、`certs`、`AIDs`、`control`、`aun-node-a`、`aun-node-b`、`storage-shared`、`sdk-tester-aun` 和 `sdk-testers`;不得只复制 CA、证书、AID、MySQL 或节点目录中的一部分。
|
|
71
|
+
- `.env.distributed` 不得被 example 覆盖。保留当前文件前要逐项比对 Issuer、MySQL/PostgreSQL 凭据、控制令牌、镜像、project/container/network 前缀、子网和端口;当前 worktree 必须保持 `kite-main-dist-*`、`172.31.89.0/24` 与新端口,不能沿用来源 worktree 的 Docker 命名空间。
|
|
72
|
+
- 克隆完成后,来源与目标成为两套独立资产。后续不得共享目录、交叉挂载或同时用同一容器名接管;每次启动都执行“运行时来源强制核验”。
|
|
73
|
+
- 启动业务服务前,先只读核对根 CA/Registry CA 哈希、十个内置服务证书的 SHA-256,以及证书在克隆后 MySQL `aun_cert.agentid_cert` 中的 `lifecycle_state=active_signing`、`cert_state=1` 记录。任一不一致即停止,不得补登记、重签、清库或局部重复制。
|
|
74
|
+
|
|
75
|
+
整套冷克隆会继承来源环境的历史业务数据,适合当前分支接管并继续回归。只有明确需要全新隔离身份和空业务库时,才在用户授权后运行 `prepare_dist_materials.py` 并完成新证书注册验收;“新建空目录 + 复制旧证书”不是合法初始化方式。
|
|
76
|
+
|
|
77
|
+
默认单实例和分布式环境必须长期保持两套独立测试窗口:
|
|
78
|
+
|
|
79
|
+
- 默认单实例只使用 `D:\modelunion\kite\docker-deploy\docker-compose.yml`、域覆盖、`docker-deploy/data*`、`kite-*` 容器、默认端口和默认 Tester。
|
|
80
|
+
- 分布式环境只使用当前 worktree 的 `docker-compose.distributed*.yml` / federation Compose、`dist-agentid.pub` / `dist-aid.*`、`data-dist`、`kite-main-dist-*` / `main-dist-*` 容器和独立端口。
|
|
81
|
+
- 不要在分布式测试中 exec、restart、down 默认单实例的 `kite-app`、`kite-python-sdk-tester`、`kite-go-tester`、`kite-ts-tester`、`kite-js-tester` 等容器。
|
|
82
|
+
|
|
83
|
+
`root.crt`、`ca.registry.aun.crt`、`ca.registry.aun.key` 以当前 worktree 的 `certool/certs` 为唯一来源。分布式环境不重新生成 root CA 或 registry CA;只在获得明确授权后为 `dist-*` 域生成 issuer CA、内置服务 AID 证书、分布式本地泛域 TLS 证书,并生成 worker 使用的本地 `aun-ca-bundle.crt`。
|
|
84
|
+
|
|
85
|
+
### 运行时来源强制核验
|
|
86
|
+
|
|
87
|
+
三节点环境启动后执行:
|
|
88
|
+
|
|
89
|
+
```powershell
|
|
90
|
+
function Resolve-DockerBindSource([string]$source) {
|
|
91
|
+
if ($source -match '^/run/desktop/mnt/host/([A-Za-z])/(.*)$') {
|
|
92
|
+
$source = "$($Matches[1]):\$($Matches[2] -replace '/', '\')"
|
|
93
|
+
}
|
|
94
|
+
[IO.Path]::GetFullPath($source)
|
|
95
|
+
}
|
|
96
|
+
$distRoot = (Resolve-Path D:\modelunion\kite).Path
|
|
97
|
+
$baseCompose = [IO.Path]::GetFullPath((Join-Path $distRoot 'docker-deploy\docker-compose.distributed.yml'))
|
|
98
|
+
$names = @(
|
|
99
|
+
'kite-main-dist-mysql', 'kite-main-dist-postgres', 'kite-main-dist-redis', 'kite-main-dist-aun-dns',
|
|
100
|
+
'kite-main-dist-aun-control', 'kite-main-dist-aun-node-a', 'kite-main-dist-aun-node-b'
|
|
101
|
+
)
|
|
102
|
+
$containers = docker inspect $names | ConvertFrom-Json
|
|
103
|
+
foreach ($container in $containers) {
|
|
104
|
+
$files = $container.Config.Labels.'com.docker.compose.project.config_files' -split ','
|
|
105
|
+
if (-not ($files | Where-Object { [IO.Path]::GetFullPath($_) -ieq $baseCompose })) {
|
|
106
|
+
throw "$($container.Name) 未加载三节点基础 Compose: $($files -join ',')"
|
|
107
|
+
}
|
|
108
|
+
if ($files | Where-Object { -not ([IO.Path]::GetFullPath($_)).StartsWith($distRoot, [StringComparison]::OrdinalIgnoreCase) }) {
|
|
109
|
+
throw "$($container.Name) 混入其他 worktree Compose: $($files -join ',')"
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
$mysql = $containers | Where-Object Name -eq '/kite-main-dist-mysql'
|
|
113
|
+
$mysqlSource = ($mysql.Mounts | Where-Object Destination -eq '/var/lib/mysql').Source
|
|
114
|
+
$expectedMysql = [IO.Path]::GetFullPath((Join-Path $distRoot 'docker-deploy\data-dist\mysql'))
|
|
115
|
+
if ((Resolve-DockerBindSource $mysqlSource) -ine $expectedMysql) { throw "分布式 MySQL 数据目录错误: $mysqlSource" }
|
|
116
|
+
"distributed preflight ok"
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
隔离 `dist-aid.*` federation 执行以下检查。所有 Compose label 和 bind mount 必须位于 `D:\modelunion\kite`;本地 `agentid.pub/agentid.cn` 的来源核验见后文专节:
|
|
120
|
+
|
|
121
|
+
```powershell
|
|
122
|
+
function Resolve-DockerBindSource([string]$source) {
|
|
123
|
+
if ($source -match '^/run/desktop/mnt/host/([A-Za-z])/(.*)$') {
|
|
124
|
+
$source = "$($Matches[1]):\$($Matches[2] -replace '/', '\')"
|
|
125
|
+
}
|
|
126
|
+
[IO.Path]::GetFullPath($source)
|
|
127
|
+
}
|
|
128
|
+
$distRoot = (Resolve-Path D:\modelunion\kite).Path
|
|
129
|
+
$fedRoot = [IO.Path]::GetFullPath((Join-Path $distRoot 'docker-deploy\federation-test'))
|
|
130
|
+
$baseCompose = [IO.Path]::GetFullPath((Join-Path $fedRoot 'docker-compose.yml'))
|
|
131
|
+
$names = @(
|
|
132
|
+
'main-dist-federation-mysql-a', 'main-dist-federation-postgres-a', 'main-dist-federation-redis-a',
|
|
133
|
+
'main-dist-federation-kite-a', 'main-dist-client-a',
|
|
134
|
+
'main-dist-federation-mysql-b', 'main-dist-federation-postgres-b', 'main-dist-federation-redis-b',
|
|
135
|
+
'main-dist-federation-kite-b', 'main-dist-client-b'
|
|
136
|
+
)
|
|
137
|
+
$containers = docker inspect $names | ConvertFrom-Json
|
|
138
|
+
foreach ($container in $containers) {
|
|
139
|
+
$files = $container.Config.Labels.'com.docker.compose.project.config_files' -split ','
|
|
140
|
+
if (-not ($files | Where-Object { [IO.Path]::GetFullPath($_) -ieq $baseCompose })) {
|
|
141
|
+
throw "$($container.Name) 未加载双域基础 Compose: $($files -join ',')"
|
|
142
|
+
}
|
|
143
|
+
if ($files | Where-Object { -not ([IO.Path]::GetFullPath($_)).StartsWith($distRoot, [StringComparison]::OrdinalIgnoreCase) }) {
|
|
144
|
+
throw "$($container.Name) 混入其他 worktree Compose: $($files -join ',')"
|
|
145
|
+
}
|
|
146
|
+
$foreignMount = $container.Mounts | Where-Object {
|
|
147
|
+
$_.Type -eq 'bind' -and -not (Resolve-DockerBindSource $_.Source).StartsWith($distRoot, [StringComparison]::OrdinalIgnoreCase)
|
|
148
|
+
}
|
|
149
|
+
if ($foreignMount) { throw "$($container.Name) 混入其他 worktree mount: $($foreignMount.Source -join ',')" }
|
|
150
|
+
}
|
|
151
|
+
"federation preflight ok"
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
任何一个容器的 Compose label 或 bind mount 不在 `D:\modelunion\kite` 都属于混合环境,必须停止对应分布式 project 后从当前 worktree 整套重建;不得只替换单个容器,也不得加 `-v`。
|
|
155
|
+
|
|
156
|
+
## 三节点分布式集群
|
|
157
|
+
|
|
158
|
+
### Group-Go 三节点覆盖层
|
|
159
|
+
|
|
160
|
+
需要在三节点环境持续运行 Group-Go 并执行 SDK integration/E2E 时,使用专用覆盖层;它只在容器内把 Go候选 manifest 挂载为 `module.md`,宿主 `extensions/services/group/module.md` 仍保持 Python:
|
|
161
|
+
|
|
162
|
+
```powershell
|
|
163
|
+
cd D:\modelunion\kite\docker-deploy
|
|
164
|
+
docker compose --env-file .env.distributed `
|
|
165
|
+
-f docker-compose.distributed.yml `
|
|
166
|
+
-f docker-compose.distributed.group-go.yml `
|
|
167
|
+
up -d --force-recreate aun-control aun-node-a aun-node-b
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
服务仍按控制中心 desired-state 调度。当前 CoreDNS 将 `group.dist-agentid.pub` 指向 `aun-node-a`,因此执行 SDK测试前应确认 registry 中唯一 active Group实例为 `aun-node-a:group`,且 `group.status` 返回 `implementation=go`。同一 DB/schema 不得同时运行 Python Group和Group-Go。
|
|
171
|
+
|
|
172
|
+
### 材料与镜像核验
|
|
173
|
+
|
|
174
|
+
日常测试只复用既有 `.env.distributed`、`data-dist/CA`、`data-dist/AIDs`、`data-dist/certs` 和数据库,不重新生成材料:
|
|
175
|
+
|
|
176
|
+
```powershell
|
|
177
|
+
cd D:\modelunion\kite\docker-deploy
|
|
178
|
+
$required = @(
|
|
179
|
+
'.env.distributed',
|
|
180
|
+
'data-dist\CA\root\root.crt',
|
|
181
|
+
'data-dist\CA\registry\ca.registry.aun.crt',
|
|
182
|
+
'data-dist\CA\issuer\ca.dist-agentid.pub.crt',
|
|
183
|
+
'data-dist\certs\aun-ca-bundle.crt',
|
|
184
|
+
'data-dist\mysql'
|
|
185
|
+
)
|
|
186
|
+
$missing = $required | Where-Object { -not (Test-Path $_) }
|
|
187
|
+
if ($missing) { throw "分布式固定材料缺失,停止测试,禁止自动重建: $($missing -join ', ')" }
|
|
188
|
+
docker image inspect docker-deploy-kite-main-dist:latest aun-sdk-tester-main-dist:latest mysql:8.0 postgres:16-alpine redis:7-alpine coredns/coredns:1.11.3 | Out-Null
|
|
189
|
+
if ($LASTEXITCODE -ne 0) { throw '分布式镜像未完成离线准备,停止测试' }
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
日常断网测试只复用上面的本地镜像。服务端或 Python Tester 源码/依赖变化时,退出业务测试阶段,在独立依赖准备阶段执行 `docker compose --env-file .env.distributed -f docker-compose.build.yml build kite sdk-tester`;基础镜像或构建缓存不完整时停止,不得在业务测试阶段联网补齐。
|
|
193
|
+
|
|
194
|
+
服务端镜像必须在 `D:\modelunion\kite\docker-deploy` 执行上面的 build。构建后至少对 Gateway、Message、Group 的本次关键文件做宿主机/镜像 SHA-256 对比;任一不同即判定镜像不是当前源码,禁止启动或打包:
|
|
195
|
+
|
|
196
|
+
```powershell
|
|
197
|
+
$repo = (Resolve-Path ..).Path
|
|
198
|
+
$files = @(
|
|
199
|
+
'extensions/services/gateway/service_plane.py',
|
|
200
|
+
'extensions/services/message/go/cmd/message-go/tail_history.go',
|
|
201
|
+
'extensions/services/group/go/internal/service/reverse_messages.go'
|
|
202
|
+
)
|
|
203
|
+
$hostHashes = $files | ForEach-Object { (Get-FileHash -Algorithm SHA256 (Join-Path $repo $_)).Hash.ToLower() }
|
|
204
|
+
$imagePaths = $files | ForEach-Object { "/app/$_" }
|
|
205
|
+
$image = docker run --rm --network none --entrypoint sha256sum docker-deploy-kite-main-dist:latest $imagePaths
|
|
206
|
+
$inside = $image | ForEach-Object { ($_ -split '\s+')[0].ToLower() }
|
|
207
|
+
if (Compare-Object $hostHashes $inside) { throw '分布式服务镜像不是当前 worktree 源码,停止' }
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
启动后还必须执行“运行时来源强制核验”。仅仅镜像哈希相同但 Compose label 或 `data-dist` mount 指向其他 worktree,仍然属于混合环境。
|
|
211
|
+
|
|
212
|
+
`prepare_dist_materials.py` 只用于首次创建独立分布式环境,并且会写入 CA、服务 AID 和 TLS 材料。只有用户明确同意创建或重建身份材料后才能执行;日常测试不得使用 `--force`。`.env.distributed` 已存在时也不得用 example 覆盖。
|
|
213
|
+
|
|
214
|
+
关键默认值:
|
|
215
|
+
|
|
216
|
+
- `AUN_IMAGE=docker-deploy-kite-main-dist:latest`
|
|
217
|
+
- `AUN_SDK_TESTER_IMAGE=aun-sdk-tester-main-dist:latest`
|
|
218
|
+
- `AUN_TS_TESTER_IMAGE=aun-ts-sdk-tester-main-dist:local`
|
|
219
|
+
- `AUN_JS_TESTER_IMAGE=aun-js-sdk-tester-main-dist:local`
|
|
220
|
+
- `AUN_ISSUER_DOMAIN=dist-agentid.pub`
|
|
221
|
+
- `AUN_CONTROL_BASE_URL=https://aun-console.dist-agentid.pub:19876`
|
|
222
|
+
- `AUN_GATEWAY_URL=wss://gateway.dist-agentid.pub:20001/aun`
|
|
223
|
+
- `AUN_WORKER_SUPERVISOR_MODE=auto`
|
|
224
|
+
- `AUN_VERIFY_SSL=0`
|
|
225
|
+
- `AUN_CONTROL_STORE_BACKEND=mysql`
|
|
226
|
+
- `AUN_CLUSTER_NODES=aun-control:control_master:true:aun-control:managed,aun-node-a:worker_node:false:aun-node-a:managed,aun-node-b:worker_node:false:aun-node-b:managed`
|
|
227
|
+
|
|
228
|
+
Compose 只传 MySQL 的 host、port、user、password,不配置 `KITE_DB_DATABASE`、`KITE_DB_DSN` 或服务专用库名。每个服务使用代码中与 Python 历史实现一致的默认库名;AUN Console 默认使用 `aun_dashboard`。
|
|
229
|
+
|
|
230
|
+
control master 会把 AUN 纳管服务的可达 endpoint 上报到同一个
|
|
231
|
+
aun_console 注册中心。worker 上的业务服务优先从注册中心发现 Gateway
|
|
232
|
+
`business_ws`,nameservice 在生成 302 跳转时优先使用注册中心的
|
|
233
|
+
`public_http`,没有注册中心记录时才回退到本地域名 + 默认端口。
|
|
234
|
+
storage 的数据平面原生 HTTPS 地址仍由 storage RPC 自身按业务语义返回,不作为
|
|
235
|
+
Gateway service-plane 自动连接路径。
|
|
236
|
+
|
|
237
|
+
默认宿主机端口映射和注册中心公开 endpoint:
|
|
238
|
+
|
|
239
|
+
| 服务 | 容器监听 | 宿主机端口变量 | 默认宿主机端口 | 注册中心公开 host |
|
|
240
|
+
| --- | --- | --- | --- | --- |
|
|
241
|
+
| AUN Console / 控制中心 / 注册中心 / 配置中心 | `19876` | `AUN_CONSOLE_PORT` | `39876` | `aun-console.dist-agentid.pub` |
|
|
242
|
+
| Gateway client plane | `20001` | `GATEWAY_PORT` | `40001` | `gateway.dist-agentid.pub` |
|
|
243
|
+
| Name Service HTTPS | `443` | `NS_HTTPS_PORT` | `38443` | `dist-agentid.pub` |
|
|
244
|
+
| Storage HTTPS | `9470` | `STORAGE_PORT` | `39470` | `storage.dist-agentid.pub` |
|
|
245
|
+
| Group HTTP | `9480` | `GROUP_PORT` | `39480` | `group.dist-agentid.pub` |
|
|
246
|
+
| Leaderboard HTTP | `19882` | `LEADERBOARD_PUBLIC_PORT` | `39882` | `leaderboard.dist-agentid.pub` |
|
|
247
|
+
| AID Custody HTTP | `18630` | `AID_CUSTODY_PUBLIC_PORT` | `38630` | `aid_custody.dist-agentid.pub` |
|
|
248
|
+
| Stream HTTP | `9490` | `STREAM_PUBLIC_PORT` | `39490` | `stream.dist-agentid.pub` |
|
|
249
|
+
| Service Proxy HTTP | `19890` | `SERVICE_PROXY_PUBLIC_PORT` | `39890` | `proxy.dist-agentid.pub` |
|
|
250
|
+
|
|
251
|
+
worker 节点默认只配置 `AUN_PRIVATE_HOST=aun-node-a/aun-node-b` 和各服务
|
|
252
|
+
容器监听端口。未配置公网 host 的 worker 服务不会上报 `public_http`,但会
|
|
253
|
+
上报可供 Docker 网络内服务发现使用的 `private_http`;如果后续需要把 worker
|
|
254
|
+
上的 gateway/storage/group 等服务也暴露到宿主机,需要为对应节点单独配置
|
|
255
|
+
公网 host/port,并避免与默认单实例的端口冲突。
|
|
256
|
+
|
|
257
|
+
`aun_console` 的 Dashboard 统计数据和控制中心配置/注册/desired-state
|
|
258
|
+
数据共用代码默认的 MySQL 数据库 `aun_dashboard`,Compose 不重复覆盖库名。控制中心不再使用
|
|
259
|
+
`data-dist/control/control-plane/control_plane.sqlite3` 作为分布式环境的
|
|
260
|
+
主存储;该 SQLite 路径只作为未配置 MySQL backend 时的本地回退。
|
|
261
|
+
|
|
262
|
+
首次获准执行时,`prepare_dist_materials.py` 会创建 `docker-deploy/data-dist`:
|
|
263
|
+
|
|
264
|
+
- `CA/root/root.crt`:从当前 worktree 的 `certool/certs` 复制
|
|
265
|
+
- `CA/registry/ca.registry.aun.crt`:从当前 worktree 的 `certool/certs` 复制
|
|
266
|
+
- `CA/issuer/ca.dist-agentid.pub.crt` 和 `.key`:使用稳定 registry CA 签发
|
|
267
|
+
- `AIDs/{service}.dist-agentid.pub`:内置服务 AID 证书和私钥
|
|
268
|
+
- `certs/`:运行时可读的 CA 公钥副本、`aun-ca-bundle.crt`、`wildcard.dist-agentid.pub.crt/key`
|
|
269
|
+
|
|
270
|
+
脚本不复制默认单实例数据库,也不复制当前 worktree 的 `docker-deploy/data`。
|
|
271
|
+
|
|
272
|
+
### 启动
|
|
273
|
+
|
|
274
|
+
```powershell
|
|
275
|
+
cd D:\modelunion\kite\docker-deploy
|
|
276
|
+
docker compose --env-file .env.distributed -f docker-compose.distributed.yml config
|
|
277
|
+
docker compose --env-file .env.distributed -f docker-compose.distributed.yml up -d
|
|
278
|
+
docker compose --env-file .env.distributed -f docker-compose.distributed.yml ps
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
查看控制台:
|
|
282
|
+
|
|
283
|
+
```powershell
|
|
284
|
+
https://localhost:39876
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
进入 `控制中心` 页面,确认能看到:
|
|
288
|
+
|
|
289
|
+
- `control master`
|
|
290
|
+
- `worker node`:`aun-node-a`、`aun-node-b`
|
|
291
|
+
- 节点心跳、控制模式、来源、公网 IP、内网 IP、启用/停用状态
|
|
292
|
+
- control master 默认启用,`AUN_CLUSTER_NODES` 中配置的 worker 默认停用,控制模式默认 `managed`
|
|
293
|
+
- worker 容器运行完整 `python main.py --no-tls` Kite 实例,启动 kernel + watchdog,并通过 `AUN_LAUNCHER_DEFER_MODULE_START=true` 延迟 AUN 业务模块自动启动
|
|
294
|
+
- worker 容器默认以 `auto` 接入,实际执行 `managed`、`report_only` 还是 `unmanaged` 由控制中心节点配置下发;`managed` 模式由 launcher 根据 desired-state 走标准模块生命周期启停模块
|
|
295
|
+
- 未配置但动态注册上来的节点可以显示在控制中心,默认 `unmanaged`、停用且服务目标全为 stopped;在控制台启用或编辑后会持久化为已配置节点记录
|
|
296
|
+
- 每个节点都显示同一套 AUN 纳管服务清单,并可通过开关写入 desired-state
|
|
297
|
+
- 期望服务槽、观察到的服务槽、服务准入策略
|
|
298
|
+
- worker launcher 默认通过 `AUN_SUPERVISOR_WATCH_ENABLED=1` 与 control master 建立 `/internal/v1/nodes/{node_id}/watch` WebSocket watch;控制台切换节点或服务开关后应立即看到 `control watch event type=desired_state.changed`,HTTP 定时 report 只作为心跳和兜底同步
|
|
299
|
+
- 浏览器控制中心页面会通过当前登录 token 连接 `/api/v1/control/watch`,开关写入后进入短时快速刷新,页面上的 target / observed / action 不应等待 10 秒普通轮询才收敛
|
|
300
|
+
|
|
301
|
+
控制中心表与 Dashboard rollup 表在同一 MySQL 库中,可用以下命令核查:
|
|
302
|
+
|
|
303
|
+
```powershell
|
|
304
|
+
docker exec kite-main-dist-mysql sh -lc 'mysql -uroot -p"$MYSQL_ROOT_PASSWORD" -e "SHOW TABLES FROM aun_dashboard;"'
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
查看日志:
|
|
308
|
+
|
|
309
|
+
```powershell
|
|
310
|
+
docker logs --since 10m kite-main-dist-aun-control
|
|
311
|
+
docker compose --env-file .env.distributed -f docker-compose.distributed.yml logs -f aun-node-a
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
worker 节点默认从控制中心同步控制模式。`managed` 模式会按 desired-state 执行启停;动作由 worker 本机 launcher 调用现有 `launcher.start_module` / `launcher.stop_module` 路径完成,watchdog 继续负责健康监控和异常重启。业务服务集群化仍不作为本阶段验收重点。control endpoint 使用 `wildcard.dist-agentid.pub.crt/key` 开启本地 HTTPS/WSS;nameservice 所在节点也使用同一证书提供 HTTPS。三机 Docker 网络内的 `aun-dns` 会把已部署服务域名解析到对应 node,把未知的 `*.dist-agentid.pub` 动态 AID 域名解析到当前承载 nameservice 的节点;SDK discovery 必须先访问 `https://{aid}/.well-known/aun-gateway`,例如 `https://alice.dist-agentid.pub/.well-known/aun-gateway` 或 `https://eve-xxx.dist-agentid.pub/.well-known/aun-gateway`,失败后才回退 `https://gateway.dist-agentid.pub/.well-known/aun-gateway`。
|
|
315
|
+
|
|
316
|
+
服务开关的即时性可用以下日志验收:
|
|
317
|
+
|
|
318
|
+
```powershell
|
|
319
|
+
docker exec kite-main-dist-aun-node-a sh -lc 'grep -a "control watch\|control supervisor diff\|auth" /data/kite-workspace/app/launcher/log/latest.log | tail -n 30'
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
期望看到 `control supervisor diff reason=watch:desired_state.changed`,而不是等下一次 10 秒轮询才执行。停用服务时,launcher 会先把 per-module target 同步给本机 kernel,避免 kernel 自动伸缩重新拉起控制中心目标为 `stopped` 的模块。
|
|
323
|
+
|
|
324
|
+
### 分布式 SDK tester
|
|
325
|
+
|
|
326
|
+
四语言 SDK Tester 使用独立 Compose project,不复用默认单实例或相邻 worktree 的 Tester 容器和数据目录。它们只挂载当前 worktree 的 SDK 源码、`extensions` 与共享契约 `aun-sdk-core/tests/contracts -> /contracts:ro`,并统一设置 `AUN_CONTRACTS_ROOT=/contracts`;连接三节点分布式网络 `kite-main-dist-worktree_kite-distributed-net`,测试数据写入当前 worktree 的 `docker-deploy/data-dist/sdk-testers/*`。
|
|
327
|
+
|
|
328
|
+
第一次从当前 worktree 接管 Tester,或 Compose/镜像发生变化时,必须在独立依赖准备阶段重建容器,使 Compose label 和 bind mount 从旧 worktree 切到当前目录。五个依赖卷在 Compose 中声明为带 `kite-main-dist-sdk-testers_` 前缀的 external volume,防止 Compose 自动新建空卷或随 project 清理;缺卷时应停止并完成离线克隆/准备。该阶段只使用已经离线准备的镜像与 named volume,入口不会执行 `apt`、`pip` 或 `npm install`:
|
|
329
|
+
|
|
330
|
+
```powershell
|
|
331
|
+
cd D:\modelunion\kite\docker-deploy
|
|
332
|
+
docker image inspect aun-sdk-tester-main-dist:latest aun-ts-sdk-tester-main-dist:local aun-js-sdk-tester-main-dist:local golang:1.24-bookworm | Out-Null
|
|
333
|
+
if ($LASTEXITCODE -ne 0) { throw '分布式 Tester 镜像未离线准备,停止' }
|
|
334
|
+
docker compose --env-file .env.distributed -f docker-compose.distributed-testers.yml up -d --force-recreate
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
断网业务测试阶段只启动已经完成依赖准备且来源正确的 Tester。先检查四个容器均存在,并验证 Compose label 与所有 bind mount 都在当前 worktree:
|
|
338
|
+
|
|
339
|
+
```powershell
|
|
340
|
+
cd D:\modelunion\kite\docker-deploy
|
|
341
|
+
function Resolve-DockerBindSource([string]$source) {
|
|
342
|
+
if ($source -match '^/run/desktop/mnt/host/([A-Za-z])/(.*)$') {
|
|
343
|
+
$source = "$($Matches[1]):\$($Matches[2] -replace '/', '\')"
|
|
344
|
+
}
|
|
345
|
+
[IO.Path]::GetFullPath($source)
|
|
346
|
+
}
|
|
347
|
+
$required = @('main-dist-python-sdk-tester', 'main-dist-go-sdk-tester', 'main-dist-ts-sdk-tester', 'main-dist-js-sdk-tester')
|
|
348
|
+
$existing = docker ps -a --format '{{.Names}}'
|
|
349
|
+
$missing = $required | Where-Object { $_ -notin $existing }
|
|
350
|
+
if ($missing) { throw "分布式 Tester 尚未完成离线依赖准备,停止测试: $($missing -join ', ')" }
|
|
351
|
+
$repoRoot = (Resolve-Path ..).Path
|
|
352
|
+
$testerCompose = [IO.Path]::GetFullPath((Resolve-Path .\docker-compose.distributed-testers.yml))
|
|
353
|
+
$containers = docker inspect $required | ConvertFrom-Json
|
|
354
|
+
foreach ($container in $containers) {
|
|
355
|
+
$files = $container.Config.Labels.'com.docker.compose.project.config_files' -split ','
|
|
356
|
+
if (-not ($files | Where-Object { [IO.Path]::GetFullPath($_) -ieq $testerCompose })) {
|
|
357
|
+
throw "$($container.Name) 不是当前分布式 Tester Compose 创建"
|
|
358
|
+
}
|
|
359
|
+
$foreign = $container.Mounts | Where-Object {
|
|
360
|
+
$_.Type -eq 'bind' -and -not (Resolve-DockerBindSource $_.Source).StartsWith($repoRoot, [StringComparison]::OrdinalIgnoreCase)
|
|
361
|
+
}
|
|
362
|
+
if ($foreign) { throw "$($container.Name) 混入其他 worktree mount: $($foreign.Source -join ', ')" }
|
|
363
|
+
}
|
|
364
|
+
docker compose --env-file .env.distributed -f docker-compose.distributed-testers.yml start
|
|
365
|
+
docker compose --env-file .env.distributed -f docker-compose.distributed-testers.yml ps
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
Docker Desktop 可能把 Windows bind source 返回为 `/run/desktop/mnt/host/<盘符>/...`;所有来源核验都必须先归一化,不能直接把这种路径判为其他 worktree。
|
|
369
|
+
|
|
370
|
+
断网业务测试阶段不得使用 `up` 或 `--force-recreate`。现有容器和 named volume 已具备 Linux 依赖时只执行 `start`;如果容器不存在、来源错误或依赖不完整,立即停止,回到独立依赖准备阶段,不能让业务测试访问外网。
|
|
371
|
+
|
|
372
|
+
容器名:
|
|
373
|
+
|
|
374
|
+
- `main-dist-python-sdk-tester`
|
|
375
|
+
- `main-dist-go-sdk-tester`
|
|
376
|
+
- `main-dist-ts-sdk-tester`
|
|
377
|
+
- `main-dist-js-sdk-tester`
|
|
378
|
+
|
|
379
|
+
四个 tester 默认环境:
|
|
380
|
+
|
|
381
|
+
- `AUN_TEST_ISSUER=dist-agentid.pub`
|
|
382
|
+
- `AUN_GATEWAY_AID=gateway.dist-agentid.pub`
|
|
383
|
+
- `AUN_VERIFY_SSL=0`
|
|
384
|
+
- `AUN_ENV=development`
|
|
385
|
+
- `AUN_DATA_ROOT=/data/aun`
|
|
386
|
+
- Go Tester 使用 `golang:1.24-bookworm` 和已准备的 named `GOMODCACHE`,并设置 `GOFLAGS=-mod=mod`、`GOPROXY=off`、`GOSUMDB=off`;当前 worktree 没有 `go/vendor`,不得写成 `-mod=vendor`
|
|
387
|
+
- JS browser E2E tester 使用依赖准备阶段已有的 Google Chrome,并设置
|
|
388
|
+
`AUN_TEST_DISABLE_LOCAL_DOCKER_PIN=1`,让浏览器使用 Docker DNS 访问
|
|
389
|
+
`gateway.dist-agentid.pub`,而不是把域名 pin 到容器内的 `127.0.0.1`
|
|
390
|
+
- tester 容器显式使用 `aun-dns` (`172.31.89.53`);它把动态 AID 域名解析到 nameservice,把 `gateway.dist-agentid.pub`、`storage.dist-agentid.pub` 等服务域名解析到当前部署节点。`nameservice` 不应通过 smoke/migration 脚本迁移;迁移任何带 DNS 名称的服务时,必须同步更新 Docker DNS/Corefile 和 compose 网络别名并重启相关容器;生产环境对应修改 DNS。
|
|
391
|
+
|
|
392
|
+
运行单元测试:
|
|
393
|
+
|
|
394
|
+
```powershell
|
|
395
|
+
docker exec main-dist-python-sdk-tester python -m pytest /workspace/python/tests/unit -q --tb=short --disable-warnings -k "not reconnect and not mail"
|
|
396
|
+
docker exec main-dist-go-sdk-tester sh -lc "cd /workspace/go && /usr/local/go/bin/go version && /usr/local/go/bin/go test ./... -mod=mod -count=1 -run '^(Test|Example)' -skip '(?i)(reconnect|mail)'"
|
|
397
|
+
docker exec main-dist-ts-sdk-tester bash -lc "cd /workspace/ts && npm run test:unit -- --no-file-parallelism --maxWorkers=1"
|
|
398
|
+
docker exec main-dist-js-sdk-tester bash -lc "cd /workspace/js && npm run test:unit -- --no-file-parallelism --maxWorkers=1"
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
停止 tester:
|
|
402
|
+
|
|
403
|
+
```powershell
|
|
404
|
+
cd D:\modelunion\kite\docker-deploy
|
|
405
|
+
docker compose --env-file .env.distributed -f docker-compose.distributed-testers.yml down
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
不要加 `-v`,除非明确要清空 `data-dist/sdk-testers` 和分布式 tester 的 named volumes。
|
|
409
|
+
|
|
410
|
+
### Python SDK smoke
|
|
411
|
+
|
|
412
|
+
优先使用 `main-dist-python-sdk-tester`。如果只想临时跑一个 Python 用例,也可以从同一个 Docker 网络临时起测试容器:
|
|
413
|
+
|
|
414
|
+
```powershell
|
|
415
|
+
cd D:\modelunion\kite\docker-deploy
|
|
416
|
+
$repo = (Resolve-Path ..).Path
|
|
417
|
+
docker run --rm --network kite-main-dist-worktree_kite-distributed-net `
|
|
418
|
+
-v "$repo\aun-sdk-core\python\src:/sdk/src:ro" `
|
|
419
|
+
-v "$repo\aun-sdk-core\python\tests:/tests:ro" `
|
|
420
|
+
-v "$repo\docker-deploy\data-dist\sdk-tester-aun:/data/aun" `
|
|
421
|
+
-e PYTHONPATH=/sdk/src `
|
|
422
|
+
-e AUN_ENV=development `
|
|
423
|
+
-e AUN_VERIFY_SSL=0 `
|
|
424
|
+
-e AUN_DATA_ROOT=/data/aun `
|
|
425
|
+
-e AUN_TEST_AUN_PATH=/data/aun/single-domain/persistent `
|
|
426
|
+
-e AUN_TEST_ISSUER=dist-agentid.pub `
|
|
427
|
+
-e AUN_TEST_ALICE_AID=alice.dist-agentid.pub `
|
|
428
|
+
-e AUN_TEST_BOB_AID=bobb.dist-agentid.pub `
|
|
429
|
+
aun-sdk-tester-main-dist:latest python -X utf8 /tests/integration_test_message_ack.py
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
按改动范围继续跑非 reconnect / 非 mail 用例。当前 Python 目录没有独立的
|
|
433
|
+
`e2e_test_v2_group_e2ee.py`;Group E2EE E2E 分散在 1DH wrap、slot 前缀隔离、
|
|
434
|
+
proximity、thought 和 recall 场景里。先跑已通过的主链路:
|
|
435
|
+
|
|
436
|
+
```powershell
|
|
437
|
+
docker exec main-dist-python-sdk-tester sh -lc "python -X utf8 /workspace/python/tests/integration_test_gap_fill.py && python -X utf8 /workspace/python/tests/e2e_test_v2_p2p_e2ee.py && python -X utf8 /workspace/python/tests/e2e_test_v2_1dh_wrap.py && python -X utf8 /workspace/python/tests/e2e_test_slot_id_separator.py && python -X utf8 /workspace/python/tests/e2e_test_proximity.py && python -X utf8 /workspace/python/tests/e2e_test_v2_thought.py"
|
|
438
|
+
docker exec main-dist-ts-sdk-tester bash -lc "cd /workspace/ts && node_modules/.bin/vitest run tests/integration/group-e2ee.test.ts tests/e2e/v2-group.test.ts tests/e2e/v2-thought.test.ts tests/e2e/slot-id-separator.test.ts --no-file-parallelism --maxWorkers=1"
|
|
439
|
+
docker exec main-dist-js-sdk-tester bash -lc "cd /workspace/js && node_modules/.bin/vitest run --environment jsdom tests/integration/v2-thought.test.ts --no-file-parallelism --maxWorkers=1 && npm run build && node_modules/.bin/playwright test --config=playwright.agentid-local.config.ts tests/e2e-browser/v2-group.spec.ts tests/e2e-browser/v2-thought.spec.ts --reporter=line"
|
|
440
|
+
docker exec main-dist-go-sdk-tester bash -lc "cd /workspace/go && /usr/local/go/bin/go test -tags integration -count=1 -run 'TestV2Group|TestV2Thought_FullFlow|TestSlotSeparatorE2E_GroupEncrypted|TestGroupUndecryptableEventOnly|TestGroupRecall' ."
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
Python encrypted group recall 去重当前仍需复核,单独运行并参考
|
|
444
|
+
`test-artifacts/distributed-test-buglist.md`:
|
|
445
|
+
|
|
446
|
+
```powershell
|
|
447
|
+
docker exec main-dist-python-sdk-tester sh -lc "python -X utf8 /workspace/python/tests/integration_test_group_recall.py"
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
### Cross-SDK 分布式 tester
|
|
451
|
+
|
|
452
|
+
分布式 cross-sdk 使用专用 compose 文件,不复用默认 `cross-sdk-*` 容器、`tests/cross-sdk/data` 或 `tests/cross-sdk/artifacts`。测试数据写入 `aun-sdk-core/tests/cross-sdk/data-dist`,产物写入 `aun-sdk-core/tests/cross-sdk/artifacts-dist`。TS/JS/Go 的五个离线依赖卷使用 `kite-main-dist-cross-sdk_` 前缀并声明为 external;不得复用相邻 worktree 的 `kite-dist-cross-sdk_*` 卷。
|
|
453
|
+
|
|
454
|
+
```powershell
|
|
455
|
+
cd D:\modelunion\kite\aun-sdk-core
|
|
456
|
+
docker image inspect aun-sdk-tester-main-dist:latest node:22-bookworm golang:1.24-bookworm | Out-Null
|
|
457
|
+
if ($LASTEXITCODE -ne 0) { throw '分布式 cross-SDK 镜像未完成离线准备,停止测试' }
|
|
458
|
+
docker compose --env-file ../docker-deploy/.env.distributed -f tests/cross-sdk/docker-compose.cross-sdk.distributed.yml config
|
|
459
|
+
docker compose --env-file ../docker-deploy/.env.distributed -f tests/cross-sdk/docker-compose.cross-sdk.distributed.yml up --force-recreate --abort-on-container-exit --exit-code-from dist-cross-sdk-runner
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
默认使用当前分支实际存在的 `cases.inbox-migration.json`。如需指定其他 cases 文件:
|
|
463
|
+
|
|
464
|
+
```powershell
|
|
465
|
+
$env:CROSS_SDK_CASES_BASENAME="cases.inbox-migration.json"
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
定向验收 Tail / History / Forward、A/T/H、Push Tail、重启恢复和坏密文推进时,使用本地 Git 忽略材料 `cases.message-windows.json`:
|
|
469
|
+
|
|
470
|
+
```powershell
|
|
471
|
+
$env:CROSS_SDK_CASES_BASENAME="cases.message-windows.json"
|
|
472
|
+
docker compose --env-file ../docker-deploy/.env.distributed -f tests/cross-sdk/docker-compose.cross-sdk.distributed.yml up --force-recreate --abort-on-container-exit --exit-code-from dist-cross-sdk-runner
|
|
473
|
+
```
|
|
474
|
+
|
|
475
|
+
该场景按 Python → TypeScript → Go → JavaScript 串行执行。Go Agent 必须使用 Go 1.24、`-tags crosssdk`、`GOPROXY=off` 和 `GOSUMDB=off`。`history_e2ee=false` 只用于隔离已知 E2EE 收件超时,不能作为 E2EE 验收结果。
|
|
476
|
+
|
|
477
|
+
分布式 cross-sdk 默认会为每个 agent 生成本次运行唯一 AID,避免持久 CA 中已有固定测试身份时出现 `IDENTITY_CONFLICT`。如果需要让四个 agent 使用同一个可读运行标识,可在启动前设置:
|
|
478
|
+
|
|
479
|
+
```powershell
|
|
480
|
+
$env:CROSS_SDK_RUN_ID="manual-$(Get-Date -Format yyyyMMddHHmmss)"
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
如需指定某个 agent 的固定身份,仍可显式设置 `CROSS_SDK_PY_AID`、`CROSS_SDK_TS_AID`、`CROSS_SDK_GO_AID`、`CROSS_SDK_JS_AID`。
|
|
484
|
+
|
|
485
|
+
跑完后清理容器即可,不要加 `-v`:
|
|
486
|
+
|
|
487
|
+
```powershell
|
|
488
|
+
docker compose --env-file ../docker-deploy/.env.distributed -f tests/cross-sdk/docker-compose.cross-sdk.distributed.yml down
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
## 本地 agentid.pub / agentid.cn 双域 Docker 跨域测试
|
|
492
|
+
|
|
493
|
+
### 定位与验收边界
|
|
494
|
+
|
|
495
|
+
这是当前真实域名的**本地双域 Docker 跨域测试环境**。两域都是分布式控制模型的单节点部署,已迁移服务默认使用 Go:Auth、CA、Gateway、Message、Group、Storage、Stream、NameService、Leaderboard、Service Proxy;AID Custody 仍使用 Python。两域必须使用同一个 `docker-deploy-kite:latest` 镜像,避免把镜像差异误判为跨域问题。
|
|
496
|
+
|
|
497
|
+
本环境验证的是本地完整调用链:
|
|
498
|
+
|
|
499
|
+
```text
|
|
500
|
+
本域 SDK -> 本域 Gateway -> 按 receiver/group/owner AID issuer 判域
|
|
501
|
+
-> 远端 Gateway -> 远端 Message/Group/Storage -> 回包或事件反向返回
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
跨域 Group 有两个不同的持久化事实,测试必须同时证明:群所属域保存权威成员关系;成员所属域保存该本域 AID 的远端群目录,使 `group.list_my` 不依赖 SDK 历史缓存逐群盲拉。`group.pull` / `group.v2.pull` 仍按 `group_id` 的 issuer 路由到群所属域,并在该域做成员校验;不得在成员本域拿远端群成员表做最终授权判断。
|
|
505
|
+
|
|
506
|
+
### 每轮执行顺序
|
|
507
|
+
|
|
508
|
+
每轮开始和结束都重新阅读 [AUN 测试运行指南](aun测试运行指南.md),确认身份保护、镜像重建和测试串行规则没有变化。固定顺序为:只读材料校验 -> 必要时构建镜像 -> 启动两域 -> 来源与 Go runtime 核验 -> 双向发现 -> P2P -> Group -> Storage OSS -> 采集两域日志。任一前置门禁失败即停止,不得用重签证书、`setup_aids.py`、清库或删除 SDK 身份绕过。
|
|
509
|
+
|
|
510
|
+
### 材料校验与镜像构建
|
|
511
|
+
|
|
512
|
+
```powershell
|
|
513
|
+
cd D:\modelunion\kite\docker-deploy
|
|
514
|
+
python scripts\domain_materials.py validate agentid.pub\materials.json
|
|
515
|
+
python scripts\domain_materials.py validate agentid.cn\materials.json
|
|
516
|
+
docker image inspect docker-deploy-kite:latest mysql:8.0 redis:7-alpine | Out-Null
|
|
517
|
+
if ($LASTEXITCODE -ne 0) { throw '双域基础镜像未准备完成,停止测试' }
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
`domain_materials.py validate` 会只读核对域名、Issuer CA 指纹、10 个服务 AID、TLS 与 MySQL `server-uuid`。任一不匹配都表示材料混域,不得自动修复。
|
|
521
|
+
|
|
522
|
+
只有服务端源码、Go 依赖、manifest 或 Dockerfile 变化时,才在依赖准备阶段构建;业务测试阶段不得临时联网补依赖:
|
|
523
|
+
|
|
524
|
+
```powershell
|
|
525
|
+
docker compose --env-file NUL -f docker-compose.build.yml build kite
|
|
526
|
+
docker image inspect docker-deploy-kite:latest --format '{{.Id}}'
|
|
527
|
+
```
|
|
528
|
+
|
|
529
|
+
### 启动两域
|
|
530
|
+
|
|
531
|
+
共享网络是 external network,首次使用时只创建网络,不创建或修改任何身份数据:
|
|
532
|
+
|
|
533
|
+
```powershell
|
|
534
|
+
docker network inspect kite-agentid-federation-net | Out-Null
|
|
535
|
+
if ($LASTEXITCODE -ne 0) { docker network create kite-agentid-federation-net | Out-Null }
|
|
536
|
+
|
|
537
|
+
$base = @('-f', 'docker-compose.yml')
|
|
538
|
+
$federation = @('-f', 'docker-compose.agentid-federation.yml')
|
|
539
|
+
|
|
540
|
+
docker compose --env-file agentid.pub/local.env --project-directory . @base `
|
|
541
|
+
-f agentid.pub/docker-compose.yml @federation config --quiet
|
|
542
|
+
docker compose --env-file agentid.pub/local.env --env-file agentid.cn/local.env --project-directory . @base `
|
|
543
|
+
-f agentid.cn/docker-compose.yml @federation config --quiet
|
|
544
|
+
|
|
545
|
+
docker compose --env-file agentid.pub/local.env --project-directory . @base `
|
|
546
|
+
-f agentid.pub/docker-compose.yml @federation up -d
|
|
547
|
+
docker compose --env-file agentid.pub/local.env --env-file agentid.cn/local.env --project-directory . @base `
|
|
548
|
+
-f agentid.cn/docker-compose.yml @federation up -d
|
|
549
|
+
|
|
550
|
+
docker compose --env-file agentid.pub/local.env --project-directory . @base `
|
|
551
|
+
-f agentid.pub/docker-compose.yml @federation ps
|
|
552
|
+
docker compose --env-file agentid.pub/local.env --env-file agentid.cn/local.env --project-directory . @base `
|
|
553
|
+
-f agentid.cn/docker-compose.yml @federation ps
|
|
554
|
+
```
|
|
555
|
+
|
|
556
|
+
`agentid.cn` 的 Compose 命令必须先加载 `agentid.pub/local.env`,再加载 `agentid.cn/local.env`:前者提供经过本地准备的 OSS endpoint、bucket 和凭据,后者覆盖 cn 的 Issuer、project、端口、数据根和 `AUN_STORAGE_OSS_PREFIX=agentid-cn/`。`agentid.cn/local.env` 不重复保存 OSS 密钥;不要在日志或 `config` 输出中打印完整环境变量。
|
|
557
|
+
|
|
558
|
+
`agentid.pub` 使用默认宿主端口;`agentid.cn` 使用 Gateway `42001`、AUN Console `42876`、NameService `42443`、Storage `42470`、Group `42480`、MySQL `8406`。这些 42xxx 端口只用于宿主机调试;服务发现和跨网关路由仍公布容器内标准端口与 `{svc}.{issuer}`,不得把 42xxx 写进 federation 内部 URL。
|
|
559
|
+
|
|
560
|
+
### 来源、隔离和 Go runtime 核验
|
|
561
|
+
|
|
562
|
+
```powershell
|
|
563
|
+
$expected = @{
|
|
564
|
+
'kite-app' = @{ Project='kite-single'; Domain='agentid.pub'; Data='data' }
|
|
565
|
+
'kite-agentid-cn-local-app' = @{ Project='kite-agentid-cn-local'; Domain='agentid.cn'; Data='data-agentid-cn' }
|
|
566
|
+
}
|
|
567
|
+
$apps = docker inspect @($expected.Keys) | ConvertFrom-Json
|
|
568
|
+
$imageIds = @($apps | ForEach-Object Image | Select-Object -Unique)
|
|
569
|
+
if ($imageIds.Count -ne 1) { throw "两域未使用同一镜像: $($imageIds -join ', ')" }
|
|
570
|
+
foreach ($app in $apps) {
|
|
571
|
+
$name = $app.Name.TrimStart('/')
|
|
572
|
+
$rule = $expected[$name]
|
|
573
|
+
if ($app.Config.Labels.'com.docker.compose.project' -ne $rule.Project) {
|
|
574
|
+
throw "$name project 错误"
|
|
575
|
+
}
|
|
576
|
+
$files = $app.Config.Labels.'com.docker.compose.project.config_files' -split ','
|
|
577
|
+
if (-not ($files -match 'docker-compose.agentid-federation.yml')) {
|
|
578
|
+
throw "$name 未加载 federation overlay"
|
|
579
|
+
}
|
|
580
|
+
if (-not $app.NetworkSettings.Networks.'kite-agentid-federation-net') {
|
|
581
|
+
throw "$name 未接入共享业务网络"
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
$dbContainers = docker inspect kite-mysql kite-redis `
|
|
585
|
+
kite-agentid-cn-local-mysql kite-agentid-cn-local-redis | ConvertFrom-Json
|
|
586
|
+
$leaked = $dbContainers | Where-Object { $_.NetworkSettings.Networks.'kite-agentid-federation-net' }
|
|
587
|
+
if ($leaked) { throw "数据库或 Redis 错误接入 federation 网络: $($leaked.Name -join ', ')" }
|
|
588
|
+
```
|
|
589
|
+
|
|
590
|
+
再核对每域最近一次 supervisor 报告均为 `desired_running=13`、`observed_running=13`、`service_errors=0`,并检查镜像内 runtime:
|
|
591
|
+
|
|
592
|
+
```powershell
|
|
593
|
+
$goServices = 'auth','ca','gateway','message','group','storage','stream','nameservice','leaderboard','service_proxy'
|
|
594
|
+
foreach ($container in 'kite-app','kite-agentid-cn-local-app') {
|
|
595
|
+
foreach ($service in $goServices) {
|
|
596
|
+
$runtime = docker exec $container sh -lc "grep '^runtime:' /app/extensions/services/$service/module.md"
|
|
597
|
+
if ($runtime -ne 'runtime: binary') { throw "$container/$service 未运行 Go manifest: $runtime" }
|
|
598
|
+
}
|
|
599
|
+
$report = docker logs --since 2m $container 2>&1 |
|
|
600
|
+
Select-String 'desired_running=13 observed_slots=13 observed_running=13' |
|
|
601
|
+
Select-Object -Last 1
|
|
602
|
+
if (-not $report -or $report.Line -notmatch 'service_errors=0') {
|
|
603
|
+
throw "$container 尚未达到 13/13 healthy"
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
```
|
|
607
|
+
|
|
608
|
+
### 双向发现门禁
|
|
609
|
+
|
|
610
|
+
```powershell
|
|
611
|
+
docker exec kite-app getent hosts gateway.agentid.cn
|
|
612
|
+
docker exec kite-agentid-cn-local-app getent hosts gateway.agentid.pub
|
|
613
|
+
docker exec kite-app curl -fsSk https://agentid.cn/.well-known/aun-gateway
|
|
614
|
+
docker exec kite-agentid-cn-local-app curl -fsSk https://agentid.pub/.well-known/aun-gateway
|
|
615
|
+
```
|
|
616
|
+
|
|
617
|
+
返回值必须分别包含 `wss://gateway.agentid.cn:20001/aun` 和 `wss://gateway.agentid.pub:20001/aun`,且不能出现 `127.0.0.1`、`localhost`、宿主机 42xxx 端口或对端域名。该门禁只证明 DNS 与 discovery,不证明 P2P、Group 或 Storage 业务路由已经通过。
|
|
618
|
+
|
|
619
|
+
### 测试身份与执行纪律
|
|
620
|
+
|
|
621
|
+
真实域测试只复用已存在且能在对应 `aun_cert.agentid_cert` 中匹配激活记录的 SDK 身份。当前临时双身份 runner 使用以下固定材料:
|
|
622
|
+
|
|
623
|
+
```text
|
|
624
|
+
agentid.pub: D:\modelunion\kite\docker-deploy\data\extended-acceptance\group-management
|
|
625
|
+
AID: alice.agentid.pub
|
|
626
|
+
agentid.cn: D:\modelunion\kite\docker-deploy\data-agentid-cn\sdk-testers\python-fixed
|
|
627
|
+
AID: cross-e2e.agentid.cn
|
|
628
|
+
key.json seed: cross-domain-e2e-v1
|
|
629
|
+
```
|
|
630
|
+
|
|
631
|
+
脚本在容器内分别只读挂载为 `/identities/pub` 和 `/identities/cn`,运行状态写入临时 `/tmp/aun-e2e`。若 cn 尚无可用身份,可以在老大明确授权的注册流程中创建专用测试 AID,并将材料放入 cn 的固定测试根;日常回归不得自动注册、重签或扫描其他身份目录。不得运行会自动生成随机真实域 AID 的 federation 脚本;`federation-test/tests/e2e_group.py` 和 `e2e_storage.py` 默认会创建身份,只能用于后文 `dist-aid.*` 隔离环境。
|
|
632
|
+
|
|
633
|
+
每轮生成唯一 `run_id`,并记录 sender AID、receiver AID、group ID、message ID/seq、Storage owner/path 和起止时间。P2P、Group、Storage 串行执行,避免固定身份的游标、目录和本地缓存相互污染。
|
|
634
|
+
|
|
635
|
+
### P2P 跨域验收
|
|
636
|
+
|
|
637
|
+
使用两端 SDK 的公开 `message.send`、push/pull、`message.ack` 完成双向闭环:
|
|
638
|
+
|
|
639
|
+
1. `.agentid.pub` 发送给 `.agentid.cn`,接收端校验 sender、payload、message ID/seq 后 ACK。
|
|
640
|
+
2. `.agentid.cn` 反向发送给 `.agentid.pub`,执行同样校验。
|
|
641
|
+
3. 接收端离线时发送,再上线 pull 并 ACK,证明远端持久化和回补路径;不能只验证在线 push。
|
|
642
|
+
4. receiver AID 的 issuer 必须决定远端 Gateway;本域 Message 不得把异域 receiver 当成本地收件人查询后返回 not found。
|
|
643
|
+
|
|
644
|
+
成功标准是发送响应、远端接收、pull/ack 和两域日志中的同一 trace/message ID 全部闭合。仅有 `message.send` 返回成功不算通过;远端超时必须返回明确的 federation unavailable/timeout,不能伪装成接收方不存在。
|
|
645
|
+
|
|
646
|
+
### Group 跨域验收
|
|
647
|
+
|
|
648
|
+
先由 `.agentid.pub` 成员创建群并加入 `.agentid.cn` 成员,再反向创建一次。每个方向都必须验证:
|
|
649
|
+
|
|
650
|
+
1. `group.create` 成功,具名 Group AID 场景最终响应包含 `aid_cert.cert`、`aid_cert.ca_cert`、`aid_cert.cert_sn`;客户端只有收到并持久化证书后才能提交临时私钥,缺字段不得继续邀请、备份或返回假成功。
|
|
651
|
+
2. 群所属域的 `group.list_members` 出现异域成员,角色正确。
|
|
652
|
+
3. 加群事件到达成员所属域后立即调用 `group.list_my`,必须出现该远端 group ID;断开并重连 SDK 后仍出现,证明来源是本域 Group 持久化目录,不是进程内事件或客户端历史缓存。
|
|
653
|
+
4. 异域成员调用 `group.pull` / `group.v2.pull`,请求必须路由到 group ID 所属域,并由该域权威成员表放行;不得在成员本域报 `member not found`。
|
|
654
|
+
5. 双方各发送一条 `group.send`,对端通过在线事件和 pull 都能按 seq 读到;验证 ACK/游标后再继续。
|
|
655
|
+
6. 异域成员 `group.leave` 后,成员所属域的 `group.list_my` 最终移除该群;此后 pull/send 返回 `member not found` 才是合法结果,并应由群所属域产生。
|
|
656
|
+
|
|
657
|
+
错误语义也必须区分:group ID 在所属域不存在应返回 group not found;群存在但调用者从未加入或已退群才返回 member not found;远端 Gateway/Group 不可达应返回 federation timeout/unavailable。不得把路由失败、目录缺失或本域误查包装成 member not found。
|
|
658
|
+
|
|
659
|
+
现有 `dist-aid.*` 的 `e2e_group.py` 覆盖跨域加人、双向群消息、退群和邀请码,但没有证明真实域固定成员的本域 `group.list_my` 持久化,也没有覆盖 `group.create` 的 `aid_cert` 字段契约。因此这两项是当前真实双域发布前必跑门禁,不能由旧脚本通过替代。
|
|
660
|
+
|
|
661
|
+
### Storage OSS 验收
|
|
662
|
+
|
|
663
|
+
先只输出 backend 名称,禁止打印 OSS AccessKey、Secret 或完整容器环境:
|
|
664
|
+
|
|
665
|
+
```powershell
|
|
666
|
+
foreach ($container in 'kite-app','kite-agentid-cn-local-app') {
|
|
667
|
+
docker inspect $container --format '{{range .Config.Env}}{{println .}}{{end}}' |
|
|
668
|
+
Select-String '^AUN_STORAGE_BACKEND='
|
|
669
|
+
}
|
|
670
|
+
```
|
|
671
|
+
|
|
672
|
+
重点在 `agentid.cn` 使用已有固定 AID 和唯一 `run_id` 目录完成:创建文件夹 -> 上传小文件(inline/秒传路径)-> 上传大文件(session/OSS PUT/complete 路径)-> `storage.fs.list` 或 `storage.list_objects` 列出两文件 -> 下载并校验 SHA-256。`agentid.pub` 至少重复“文件夹内上传并列出”作为对照。
|
|
673
|
+
|
|
674
|
+
上传接口返回成功只说明数据面或 `complete_upload` 返回成功,不代表目录元数据可见。验收必须断言列表出现同一 owner、bucket、规范化 path、size 和内容哈希;重新连接 SDK 后再次 list 仍可见。若 OSS 对象存在而列表没有记录,按 Storage 控制面提交/数据库持久化失败处理,不能归因于客户端刷新。
|
|
675
|
+
|
|
676
|
+
跨域 Storage/Group FS 还需用 owner AID 或 group AID 的 issuer 验证路由到所属域;不允许本域 Storage 查询异域 owner 的本地目录后返回空列表。任何清理测试对象的操作只限本轮唯一目录,固定身份目录和数据库不得删除。
|
|
677
|
+
|
|
678
|
+
本地双域 Storage 阶段使用临时 runner,同时挂载上面两个固定身份根;以下命令跳过 mail 和 reconnect,只验证上传、列表、权限、token、跨域下载和 SHA-256。业务测试阶段不安装依赖、不创建身份:
|
|
679
|
+
|
|
680
|
+
```powershell
|
|
681
|
+
$testSince = (Get-Date).ToUniversalTime().ToString('o')
|
|
682
|
+
$runId = 'agentid-storage-' + (Get-Date).ToUniversalTime().ToString('yyyyMMddHHmmss')
|
|
683
|
+
docker run --rm --network kite-agentid-federation-net `
|
|
684
|
+
-v "D:\modelunion\kite\aun-sdk-core\python\src:/sdk/src:ro" `
|
|
685
|
+
-v "D:\modelunion\kite\docker-deploy\tests\agentid_cross_domain_e2e.py:/tests/agentid_cross_domain_e2e.py:ro" `
|
|
686
|
+
-v "D:\modelunion\kite\docker-deploy\data\extended-acceptance\group-management:/identities/pub:ro" `
|
|
687
|
+
-v "D:\modelunion\kite\docker-deploy\data-agentid-cn\sdk-testers\python-fixed:/identities/cn:ro" `
|
|
688
|
+
-e PYTHONPATH=/sdk/src `
|
|
689
|
+
-e AUN_E2E_PUB_IDENTITY_ROOT=/identities/pub `
|
|
690
|
+
-e AUN_E2E_CN_IDENTITY_ROOT=/identities/cn `
|
|
691
|
+
-e AUN_E2E_CN_ENCRYPTION_SEED=cross-domain-e2e-v1 `
|
|
692
|
+
-e AUN_E2E_RUN_ROOT=/tmp/aun-e2e `
|
|
693
|
+
-e HTTP_PROXY= -e HTTPS_PROXY= -e ALL_PROXY= -e NO_PROXY=* `
|
|
694
|
+
aun-sdk-tester:latest python /tests/agentid_cross_domain_e2e.py `
|
|
695
|
+
--phase storage --skip-reconnect --run-id $runId
|
|
696
|
+
if ($LASTEXITCODE -ne 0) { throw 'Storage 双域 E2E 失败' }
|
|
697
|
+
docker logs --since $testSince kite-app 2>&1 |
|
|
698
|
+
Tee-Object D:\modelunion\kite\docker-deploy\agentid.pub\latest.log | Out-Null
|
|
699
|
+
docker logs --since $testSince kite-agentid-cn-local-app 2>&1 |
|
|
700
|
+
Tee-Object D:\modelunion\kite\docker-deploy\agentid.cn\latest.log | Out-Null
|
|
701
|
+
```
|
|
702
|
+
|
|
703
|
+
成功必须同时看到 `STORAGE_LIST_OK`、`STORAGE_PRIVATE_DENIED_OK`、`STORAGE_TOKEN_OK`、`STORAGE_CROSS_OWNER_ROUTING_OK`、`STORAGE_CLEANUP_OK` 和 `PASS phase=storage`。日志中应出现两域的 `federation.hello` / `federation.relay`,权限拒绝保持为 `forbidden`;不得被 Gateway 改写成 `-32012` 或泛化的 `StorageError`。
|
|
704
|
+
|
|
705
|
+
### 日志采集与根因判定
|
|
706
|
+
|
|
707
|
+
测试开始前记录时间:
|
|
708
|
+
|
|
709
|
+
```powershell
|
|
710
|
+
$testSince = (Get-Date).ToUniversalTime().ToString('o')
|
|
711
|
+
```
|
|
712
|
+
|
|
713
|
+
测试结束后保存两域完整容器日志到固定路径:
|
|
714
|
+
|
|
715
|
+
```powershell
|
|
716
|
+
docker logs --since $testSince kite-app 2>&1 |
|
|
717
|
+
Tee-Object D:\modelunion\kite\docker-deploy\agentid.pub\latest.log | Out-Null
|
|
718
|
+
docker logs --since $testSince kite-agentid-cn-local-app 2>&1 |
|
|
719
|
+
Tee-Object D:\modelunion\kite\docker-deploy\agentid.cn\latest.log | Out-Null
|
|
720
|
+
```
|
|
721
|
+
|
|
722
|
+
用本轮 AID、group ID、message ID、Storage path/owner 和 trace ID 同时检索两个文件,再按以下顺序还原调用链:SDK 请求 -> 本域 Gateway 判域 -> federation 出站 -> 远端 Gateway 入站 -> 目标服务授权/持久化 -> 响应或事件返回 -> 成员所属域目录持久化 -> SDK 回调/重连查询。不要只搜索错误文本后推断根因。
|
|
723
|
+
|
|
724
|
+
对 `member not found` 必须证明四个事实:具体 group ID、该 group ID 的所属域、调用者在所属域权威成员表中的状态、错误由哪一域哪一服务产生。若日志显示请求根本未到群所属域,就是路由问题;若到达所属域但权威成员存在仍报错,是成员查询/事务可见性问题;若权威成员不存在,则继续追加群事务和跨域事件,不得用“SDK 盲拉”作为未经证据的结论。
|
|
725
|
+
|
|
726
|
+
### 停止本地真实域名双域
|
|
727
|
+
|
|
728
|
+
```powershell
|
|
729
|
+
cd D:\modelunion\kite\docker-deploy
|
|
730
|
+
$base = @('-f', 'docker-compose.yml')
|
|
731
|
+
$federation = @('-f', 'docker-compose.agentid-federation.yml')
|
|
732
|
+
docker compose --env-file agentid.pub/local.env --env-file agentid.cn/local.env --project-directory . @base `
|
|
733
|
+
-f agentid.cn/docker-compose.yml @federation down
|
|
734
|
+
docker compose --env-file agentid.pub/local.env --project-directory . @base `
|
|
735
|
+
-f agentid.pub/docker-compose.yml @federation down
|
|
736
|
+
```
|
|
737
|
+
|
|
738
|
+
不得加 `-v`,不得删除 `kite-agentid-federation-net` 来代替停止 project。网络可以保留供下一轮复用。
|
|
739
|
+
|
|
740
|
+
## 公网 agentid.pub / agentid.cn 固定身份复测
|
|
741
|
+
|
|
742
|
+
公网复测只在本地双域全部通过后执行。它直接访问公网 DNS/TLS 和两台线上服务器,不加载本地 federation overlay,也不能把本地容器日志当成线上证据。
|
|
743
|
+
|
|
744
|
+
### 身份目录与首次注册
|
|
745
|
+
|
|
746
|
+
公网 SDK 身份只允许保存在 AUN SDK 公网测试根:
|
|
747
|
+
|
|
748
|
+
```text
|
|
749
|
+
D:\modelunion\kite\aun-sdk-core\.public-test-data\identities\agentid.pub\<identity-prefix>\persistent
|
|
750
|
+
D:\modelunion\kite\aun-sdk-core\.public-test-data\identities\agentid.cn\<identity-prefix>\persistent
|
|
751
|
+
```
|
|
752
|
+
|
|
753
|
+
不得扫描或复用用户真实的 `~/.aun`、本地 Docker 的 `docker-deploy/data*`、其他 worktree 或其他公网测试前缀。已有固定身份时直接复用;目标域没有测试身份且老大已明确授权注册时,分别对两个域运行公网 runner 的 `smoke`,让它在上述目录创建并验证固定身份:
|
|
754
|
+
|
|
755
|
+
```powershell
|
|
756
|
+
cd D:\modelunion\kite\aun-sdk-core
|
|
757
|
+
$identityPrefix = 'cross-public-ci'
|
|
758
|
+
$env:AUN_TEST_ENCRYPTION_SEED = '<固定且受保护的 seed>'
|
|
759
|
+
foreach ($domain in 'agentid.pub', 'agentid.cn') {
|
|
760
|
+
docker run --rm `
|
|
761
|
+
-v "${PWD}\python:/workspace/python:ro" `
|
|
762
|
+
-v "${PWD}\.public-test-data:/public-test-data" `
|
|
763
|
+
-e AUN_TEST_ENCRYPTION_SEED `
|
|
764
|
+
-w /workspace/python `
|
|
765
|
+
aun-sdk-tester:latest `
|
|
766
|
+
python -X utf8 run-public-tests.py `
|
|
767
|
+
--domain $domain --suite smoke `
|
|
768
|
+
--data-root /public-test-data `
|
|
769
|
+
--identity-prefix $identityPrefix `
|
|
770
|
+
--allow-create-identities --fail-fast
|
|
771
|
+
if ($LASTEXITCODE -ne 0) { throw "$domain 公网身份准备或 smoke 失败" }
|
|
772
|
+
}
|
|
773
|
+
```
|
|
774
|
+
|
|
775
|
+
同一 `identity-prefix` 后续必须继续使用同一 seed。注册成功后不得删除、重签或复制到另一域;每个域的证书主体必须与 AID issuer 一致。
|
|
776
|
+
|
|
777
|
+
### 双域业务复测
|
|
778
|
+
|
|
779
|
+
使用 `docker-deploy/tests/agentid_cross_domain_e2e.py`,把两域固定身份根分别只读挂载。公网必须启用 TLS 校验;P2P、Group、Storage 串行执行,并按当前范围跳过 reconnect 和 mail:
|
|
780
|
+
|
|
781
|
+
```powershell
|
|
782
|
+
cd D:\modelunion\kite
|
|
783
|
+
$identityPrefix = 'cross-public-ci'
|
|
784
|
+
$pubAid = "$identityPrefix-alice.agentid.pub"
|
|
785
|
+
$cnAid = "$identityPrefix-alice.agentid.cn"
|
|
786
|
+
$seed = $env:AUN_TEST_ENCRYPTION_SEED
|
|
787
|
+
if ([string]::IsNullOrWhiteSpace($seed)) { throw '缺少 AUN_TEST_ENCRYPTION_SEED' }
|
|
788
|
+
|
|
789
|
+
foreach ($phase in 'p2p', 'group', 'storage') {
|
|
790
|
+
$runId = "public-cross-$phase-" + (Get-Date).ToUniversalTime().ToString('yyyyMMddHHmmss')
|
|
791
|
+
docker run --rm `
|
|
792
|
+
-v "D:\modelunion\kite\aun-sdk-core\python\src:/sdk/src:ro" `
|
|
793
|
+
-v "D:\modelunion\kite\docker-deploy\tests\agentid_cross_domain_e2e.py:/tests/agentid_cross_domain_e2e.py:ro" `
|
|
794
|
+
-v "D:\modelunion\kite\aun-sdk-core\.public-test-data\identities\agentid.pub\$identityPrefix\persistent:/identities/pub:ro" `
|
|
795
|
+
-v "D:\modelunion\kite\aun-sdk-core\.public-test-data\identities\agentid.cn\$identityPrefix\persistent:/identities/cn:ro" `
|
|
796
|
+
-e PYTHONPATH=/sdk/src `
|
|
797
|
+
-e AUN_E2E_PUB_AID=$pubAid -e AUN_E2E_CN_AID=$cnAid `
|
|
798
|
+
-e AUN_E2E_PUB_IDENTITY_ROOT=/identities/pub `
|
|
799
|
+
-e AUN_E2E_CN_IDENTITY_ROOT=/identities/cn `
|
|
800
|
+
-e AUN_E2E_PUB_ENCRYPTION_SEED=$seed `
|
|
801
|
+
-e AUN_E2E_CN_ENCRYPTION_SEED=$seed `
|
|
802
|
+
-e AUN_E2E_RUN_ROOT=/tmp/aun-e2e `
|
|
803
|
+
-e AUN_E2E_VERIFY_SSL=1 `
|
|
804
|
+
-e HTTP_PROXY= -e HTTPS_PROXY= -e ALL_PROXY= -e NO_PROXY=* `
|
|
805
|
+
aun-sdk-tester:latest python /tests/agentid_cross_domain_e2e.py `
|
|
806
|
+
--phase $phase --skip-reconnect --run-id $runId
|
|
807
|
+
if ($LASTEXITCODE -ne 0) { throw "$phase 公网双域 E2E 失败" }
|
|
808
|
+
}
|
|
809
|
+
```
|
|
810
|
+
|
|
811
|
+
公网 Group 的发布门禁与本地相同:两个方向都必须看到权威成员存在、远端 pull 成功、成员所属域 `list_my` 出现远端群,以及具名群返回 `aid_cert.cert`、`aid_cert.ca_cert`、`aid_cert.cert_sn`。若“权威成员存在 + 远端 pull 成功”但 `list_my` 缺失,说明路由与权威授权已经成功,失败点是成员所属域没有持久化远端群目录;不能归因于 SDK 盲拉或身份未注册。
|
|
812
|
+
|
|
813
|
+
### 部署与日志门禁
|
|
814
|
+
|
|
815
|
+
本地通过不等于公网已修复。发布前必须重新生成 `docker-deploy-kite:latest` 镜像包,并确认两个域 `online/go/kite-docker.tar.gz` 的 SHA-256 相同;线上加载后核对镜像 ID,再只重建 Kite 应用容器,不能重建 MySQL、清库或替换身份材料。
|
|
816
|
+
|
|
817
|
+
如果线上仍返回旧 `aid_cert.cert_pem/ca_cert_pem/serial`,或两个方向的 `list_my` 都缺少远端群,而本地当前镜像已经通过,直接判定为线上仍在运行旧镜像。部署完成后必须重新跑完整 P2P/Group/Storage 三阶段,旧失败记录不能作为新版本验收结果。
|
|
818
|
+
|
|
819
|
+
公网日志应从两台服务器按本轮开始时间分别采集。若仍保存到 `docker-deploy/agentid.pub/latest.log` 和 `docker-deploy/agentid.cn/latest.log`,必须同时记录日志来源是“本地 Docker”还是“公网服务器”;文件名相同不能证明环境。没有远端日志访问权限时,只能给出客户端 E2E 结论,不能声称已完成服务端调用链闭环。
|
|
820
|
+
|
|
821
|
+
## 隔离双域 federation(dist-aid.com / dist-aid.net)
|
|
822
|
+
|
|
823
|
+
### 准备并启动
|
|
824
|
+
|
|
825
|
+
日常启动只复用 `D:\modelunion\kite\docker-deploy\federation-test\data-dist` 中的固定 CA、服务证书、MySQL 和客户端身份。先做只读材料检查:
|
|
826
|
+
|
|
827
|
+
```powershell
|
|
828
|
+
cd D:\modelunion\kite\docker-deploy
|
|
829
|
+
$required = @(
|
|
830
|
+
'.env.distributed',
|
|
831
|
+
'federation-test\data-dist\dist-aid.com\CA',
|
|
832
|
+
'federation-test\data-dist\dist-aid.com\AIDs',
|
|
833
|
+
'federation-test\data-dist\dist-aid.com\mysql',
|
|
834
|
+
'federation-test\data-dist\dist-aid.net\CA',
|
|
835
|
+
'federation-test\data-dist\dist-aid.net\AIDs',
|
|
836
|
+
'federation-test\data-dist\dist-aid.net\mysql',
|
|
837
|
+
'federation-test\data-dist\client-data'
|
|
838
|
+
)
|
|
839
|
+
$missing = $required | Where-Object { -not (Test-Path $_) }
|
|
840
|
+
if ($missing) { throw "双域固定材料缺失,停止测试,禁止自动重建: $($missing -join ', ')" }
|
|
841
|
+
docker image inspect docker-deploy-kite-main-dist:latest aun-sdk-tester-main-dist:latest mysql:8.0 postgres:16-alpine redis:7-alpine node:22-bookworm golang:1.24-bookworm | Out-Null
|
|
842
|
+
if ($LASTEXITCODE -ne 0) { throw 'Federation 镜像未完成离线准备,停止测试' }
|
|
843
|
+
cd federation-test
|
|
844
|
+
docker compose --env-file ../.env.distributed -f docker-compose.yml config
|
|
845
|
+
docker compose --env-file ../.env.distributed -f docker-compose.yml up -d `
|
|
846
|
+
mysql-a mysql-b postgres-a postgres-b redis-a redis-b kite-a kite-b client-a client-b
|
|
847
|
+
docker compose --env-file ../.env.distributed -f docker-compose.yml ps
|
|
848
|
+
```
|
|
849
|
+
|
|
850
|
+
`setup_certs.py` 会签发或重签 `dist-aid.*` 的 issuer 与服务证书,不属于日常启动命令。只有用户明确同意首次创建或重建该环境时才能执行;固定材料存在时严禁使用 `--force`。
|
|
851
|
+
|
|
852
|
+
上面的日常命令明确排除 `ts-tester` 和 `go-tester`,避免新建 TS Tester 时触发 `npm install`。需要运行 federation TS/Go 用例时只能 `start` 已完成离线依赖准备的容器;容器不存在或缓存不完整就停止测试,不能临时联网补依赖。
|
|
853
|
+
|
|
854
|
+
默认域名和固定身份:
|
|
855
|
+
|
|
856
|
+
- 本域:`dist-aid.com`
|
|
857
|
+
- 远端:`dist-aid.net`
|
|
858
|
+
- Alice:`alice.dist-aid.com`
|
|
859
|
+
- Bob:`bobb.dist-aid.net`
|
|
860
|
+
- Charlie:`charlie.dist-aid.com`
|
|
861
|
+
- Dave:`dave.dist-aid.net`
|
|
862
|
+
|
|
863
|
+
### 基础回归
|
|
864
|
+
|
|
865
|
+
固定 Alice/Bob/Charlie/Dave 身份应直接复用。先确认宿主机 `data-dist/client-data` 中身份目录存在,并确认两个 MySQL 的 `aun_cert.agentid_cert` 中证书序列号与本地证书一致;不一致时停止,不得自动执行 `setup_aids.py`、清理证书表或覆盖身份。
|
|
866
|
+
|
|
867
|
+
```powershell
|
|
868
|
+
docker exec main-dist-client-a python /test/federation_ping.py
|
|
869
|
+
docker exec main-dist-client-a python /test/gateway_to_gateway.py
|
|
870
|
+
docker exec main-dist-client-a python /test/cross_domain_p2p.py
|
|
871
|
+
docker exec main-dist-client-a python /test/e2e_plaintext.py
|
|
872
|
+
```
|
|
873
|
+
|
|
874
|
+
按改动范围继续跑主要业务路径:
|
|
875
|
+
|
|
876
|
+
```powershell
|
|
877
|
+
docker exec main-dist-client-a python /test/cross_domain_stream.py
|
|
878
|
+
docker exec main-dist-client-a python /test/e2e_encrypted.py
|
|
879
|
+
docker exec main-dist-client-a python /test/e2e_v2_cross_domain.py
|
|
880
|
+
docker exec main-dist-client-a python /test/test_e2ee_cross_domain.py
|
|
881
|
+
docker exec main-dist-client-a python /test/e2e_group.py
|
|
882
|
+
docker exec main-dist-client-a python /test/e2e_storage.py
|
|
883
|
+
docker exec main-dist-client-a python /test/e2e_group_fs.py
|
|
884
|
+
docker exec main-dist-client-a python /test/cross_domain_collab.py
|
|
885
|
+
docker exec main-dist-client-a python /test/cross_domain_service_proxy.py
|
|
886
|
+
```
|
|
887
|
+
|
|
888
|
+
暂不跑:
|
|
889
|
+
|
|
890
|
+
- `e2e_mail.py`
|
|
891
|
+
- reconnect 相关测试
|
|
892
|
+
- `e2e_real.py`、`e2e_comprehensive.py`、`e2e_coverage_gaps.py` 这类仍依赖宿主机 Docker 协调并可能硬编码旧容器名的脚本
|
|
893
|
+
|
|
894
|
+
### TypeScript / Go federation
|
|
895
|
+
|
|
896
|
+
先复用已有 Tester,不得在断网阶段通过 `up` 或 `--force-recreate` 新建:
|
|
897
|
+
|
|
898
|
+
```powershell
|
|
899
|
+
$required = @('main-dist-federation-ts-tester', 'main-dist-federation-go-tester')
|
|
900
|
+
$existing = docker ps -a --format '{{.Names}}'
|
|
901
|
+
$missing = $required | Where-Object { $_ -notin $existing }
|
|
902
|
+
if ($missing) { throw "Federation Tester 尚未完成离线依赖准备,停止测试: $($missing -join ', ')" }
|
|
903
|
+
docker compose --env-file ../.env.distributed -f docker-compose.yml start ts-tester go-tester
|
|
904
|
+
```
|
|
905
|
+
|
|
906
|
+
```powershell
|
|
907
|
+
docker exec main-dist-federation-ts-tester bash -lc "cd /workspace/ts && node_modules/.bin/vitest run tests/integration/federation.test.ts tests/integration/federation-storage.test.ts"
|
|
908
|
+
```
|
|
909
|
+
|
|
910
|
+
```powershell
|
|
911
|
+
docker exec main-dist-federation-go-tester sh -lc "cd /workspace/go && /usr/local/go/bin/go test -tags integration . -run Federation -count=1 -v"
|
|
912
|
+
```
|
|
913
|
+
|
|
914
|
+
如果用临时 Go 容器,需要加入分布式 federation 网络:
|
|
915
|
+
|
|
916
|
+
```powershell
|
|
917
|
+
$repo = (Resolve-Path ..\..).Path
|
|
918
|
+
docker run --rm --network kite-main-dist-federation_federation-net `
|
|
919
|
+
-v "$repo\aun-sdk-core\go:/workspace/go" `
|
|
920
|
+
-v kite-main-dist-sdk-testers_dist-go-sdk-mod:/tmp/go-mod:ro `
|
|
921
|
+
-e HTTP_PROXY= -e HTTPS_PROXY= -e ALL_PROXY= -e NO_PROXY=* `
|
|
922
|
+
-e GOMODCACHE=/tmp/go-mod -e GOPROXY=off -e GOSUMDB=off `
|
|
923
|
+
-e AUN_ENV=development -e AUN_VERIFY_SSL=0 `
|
|
924
|
+
-e GOCACHE=/workspace/go/.codex_gocache_linux `
|
|
925
|
+
-e GOTMPDIR=/workspace/go/.codex_gotmp_linux `
|
|
926
|
+
golang:1.24-bookworm sh -lc "mkdir -p /workspace/go/.codex_gocache_linux /workspace/go/.codex_gotmp_linux && cd /workspace/go && /usr/local/go/bin/go test -tags integration . -run Federation -count=1 -v"
|
|
927
|
+
```
|
|
928
|
+
|
|
929
|
+
这条临时命令只读挂载 `kite-main-dist-sdk-testers` project 已准备的 module cache;当前 worktree 没有 `go/vendor`,不得改回 `-mod=vendor`。若 named volume 不存在或缺少依赖,`GOPROXY=off` 会直接失败,此时应停止并回到独立依赖准备阶段。
|
|
930
|
+
|
|
931
|
+
## 原有用例兼容验证
|
|
932
|
+
|
|
933
|
+
## Message Python/Go 性能与恢复门禁
|
|
934
|
+
|
|
935
|
+
从当前 worktree 根目录运行串行 A/B。脚本会分别构建独立镜像标签,避免 `latest` 构建缓存污染,并在每个 warmup/measure 阶段前后排空 receiver:
|
|
936
|
+
|
|
937
|
+
```powershell
|
|
938
|
+
cd D:\modelunion\kite
|
|
939
|
+
python docker-deploy/tests/message_performance_gate.py `
|
|
940
|
+
--operations 100 --warmup 10 --concurrency 8 `
|
|
941
|
+
--timeout 120 --output test-runs/message-performance.json
|
|
942
|
+
```
|
|
943
|
+
|
|
944
|
+
单 receiver 的 push 使用 conflation,push 次数不是消息完整性指标;门禁以 `pull + ack` 验证全部消息到达,并要求最终 receiver 排空。性能镜像分别为 `docker-deploy-kite-message-python-perf:latest` 与 `docker-deploy-kite-message-go-perf:latest`。
|
|
945
|
+
|
|
946
|
+
Gateway 模块重启恢复与多 receiver 并发 soak:
|
|
947
|
+
|
|
948
|
+
```powershell
|
|
949
|
+
python docker-deploy/tests/message_concurrent_soak_gate.py `
|
|
950
|
+
--clients 4 --operations 10 --rounds 1 `
|
|
951
|
+
--timeout 60 --max-p99-ms 500 --max-recovery-seconds 30
|
|
952
|
+
```
|
|
953
|
+
|
|
954
|
+
扩大门禁:
|
|
955
|
+
|
|
956
|
+
```powershell
|
|
957
|
+
python docker-deploy/tests/message_concurrent_soak_gate.py `
|
|
958
|
+
--clients 8 --operations 20 --rounds 2 `
|
|
959
|
+
--timeout 120 --max-p99-ms 500 --max-recovery-seconds 30
|
|
960
|
+
```
|
|
961
|
+
|
|
962
|
+
soak 脚本会构建 Message-Go、重建 `kite-a`、串行准备 identity、并发发送、逐 receiver `pull + ack + drain`,仅重启 Gateway 模块并要求 Message-Go PID 不变;结束或失败后自动恢复 Python Message 镜像。若 Docker 报残留容器 `No such container`,先执行:
|
|
963
|
+
|
|
964
|
+
```powershell
|
|
965
|
+
docker compose --env-file docker-deploy/.env.distributed `
|
|
966
|
+
-f docker-deploy/federation-test/docker-compose.yml rm -sf kite-a
|
|
967
|
+
```
|
|
968
|
+
|
|
969
|
+
如果目标是证明原来的单实例用例仍可通过,使用当前 worktree 的默认单实例环境:
|
|
970
|
+
|
|
971
|
+
```powershell
|
|
972
|
+
cd D:\modelunion\kite\docker-deploy
|
|
973
|
+
docker compose --env-file NUL -f docker-compose.yml up -d
|
|
974
|
+
```
|
|
975
|
+
|
|
976
|
+
这一路径必须继续保持默认单实例值,不使用 `dist-*` 域名,不使用 `data-dist`,也不使用 `kite-dist-*` 容器名。默认单实例测试按主指南执行;双域测试只按本指南的 `dist-aid.*` 环境执行。
|
|
977
|
+
|
|
978
|
+
如果目标是证明“同一批非 reconnect / 非 mail 用例可在分布式控制 master 上通过”,使用本指南的 `dist-agentid.pub` 和临时测试容器命令。
|
|
979
|
+
|
|
980
|
+
## 停止环境
|
|
981
|
+
|
|
982
|
+
三节点分布式:
|
|
983
|
+
|
|
984
|
+
```powershell
|
|
985
|
+
cd D:\modelunion\kite\docker-deploy
|
|
986
|
+
docker compose --env-file .env.distributed -f docker-compose.distributed.yml down
|
|
987
|
+
```
|
|
988
|
+
|
|
989
|
+
双域 federation:
|
|
990
|
+
|
|
991
|
+
```powershell
|
|
992
|
+
cd D:\modelunion\kite\docker-deploy\federation-test
|
|
993
|
+
docker compose --env-file ../.env.distributed -f docker-compose.yml down
|
|
994
|
+
```
|
|
995
|
+
|
|
996
|
+
不要加 `-v`,除非明确要丢弃本 worktree 的 `data-dist` 运行数据和测试身份。
|
|
997
|
+
|
|
998
|
+
## 故障排查
|
|
999
|
+
|
|
1000
|
+
- worker 连接控制中心失败:检查 `AUN_CONTROL_BASE_URL` 是否为 `https://aun-console.dist-agentid.pub:19876`,不要写服务 AID `aun_console.dist-agentid.pub`、`127.0.0.1` 或 `localhost`;同时确认 worker 已挂载 `/data/certs/aun-ca-bundle.crt`。
|
|
1001
|
+
- SDK discovery 失败:先在测试容器内访问 `https://gateway.dist-agentid.pub/.well-known/aun-gateway`、`https://alice.dist-agentid.pub/.well-known/aun-gateway` 或双域环境的 `https://dist-aid.com/.well-known/aun-gateway`;本地 TLS 校验应由 `AUN_ENV=development`、`AUN_VERIFY_SSL=0` 跳过。
|
|
1002
|
+
- URL 返回 loopback:服务端 URL 生成逻辑有问题,应返回 `gateway.{issuer}`、`storage.{issuer}`、`group.{issuer}` 这类 Docker network alias。
|
|
1003
|
+
- TLS 报错:本地分布式环境使用自签名材料,确认测试容器内有 `AUN_ENV=development` 和 `AUN_VERIFY_SSL=0`。
|
|
1004
|
+
- 来源冲突:检查 Compose label 和 bind mount 是否全部位于 `D:\modelunion\kite`;只看 `dist-*` 容器名不足以证明来源。
|