티스토리 뷰

IT/GOLANG

[Issue] Go Module can not find a package

트래이닝맨 2021. 2. 4. 03:44
728x90
반응형

Today, I am going to share a Go Module issue and show you why and how to solve it.

 

This issue happened when I tried to build isv-cli binary that is based on openshift oc cli

 

The First Half

How can I use oc module?

Simple! Import any of oc packages like the following:

import (
	....
	"github.com/openshift/oc/pkg/cli/admin/mustgather"
	....
)

Then go module will update go.mod file and will download them on behalf of me.

 

Let's see go.mod

..
required (
  ..
	github.com/openshift/oc v4.2.0-alpha.0+incompatible
  ..
)

 

What does the version mean and why this version is selected?

 

For the first question, This blog is perfect so read it.

 

What about the second question? If you didn't specify the version, it will try to use the latest version and the latest version is based on tag started with vX.X.X. As you see below, there are 2 tag versions for go mod, and v4.2.0-alpha.0 is the higher so this version is selected.

 

OK after dependencies are updated, try to go run. Unfortunately, I hit this error. 

 

Error messages

github.com/jooho/isv-cli/pkg/cli imports
github.com/openshift/oc/pkg/helpers/cmd imports
k8s.io/kubernetes/pkg/kubectl/util/templates: 
    module k8s.io/kubernetes@latest found (v1.20.2, replaced by github.com/openshift/kubernetes@v1.20.0), 
    but does not contain package k8s.io/kubernetes/pkg/kubectl/util/templates

 

What does this error message mean?

Literally, k8s.io/kubernetes module does not have the package k8s.io/kubernetes/pkg/kubectl/util/templates. But the most curious part is WHY?

The module is the KUBERNETES repo so it should have every packages, NO?

 

Root Cause

While after i research this issue, I found "Referring Kuberentes is not the right way now so Kubernetes module is separated into several modules." So, the package in the error messages should be in the kubectl repo "k8s.io/kubectl".

 

Ok, it sounds like I need to add k8s.io/kubectl to go.mod to solve the issue. However, the issue was not solved after adding the module.

 

Why?!

It is because that the oc module v4.2.0-alpha version refer k8s.io/kubernetes/pkg/kubectl/util/templates instead of k8s.io/kubectl/pkg/util/templates. That's why even though I add the right module, still the oc module is not using it.

 

So what should I do?

I decided to check if which version of oc module referring `k8s.io/kubectl`. Then, I found the release 4.7 branch is using it so I think I can use it.

 

The next question is how I can use the release-4.7 branch instead of v4.2.0-alpha.0 


Second Half

In order to solve this issue, you should know what is pseudo-version of the module.

pseudo-version: A version that encodes a revision identifier (such as a Git commit hash) and a timestamp 
               from a version control system. For example, v0.0.0-20191109021931-daa7c04131f5. Used for compatibility 
               with non-module repositories and in other situations when a tagged version is not available.

Long story to short, pseudo-version is auto-generated by go mod for the repository branch that does not match to any tags. This is exactly our situation.

 

How to find a pseudo-version of the specific branch in the module?

 

Refer go doc ($ go help modules)

For example, these commands are all valid:

    go get github.com/gorilla/mux@latest    # same (@latest is default for 'go get')
    go get github.com/gorilla/mux@v1.6.2    # records v1.6.2
    go get github.com/gorilla/mux@e3702bed2 # records v1.6.2
    go get github.com/gorilla/mux@c856192   # records v0.0.0-20180517173623-c85619274f5d
    go get github.com/gorilla/mux@master    # records current meaning of master

Some StackOverflow pages show how to generate the pseudo version manually BUT that is not necessary.

 

The right and easy way to know the pseudo-version of the master branch of oc repository is this.

go get github.com/openshift/oc@master

It should show you the pseudo-version but in my case, guess what?! Error again

go get github.com/openshift/oc@master
go: cannot use path@version syntax in GOPATH mode

What is the "GOPATH MODE"? 

Go 1.13 Release Notes uses term “GOPATH mode” (as being opposite to the “modules mode”)

OK, I didn't know that I still use GOPATH mode even though I fully use the go module. :(

 

So what's next?

I should enable GOMODULE mode!

GO111MODULE=on go get github.com/openshift/oc@master

go: downloading github.com/openshift/oc v0.0.0-alpha.0.0.20210119130517-6f8f260853ad
go: github.com/openshift/oc master => v0.0.0-alpha.0.0.20210119130517-6f8f260853ad

Yay! It works! .......................................................no another error occurred :(

go: downloading github.com/openshift/oc v0.0.0-alpha.0.0.20210119130517-6f8f260853ad
go: github.com/openshift/oc master => v0.0.0-alpha.0.0.20210119130517-6f8f260853ad
go get: github.com/openshift/oc@v0.0.0-alpha.0.0.20210119130517-6f8f260853ad requires
  github.com/apcera/gssapi@v0.0.0-00010101000000-000000000000:
    invalid version: git fetch -f origin refs/heads/*:refs/heads/* refs/tags/*:refs/tags/*
    in /home/jooho/dev/lang/gopath/pkg/mod/cache/vcs/7e22c68b7feb: exit status 128:

But now I understand what the issue is. This is also dependency issue that oc@master repo used. In this case, it is github.com/apcera/gssapi but actually, openshift repo has a forked repo of the gssapi repo (github.com/openshift/gssapi)

 

So we should know the pseudo version of the master branch of openshift/gssapi as well :)

 

How?

Like above oc@master.

 GO111MODULE=on go get github.com/openshift/gssapi@master
 go: downloading github.com/openshift/gssapi v0.0.0-20161010215902-5fb4217df13b
 go: github.com/openshift/gssapi master => v0.0.0-20161010215902-5fb4217df13b

The final go.mod !



require (
 ...
 github.com/openshift/oc v4.2.0-alpha.0+incompatible
 ...
)

replace (
  github.com/openshift/oc v4.2.0-alpha.0+incompatible => github.com/openshift/oc v0.0.0-20210119130517-6f8f260853ad
  github.com/apcera/gssapi => github.com/openshift/gssapi v0.0.0-20161010215902-5fb4217df13b
  github.com/containers/image => github.com/openshift/containers-image v0.0.0-20190116145627-8841ed7cc6ed
 )

 

Conclusion

Golang module is a new great feature but still, there are a lot of projects that do not use the go module. In order to support GOPATH mode, the pseudo version is necessary. When you try to import other modules and meet this kind of issue, you should check the package is really in the module version. If not, you should check the latest version or branch. After you find the right module version then you can replace the required module with a specific version.

 

Dependency issue is a common issue in every development language so accept this challenge and understand how to solve it. Then move forward!

 

I hope this blog is useful for many of gophers.!

 

 

반응형

'IT > GOLANG' 카테고리의 다른 글

Kubernetes development for beginners  (0) 2021.02.12
Go를 시작하는 사람들을 위한 Module 이야기  (0) 2021.02.04
댓글
250x250
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함