Reputation: 1173
I always get the following error:
plugin.Open("./plugin"): plugin was built with a different version of package internal/cpu
I did some research about this issue, and it's clearly pointing out that the plugin has been built using different context versions (golang version, or dependencies) than the app loading the plugin.
I ran a minimal test under Docker, using exactly the same Go compiler version and same image to build both the plugin and the app, but I'm still getting the same error.
I appreciate if anyone can point me out where's the failure, or what else should I check to prevent this error.
It's worth mentioning I'm using MacOS, but I'm running the test under Docker containers. Actually, I was able to build and run golang plugins under Docker for third party products.
This is the code:
// 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
Thanks
Upvotes: 4
Views: 1594
Reputation: 18380
You are using the -trimpath
option when building the plugin but not when building the app. Edit the docker file so both builds use -trimpath
(or neither do) then the application will run (well it does on my machine).
My guess as to why this causes the issue is that trimpath
"removes all file system paths from the compiled executable" so when the runtime verifies versions it picks up the difference in the paths.
Here is the dockerfile that works for me (having replicated the issue with the original; the only change is adding -trimpath
to the second 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
Upvotes: 5