Search code examples
gogo-modules

Versioned import in go using modules fails


I want my program to use a specific version of client-go, so that it is compatible with the target cluster.

However the following syntax:

import (
    "log"
    "os"
    "path/filepath"

    clientcmd "k8s.io/[email protected]/tools/clientcmd"
)

which I use to achieve to build my client configuration as follows:

    config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)

fails with this error message:

▶ go run main.go
package main imports k8s.io/[email protected]/tools/clientcmd: can only use path@version syntax with 'go get'

How should I state the particular versioned input?


Solution

  • Change your import to

    import "k8s.io/client-go/tools/clientcmd"
    

    And execute the command:

    go get k8s.io/[email protected]
    

    The used versions are recorded in the go.mod file. The above go get will change go.mod to depend on the given version. Note that you could also edit go.mod manually (but it's better to leave it to the go tool). You only need to modify the import path if you're using versions starting or above v2, in which case the major version must be a suffix, e.g.

    import "k8s.io/client-go/tools/clientcmd/v2"
    

    Note:

    After the above go get command, the the go.mod file will be modified to contain a require directive like this:

    k8s.io/client-go v0.0.0-20190708094436-77c08c6b86df // indirect
    

    The reason for this is because go modules require semantic versioning, while kubernetes-1.12.10 is not a semver2 compatible version number. Still, the go tool will resove that this version tags the 77c08c6b86df0af19f718d9a57620c4e9b811d48 commit, and use it in the go.mod file.

    Read more about it here: Go Wiki: Modules: How to Upgrade and Downgrade Dependencies

    Also see: The Go Blog: Go Modules: v2 and Beyond