Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

plugin: not usable on another host using same go version and common dependencies #29055

Open
oszika opened this issue Dec 1, 2018 · 5 comments
Open

Comments

@oszika
Copy link

@oszika oszika commented Dec 1, 2018

What version of Go are you using (go version)?

$ go version
go version go1.11.2 linux/amd64

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

go env ArchLinux host
$ go env
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/oszika/.cache/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/oszika/go"
GOPROXY=""
GORACE=""
GOROOT="/usr/lib/go"
GOTMPDIR=""
GOTOOLDIR="/usr/lib/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/home/oszika/go/src/plugin/main/go.mod"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build912174408=/tmp/go-build -gno-record-gcc-switches"
go env Docker golang:1.11.2
$ go env
GOARCH="amd64"
GOBIN=""
GOCACHE="/root/.cache/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/go"
GOPROXY=""
GORACE=""
GOROOT="/usr/local/go"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/plugins/main/go.mod"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build407785075=/tmp/go-build -gno-record-gcc-switches"

What did you do?

I try to build plugin on host and use it on container. Versions of common dependencies are defined in go.mod.

p1/go.mod

module p1

require gopkg.in/yaml.v2 v2.2.1

p1/p1.go

package main

import (
        "fmt"

        yaml "gopkg.in/yaml.v2"
)

var e = yaml.Encoder{}

func init() { fmt.Printf("p1: Type: %T\n", e) }

func main() {}

main/go.mod

module main

require (
        gopkg.in/yaml.v2 v2.2.1
        p1 v0.0.0 // indirect
)

replace p1 => ../p1

main/main.go

package main

import (
        "fmt"
        "plugin"

        yaml "gopkg.in/yaml.v2"
)

var e = yaml.Encoder{}

func init() { fmt.Printf("main: Type: %T\n", e) }

func main() {
        if _, err := plugin.Open("p1.so"); err != nil {
                panic(err)
        }
}

On host :

.../main $ go build -buildmode=plugin p1

On docker

.../main $ go run main.go

What did you expect to see?

Like on host:

.../main $ go run main.go
main: Type: yaml.Encoder
p1: Type: yaml.Encode

What did you see instead?

.../main $ go run main.go 
go: finding gopkg.in/yaml.v2 v2.2.1
go: finding gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405
go: downloading gopkg.in/yaml.v2 v2.2.1
main: Type: yaml.Encoder
panic: plugin.Open("p1"): plugin was built with a different version of package gopkg.in/yaml.v2

goroutine 1 [running]:
main.main()
	/plugins/main/main.go:16 +0x63
exit status 2

Except the GOROOT, the package built seems the same:

On host:

#
# gopkg.in/yaml.v2
#

mkdir -p $WORK/b026/
cat >$WORK/b026/importcfg << 'EOF' # internal
# import config
packagefile bytes=/usr/lib/go/pkg/linux_amd64/bytes.a
packagefile encoding=/usr/lib/go/pkg/linux_amd64/encoding.a
packagefile encoding/base64=/usr/lib/go/pkg/linux_amd64/encoding/base64.a
packagefile errors=/usr/lib/go/pkg/linux_amd64/errors.a
packagefile fmt=/usr/lib/go/pkg/linux_amd64/fmt.a
packagefile io=/usr/lib/go/pkg/linux_amd64/io.a
packagefile math=/usr/lib/go/pkg/linux_amd64/math.a
packagefile reflect=/usr/lib/go/pkg/linux_amd64/reflect.a
packagefile regexp=/usr/lib/go/pkg/linux_amd64/regexp.a
packagefile sort=/usr/lib/go/pkg/linux_amd64/sort.a
packagefile strconv=/usr/lib/go/pkg/linux_amd64/strconv.a
packagefile strings=/usr/lib/go/pkg/linux_amd64/strings.a
packagefile sync=/usr/lib/go/pkg/linux_amd64/sync.a
packagefile time=/usr/lib/go/pkg/linux_amd64/time.a
packagefile unicode=/usr/lib/go/pkg/linux_amd64/unicode.a
packagefile unicode/utf8=/usr/lib/go/pkg/linux_amd64/unicode/utf8.a
EOF
cd /home/oszika/go/pkg/mod/gopkg.in/yaml.v2@v2.2.1
/usr/lib/go/pkg/tool/linux_amd64/compile -o $WORK/b026/_pkg_.a -trimpath $WORK/b026 -p gopkg.in/yaml.v2 -complete -buildid -TBoSu6rbJldl0TAHMGq/-TBoSu6rbJldl0TAHMGq -goversion go1.11.2 -D "" -importcfg $WORK/b026/importcfg -pack -c=4 ./apic.go ./decode.go ./emitterc.go ./encode.go ./parserc.go ./readerc.go ./resolve.go ./scannerc.go ./sorter.go ./writerc.go ./yaml.go ./yamlh.go ./yamlprivateh.go
/usr/lib/go/pkg/tool/linux_amd64/buildid -w $WORK/b026/_pkg_.a # internal

