mirror of
https://gitcode.com/JianFeeeee/HomeAgent.git
synced 2026-10-04 00:03:59 +00:00
plugin: 删除 C ABI 通道(Part 6.2 完成,-3198 行)
外部插件统一走子进程 + stdio RPC,三套独立 ABI 实现收敛为单一 RPC 实现。 用户决策:彻底舍弃 .so 能力,不保留双通道回退。 ## 删除清单 internal/plugin/cabi/ 1156 行(loader.go/loader.c/types.go/output_test.go) internal/plugin/dynamic_dll_windows.go 272 行(§9.2 记录的能力退化实现) internal/plugin/dynamic_loader_unix.go 79 行(唯一 cabi 引用点) internal/plugin/dynamic_dll_test.go 32 行 internal/plugin/dynamic_dll_stub.go 11 行 internal/plugin/dynamic_loader_windows.go 11 行 internal/plugin/bridge_e2e_test.go (测的是 cabi 路径) third_party/.../plugindev/templates.go 1296 行(取消跟踪,SDK 仓才是权威副本) dynamic.go:entryCABI 通道删除,soEntry/dllEntry 常量删除。 registry.go:tryDynamic 探测顺序从 .so → .dll → .lua 变成 proc → lua。 ## 旧 .so 给明确错误,不静默跳过 静默跳过会让「插件目录在但没加载」看起来像配置问题,而实际原因是需要 用新版 plugindev 重编。故保留 legacyCABIEntries 表专门用于识别残留: plugin legacy: 检测到旧 C ABI 产物(plugin.so/.dll/.dylib)。 外部插件已改为子进程模式,请用新版 plugindev 重编产出 plugin.bin (业务代码无需修改) 错误消息里「业务代码无需修改」这句是有测试守着的——迁移的核心承诺就是它。 ## pluginmgr 安装逻辑跟进 bundle 命名 子进程模式下各平台产物统一叫 plugin.bin(进程边界即 ABI 边界),故 zip 内 按平台加后缀 plugin.bin.<goos>.<goarch>,解包时挑当前平台那一份重命名。 platformBinary 改为按 runtime.GOOS+GOARCH 生成条目名;platformBinaries 固定表 换成 isPlatformBinary 前缀判断(平台组合会增长:linux/arm64、darwin/arm64…, 按前缀判断无需维护清单)。 新增 chmod 0755:zip 保留了原权限位,但经某些工具链/传输后可能丢失, 内核加载时会因缺执行位报错。提前补上比事后让用户 chmod 更好。 ## 测试 entry_dispatch_test.go 重写(12 项): - classifyEntry 对 .so/.dll/.dylib 现在返回 unknown - LegacyManifestFallsBackToProbe:存量插件 manifest 仍写 "plugin.so" (17 个插件没人去改),须靠目录探测找到 plugin.bin —— 这是 「外部插件零改动」的直接后果 - LegacyCABIGivesActionableError:错误消息须含 plugindev / plugin.bin / 业务代码 - PluginEntryHash_IgnoresLegacyCABI:.so 不参与 hash(内核已不认它) upgrade_test.go 的 .hmap 构造改用 plugin.bin。 验证:go build ./... 通过;go test ./... 全仓无失败; go test -race ./internal/plugin/... 全绿;三平台构建通过。 Ref: docs/zh/架构迁移评估.md §3.1/§9.2、docs/zh/plugin-migration-plan.md Part 6
This commit is contained in:
@ -374,7 +374,7 @@ func (r *Registry) isDisabled(name string) bool {
|
||||
// plugin.bin 排在最前:与 detectEntryKind 保持一致的优先级,迁移期间同目录
|
||||
// 两种产物共存时以子进程产物为准。
|
||||
func pluginEntryHash(plgDir string) string {
|
||||
for _, candidate := range []string{binEntry, soEntry, dllEntry, "plugin.dylib", luaEntry, skillEntry} {
|
||||
for _, candidate := range []string{binEntry, luaEntry, skillEntry} {
|
||||
path := filepath.Join(plgDir, candidate)
|
||||
if data, err := os.ReadFile(path); err == nil && len(data) > 0 {
|
||||
sum := sha256.Sum256(data)
|
||||
@ -905,8 +905,10 @@ func (r *Registry) PluginDir() string {
|
||||
}
|
||||
|
||||
func (r *Registry) tryDynamic(plgDir, name string, config map[string]interface{}) (sdk.Plugin, error) {
|
||||
// 按 manifest entry 分派到对应加载通道(外部插件多进程化:.so/.dll 与 .bin 双通道共存)。
|
||||
// 这使迁移可逐插件推进、随时回退——把 entry 改回 plugin.so 即回到旧通道。
|
||||
// 按 manifest entry 分派加载通道。
|
||||
//
|
||||
// C ABI 通道(.so/.dll/.dylib)已整体删除:外部插件统一走子进程,
|
||||
// 三套独立 ABI 实现收敛为单一 RPC 实现(§9.2)。
|
||||
if detectEntryKind(plgDir) == entryProc {
|
||||
plg, err := r.loadProc(plgDir, name, config)
|
||||
if err != nil {
|
||||
@ -916,29 +918,21 @@ func (r *Registry) tryDynamic(plgDir, name string, config map[string]interface{}
|
||||
log.Printf("[plugin] %s: 经 proc 通道加载(子进程)", name)
|
||||
return plg, nil
|
||||
}
|
||||
// entry 声明了 plugin.bin 但文件不存在/不可用 → 不隐式回退到 cabi,
|
||||
// 否则"已迁移插件静默跑回旧通道"极难排查。
|
||||
return nil, fmt.Errorf("plugin %s: entry 声明 %s 但未找到可用二进制", name, binEntry)
|
||||
}
|
||||
|
||||
// 既有探测顺序(保持不变):.so → .dll → .lua
|
||||
for _, try := range []struct {
|
||||
name string
|
||||
fn func(string, string, map[string]interface{}) (sdk.Plugin, error)
|
||||
}{
|
||||
{"so", tryLoadSO},
|
||||
{"dll", tryLoadDLL},
|
||||
{"lua", tryLoadLua},
|
||||
} {
|
||||
plg, err := try.fn(plgDir, name, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if plg != nil {
|
||||
return plg, nil
|
||||
}
|
||||
// 旧 .so/.dll 插件给明确错误,不静默跳过。
|
||||
// 静默跳过会让「插件目录在但没加载」看起来像配置问题,
|
||||
// 而实际原因是需要用新 plugindev 重编。
|
||||
if hasLegacyCABIEntry(plgDir) {
|
||||
return nil, fmt.Errorf(
|
||||
"plugin %s: 检测到旧 C ABI 产物(plugin.so/.dll/.dylib)。"+
|
||||
"外部插件已改为子进程模式,请用新版 plugindev 重编产出 %s"+
|
||||
"(业务代码无需修改)", name, binEntry)
|
||||
}
|
||||
return nil, nil
|
||||
|
||||
// Lua 插件仍走解释器
|
||||
return tryLoadLua(plgDir, name, config)
|
||||
}
|
||||
|
||||
func (r *Registry) readConfig(plgDir string) map[string]interface{} {
|
||||
|
||||
Reference in New Issue
Block a user