【问题标题】:Unable to open a Go plugin无法打开 Go 插件
【发布时间】:2021-08-10 17:24:21
【问题描述】:

我总是收到以下错误:

plugin.Open("./plugin"): plugin was built with a different version of package internal/cpu

我对这个问题做了一些研究,它清楚地指出插件是使用不同的上下文版本(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()
}
// plugin.go

package main

func Create() interface{} {
    return nil
}
//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

谢谢

【问题讨论】:

  • 为服务器和插件使用不同的构建阶段背后的逻辑是什么?
  • @DanielFarrell 使用不同的构建阶段应该不是问题,在构建插件时考虑不同的管道。这是一个示例,其前提是将构建保持在单独的上下文中。在实际场景中,插件将构建在另一个代码库中,因此是不同的 Dockerfile。

标签: docker go


【解决方案1】:

您在构建插件时使用-trimpath 选项,但在构建应用程序时没有。编辑 docker 文件,使两个版本都使用 -trimpath(或两者都不使用),然后应用程序将运行(它在我的机器上运行良好)。

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

这是适用于我的 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

【讨论】:

    猜你喜欢
    • 2011-03-15
    • 1970-01-01
    • 2018-02-23
    • 2019-01-06
    • 2015-07-06
    • 1970-01-01
    • 1970-01-01
    • 2022-08-04
    • 1970-01-01
    相关资源
    最近更新 更多