On container:

#
# gopkg.in/yaml.v2
#

mkdir -p $WORK/b026/
cat >$WORK/b026/importcfg << 'EOF' # internal
# import config
packagefile bytes=/usr/local/go/pkg/linux_amd64/bytes.a
packagefile encoding=/usr/local/go/pkg/linux_amd64/encoding.a
packagefile encoding/base64=/usr/local/go/pkg/linux_amd64/encoding/base64.a
packagefile errors=/usr/local/go/pkg/linux_amd64/errors.a
packagefile fmt=/usr/local/go/pkg/linux_amd64/fmt.a
packagefile io=/usr/local/go/pkg/linux_amd64/io.a
packagefile math=/usr/local/go/pkg/linux_amd64/math.a
packagefile reflect=/usr/local/go/pkg/linux_amd64/reflect.a
packagefile regexp=/usr/local/go/pkg/linux_amd64/regexp.a
packagefile sort=/usr/local/go/pkg/linux_amd64/sort.a
packagefile strconv=/usr/local/go/pkg/linux_amd64/strconv.a
packagefile strings=/usr/local/go/pkg/linux_amd64/strings.a
packagefile sync=/usr/local/go/pkg/linux_amd64/sync.a
packagefile time=/usr/local/go/pkg/linux_amd64/time.a
packagefile unicode=/usr/local/go/pkg/linux_amd64/unicode.a
packagefile unicode/utf8=/usr/local/go/pkg/linux_amd64/unicode/utf8.a
EOF
cd /go/pkg/mod/gopkg.in/yaml.v2@v2.2.1
/usr/local/go/pkg/tool/linux_amd64/compile -o $WORK/b026/_pkg_.a -trimpath $WORK/b026 -p gopkg.in/yaml.v2 -complete -buildid Vu3xvoPx_6--pylAg8yB/Vu3xvoPx_6--pylAg8yB -goversion go1.11.2 -D "" -importcfg $WORK/b026/importcfg -pack -c=4 ./apic.go ./decode.go ./emitterc.go ./encode.go ./parserc.go ./readerc.go ./resolve.go ./scannerc.go ./sorter.go ./writerc.go ./yaml.go ./yamlh.go ./yamlprivateh.go
/usr/local/go/pkg/tool/linux_amd64/buildid -w $WORK/b026/_pkg_.a # internal
@oszika oszika changed the title go/cmd: plugin not usable on another host using same go version and common dependencies cmd/go: plugin not usable on another host using same go version and common dependencies Dec 1, 2018
@cherrymui

This comment has been minimized.

Copy link
Contributor

@cherrymui cherrymui commented Dec 1, 2018

Does it work if you don't use module?

Probably related (or dup) to #27751 and #26759.

@oszika

This comment has been minimized.

Copy link
Author

@oszika oszika commented Dec 1, 2018

Without modules, I have the same error:

On host:

$ GO111MODULE=off go get -v -u gopkg.in/yaml.v2
$ GO111MODULE=off go build -buildmode=plugin plugin/p1
.../main $ GO111MODULE=off go run main.go
main: Type: yaml.Encoder
p1: Type: yaml.Encoder

On container:

# GO111MODULE=off go get -v -u gopkg.in/yaml.v2
# GO111MODULE=off go run main.go
main: Type: yaml.Encoder
panic: plugin.Open("p1"): plugin was built with a different version of package gopkg.in/yaml.v2

goroutine 1 [running]:
main.main()
	/go/src/plugins/main/main.go:16 +0x63
