无法打开 Go 插件

Rod*_*o.C 4 go docker

我总是收到以下错误:

plugin.Open("./plugin"): plugin was built with a different version of package internal/cpu
Run Code Online (Sandbox Code Playgroud)

我对这个问题做了一些研究,它清楚地指出该插件是使用与加载插件的应用程序不同的上下文版本(golang 版本或依赖项)构建的。

我在 Docker 下运行了一个最小的测试,使用完全相同的 Go 编译器版本和相同的映像来构建插件和应用程序,但我仍然遇到相同的错误。

如果有人能指出故障出在哪里,或者我还应该检查哪些内容来防止出现此错误,我将不胜感激。

值得一提的是,我使用的是 MacOS,但我是在 Docker 容器下运行测试。实际上,我能够在 Docker 下为第三方产品构建和运行 golang 插件。

这是代码:

// main.go

package main

import (
    "fmt"
    "plugin"
)

func main() {
    path := "./plugin.so"
    p, err := plugin.Open(path)
    if err != nil {
        fmt.Printf("unable to load plugin at %s.\n%v", path, err)
    }

    symbol, err := p.Lookup("Create")
    if err != nil {
        fmt.Printf("unable to find Create() function in plugin %s.\n%v", path, err)
    }

    createMethod, ok := symbol.(func()interface{})
    if !ok {
        fmt.Printf("Create is not a function in plugin %s", path)
    }
    createMethod()
}
Run Code Online (Sandbox Code Playgroud)
// plugin.go

package main

func Create() interface{} {
    return nil
}
Run Code Online (Sandbox Code Playgroud)
//Dockerfile

FROM golang:1.13.5 as pluginBuilder

WORKDIR /app

COPY . .

RUN go build --buildmode=plugin --trimpath -o /plugin.so plugin.go

FROM golang:1.13.5 as serverBuilder
WORKDIR /app

COPY . .

RUN go build -o /server main.go

FROM debian:stable AS server

WORKDIR /app
COPY --from=pluginBuilder /plugin.so .
COPY --from=serverBuilder /server .

RUN /app/server
Run Code Online (Sandbox Code Playgroud)

谢谢

Bri*_*its 5

-trimpath您在构建插件时使用该选项,但在构建应用程序时不使用该选项。编辑 docker 文件,以便两个构建都使用-trimpath(或都不使用),然后应用程序将运行(在我的机器上也是如此)。

我对这导致问题的原因的猜测是trimpath“从编译的可执行文件中删除所有文件系统路径”,因此当运行时验证版本时,它会发现路径中的差异。

这是适合我的 dockerfile(已复制原始问题;唯一的更改是添加-trimpath到第二个go build):

FROM golang:1.13.5 as pluginBuilder

WORKDIR /app

COPY . .

RUN go build --buildmode=plugin --trimpath -o /plugin.so plugin.go

FROM golang:1.13.5 as serverBuilder
WORKDIR /app

COPY . .

RUN go build --trimpath -o /server main.go

FROM debian:stable AS server

WORKDIR /app
COPY --from=pluginBuilder /plugin.so .
COPY --from=serverBuilder /server .

RUN /app/server
Run Code Online (Sandbox Code Playgroud)