背景
Woodpecker CI 支持通过附加组件(addon)扩展对非官方 Git 平台的支持。我当时正在开发这样一个附加组件,目的是让 Woodpecker 能够接入阿里云云效。
Woodpecker 的附加组件均基于 go-plugin 实现,官方已定义好需要实现的接口,理论上按照规范进行实现即可。
问题
我发现我的插件无论如何都无法完成初始化,始终报错。起初我怀疑是权限问题——毕竟基于 go-plugin 的插件本质上是一个独立的二进制程序。可我调整了半天可执行文件的权限,问题依旧。
debug 这类插件让人头疼的地方在于,它们必须经由宿主程序启动,而宿主程序提供的启动日志只显示初始化阶段就失败了,之后便再无更多有效信息。中间我也曾猜测是否进程间通过 stdio 通信出了问题,但即便关闭了日志打印,初始化依然失败。
折腾一圈下来,真是没招了,只得求助 LLM…
实践
我一口气把 Woodpecker 的源码、实验环境的 SSH 访问权限,以及插件的源码全丢给了 agent,让它自己翻代码、起服务调试。过了几分钟居然就解决了~
插件由宿主进程启动后,通过 Unix Socket 与主进程进行 RPC 通信,而 go-plugin 默认会把 socket 文件创建在 /tmp 目录下。偏偏我们运行 Woodpecker 的容器里压根没有 /tmp 这个目录,所以插件一启动就似了(
解决方法是:go-plugin 支持通过环境变量 PLUGIN_UNIX_SOCKET_DIR 指定 socket 目录,把它改到 /var/lib/woodpecker 下,一切就正常了。
半天折腾了个寂寞…
后记
好像没多少人遇到过如此刁钻的问题,要不是 LLM 可能我就嘎巴似那了,成为悬案一桩。赞美大鲸鱼!