exit status 2

I think it's not related to #27751 because the version of gopkg.in/yaml.v2 is the same for "main" and "p1".

About #26759, GOPATH could have an impact using modules?

[Edit: fix mis-typed environment variable]

@agnivade agnivade changed the title cmd/go: plugin not usable on another host using same go version and common dependencies plugin: not usable on another host using same go version and common dependencies Dec 2, 2018
@cherrymui

This comment has been minimized.

Copy link
Contributor

@cherrymui cherrymui commented Dec 3, 2018

# GOMODULE111=off go get -v -u gopkg.in/yaml.v2

The environment variable is mis-typed. Does anything change if you fix that?

I'm not familiar with how modules work, so I may be wrong. My guess is that this issue and the other linked issues have similar underlying reason: it is sensitive to the source code path. With modules, the go command will download the dependencies' source code in a hidden place, which may not be the same across machines. With GOPATH, these paths are more explicit.

@oszika

This comment has been minimized.

Copy link
Author

@oszika oszika commented Dec 3, 2018

Sorry for the error but I confirm that the behavior is the same using GOPATH.

The result of "go list" using modules :

go list -m -json all Archlinux host
$ GO111MODULE=on go list -m -json all                 
go: finding gopkg.in/yaml.v2 v2.2.1
go: finding gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405
{
	"Path": "main",
	"Main": true,
	"Dir": "/home/oszika/go/src/plugin/main",
	"GoMod": "/home/oszika/go/src/plugin/main/go.mod"
}
{
	"Path": "gopkg.in/check.v1",
	"Version": "v0.0.0-20161208181325-20d25e280405",
	"Time": "2016-12-08T18:13:25Z",
	"Indirect": true,
	"GoMod": "/home/oszika/go/pkg/mod/cache/download/gopkg.in/check.v1/@v/v0.0.0-20161208181325-20d25e280405.mod"
}
{
	"Path": "gopkg.in/yaml.v2",
	"Version": "v2.2.1",
	"Time": "2018-03-28T19:50:20Z",
	"GoMod": "/home/oszika/go/pkg/mod/cache/download/gopkg.in/yaml.v2/@v/v2.2.1.mod"
}
{
	"Path": "p1",
	"Version": "v0.0.0",
	"Replace": {
		"Path": "../p1",
		"Dir": "/home/oszika/go/src/plugin/p1"
	},
	"Indirect": true,
	"Dir": "/home/oszika/go/src/plugin/p1",
	"GoMod": "/home/oszika/go/src/plugin/p1/go.mod"
}
go list -m -json all Docker golang:1.11.2 host
root@6b019df88e5d:/go/src/plugin/main# GO111MODULE=on go list -m -json all
go: finding gopkg.in/yaml.v2 v2.2.1
go: finding gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405
{
	"Path": "main",
	"Main": true,
	"Dir": "/go/src/plugin/main",
	"GoMod": "/go/src/plugin/main/go.mod"
}
{
	"Path": "gopkg.in/check.v1",
	"Version": "v0.0.0-20161208181325-20d25e280405",
	"Time": "2016-12-08T18:13:25Z",
	"Indirect": true,
	"GoMod": "/go/pkg/mod/cache/download/gopkg.in/check.v1/@v/v0.0.0-20161208181325-20d25e280405.mod"
}
{
	"Path": "gopkg.in/yaml.v2",
	"Version": "v2.2.1",
	"Time": "2018-03-28T19:50:20Z",
	"GoMod": "/go/pkg/mod/cache/download/gopkg.in/yaml.v2/@v/v2.2.1.mod"
}
{
	"Path": "p1",
	"Version": "v0.0.0",
	"Replace": {
		"Path": "../p1",
		"Dir": "/go/src/plugin/p1"
	},
	"Indirect": true,
	"Dir": "/go/src/plugin/p1",
	"GoMod": "/go/src/plugin/p1/go.mod"
}

I will try to see if the problem occurs using same GOPATH and GOROOT.

@oszika

This comment has been minimized.

Copy link
Author

@oszika oszika commented Dec 3, 2018

@cherrymui you are right, if I define the same GOPATH (using modules or not), it works!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
3 participants
You can’t perform that action at this time.