moby / moby

The Moby Project - a collaborative project for the container ecosystem to assemble container-based systems

Home Page:https://mobyproject.org/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Setting Ports in a container config no longer compiles

Murf opened this issue · comments

Setting Ports in a container config no longer compiles

package main

import (
	containertypes "github.com/docker/docker/api/types/container"
	"github.com/docker/go-connections/nat"
)

func main() {
	exposedPorts := map[nat.Port]struct{}{"514/udp": {}}
	containerConfig := &containertypes.Config{
		ExposedPorts: exposedPorts,
	}
}

monitor.go:11: cannot use exposedPorts (type map["github.com/docker/go-connections/nat".Port]struct {}) as type map["github.com/docker/docker/vendor/github.com/docker/go-connections/nat".Port]struct {} in field value

ping @LK4D4 I think this could be a Go vendor issue.

This is a Go issue with how vendor/ works.

One way of fixing this would be to provide helper functions in the github.com/docker/docker/api/types/container package. But this is something that's really wrong with Go. I wonder if this could be another area where the new alias proposal could work. cc @cpuguy83 @jessfraz

Any suggestions for this situation ?

I can't use APIs normally…

I think we need to copy the api code into a separate repo periodically, and at least certainly at release.
It will still be painful to use since you'll have to rewrite imports, though.

temporary solution:

you could use go vendor tools such as godep govendor to save the dependency to current project, and then both docker and your code will pointer to the same package in vendor directory.

I guess this would be fine if this code was not intended to be used outside of this repo. But if the client sub-package is intended to be used by other Go projects as a client library (my assumption) then this is currently a blocker.

It's obvious that any type that a public API depends on should be accessible to the consumer as well. I will try @soyking's suggestion for now. For the time being, any third-party Go projects that depend on the latest version of Docker client code that uses the "nat" package cannot be built.

I tried @soyking's suggestion but it won't work because the path to the dependencies will still be different. They will both be under the vendor directory but they will have different parents.

Any other suggestions/workarounds to build a Go client with 1.13?

@ikester Could you please show me the error information? Because it really worked on my project.I just go to the top folder of my project then godep save

@soyking I tried with Glide, which is what we use, and the error was basically the same, because the new package path was <my_project>/vendor/github.com/docker/go-connections/nat instead of github.com/docker/docker/vendor/github.com/docker/go-connections/nat

It was never doing this before we used to have vendor/src/github.com... just fwiw (which is anti-go), we are releasing our prototype dep management tool either later today or tomorrow and it should address this issue (it flattens all deps so there is no nested vendor to consider)

I'm intrigued @jessfraz. Looking forward to it.

Something is definitely broken with this approach.

ah ha... I tried, glide does not remove the nested vendor dir...

@soyking, basically after setting up Glide I get this:

# command-line-arguments
./main.go:205: cannot use ports (type map["bitbucket.org/myorg/myproject/vendor/github.com/docker/go-connect
ions/nat".Port]struct {}) as type "github.com/docker/docker/vendor/github.com/docker/go-connections/nat".PortSet in field
 value
./main.go:272: cannot use portBindings (type map["bitbucket.org/myorg/myproject/vendor/github.com/docker/go-
connections/nat".Port][]"bitbucket.org/myorg/myproject/vendor/github.com/docker/go-connections/nat".PortBind
ing) as type "github.com/docker/docker/vendor/github.com/docker/go-connections/nat".PortMap in field value

With the following imports:

	"github.com/docker/docker/api/types"
	"github.com/docker/docker/api/types/container"
	"github.com/docker/docker/api/types/network"
	"github.com/docker/docker/client"
	"github.com/docker/go-connections/nat"

Thanks. Yes, that works.

But glide update will bring it back. I'll just need to remember to delete that particular vendor dir every time someone runs an update on the dependencies. Not ideal but manageable.

Yes, I was also bit by glide not doing it by default. glide install -v should help.

Thanks. glide install -v (a.k.a. --strip-vendor) does the right thing.

Is there a good way to fix this if you aren't using glide?

I'm also faced with this problem. I'm building a library using these imports and can't have a vendor folder in the library.

Wouldn't it suffice to add a type PortMap nat.PortMap and update the API to use this? It would of course be a breaking change, but it can't be worse than the status quo.

So, what if I don't use vendoring? How would I fix this issue?

Same issue, I don't want to use glide, https://github.com/golang/dep is better

This has been open for a year, any progress? I don't use glide and I tried the recommendation of deleting the vendor folder but that does not seem to work and causes more problems.

Hello guys. I was able to solve this problem by deleting the folder: /src/github.com/docker/docker/vendor/github.com/docker/go-connections

And you need to install github.com/pkg/errors.git

Have a happy new year

I'm currently facing this problem. On my local machine I deleted "/src/github.com/docker/docker/vendor/github.com/docker/go-connections" and installed "github.com/pkg/errors.git" afterwards.
Now I want to build the project with TravisCI, this are some lines of my Dockerfile where I'm installing the dependencies:

RUN go get github.com/docker/docker/client
RUN rm -rf /go/src/github.com/docker/docker/vendor/github.com/docker/go-connections
RUN go get github.com/docker/go-connections/nat
RUN go get github.com/pkg/errors

During the go get github.com/docker/docker/client I'm getting the following error log:

github.com/docker/docker/vendor/github.com/docker/go-connections/sockets
github.com/docker/docker/api/types/volume
github.com/docker/docker/vendor/github.com/pkg/errors
github.com/docker/docker/vendor/golang.org/x/net/context
github.com/docker/docker/vendor/github.com/docker/go-connections/tlsconfig
github.com/docker/docker/vendor/golang.org/x/net/context/ctxhttp
github.com/docker/go-connections/nat
github.com/docker/docker/client
golang.org/x/net/context
github.com/dgrijalva/jwt-go
github.com/auth0/go-jwt-middleware
github.com/[secure]/api_docli/middleware
github.com/[secure]/api_docli/fs
github.com/[secure]/api_docli/helper
github.com/[secure]/api_docli/docker

docker/container.go:61:15: cannot use exposedPorts (type "github.com/docker/go-connections/nat".PortSet) as type "github.com/docker/docker/vendor/github.com/docker/go-connections/nat".PortSet in field value
docker/container.go:68:15: cannot use portBindings (type "github.com/docker/go-connections/nat".PortMap) as type "github.com/docker/docker/vendor/github.com/docker/go-connections/nat".PortMap in field value
The command "eval go get -t -v ./... " failed. Retrying, 2 of 3.

I'm relatively new to golang and at the moment I don't know how to fix this issue.

@cpuguy83 Unfortunately stripping the vendor directory breaks other things. :(

I'm of the impression that libraries aren't supposed to have a vendor directory in the first place?

# github.com/docker/docker/client
../../github.com/docker/docker/client/service_create.go:128:36: cannot use dgst (type "github.com/opencontainers/go-digest".Digest) as type "github.com/docker/distribution/vendor/github.com/opencontainers/go-digest".Digest in argument to reference.WithDigest

@ns-cweber Did you strip everything from vendor? This should all work.

I ran rm -rf $GOPATH/src/github.com/mob/moby/vendor. I eventually got it working by moving to dep and hacking on it, but it wasn't trivial. It seems like a bug that I have to strip vendor in the first place. I've never had to do that with another Go library, and as I mentioned above, I'm under the impression that libraries shouldn't have vendor directories? Maybe the bug is with Go's tooling?

@ns-cweber

The correct path for pulling in this project is github.com/docker/docker, not github.com/moby/moby
This repo contains much much more than a client library.

Yes, the issue is with how go treats vendor directories from dependencies.
Deps always need to have their vendor dirs stripped.

@cpuguy83 Surely we can import go-connection as vendor, but for those non-vendor user, I think type PortMap nat.PortMap is always a good option
quote: #28269 (comment)

@davidkhala I'm not sure I'm following. The issue is go doesn't handle nested vendor dirs correctly and as such they need to be stripped. A type alias like that doesn't fix this.

I fail to see the benefit of using vendor directories in go projects. I'd sooner say the bug is with the decision to use a vendor directory, considering the way go is wired. why wouldn't you just change your go root for a project, sort of like venv in python? go has a built-in package management solution, and while there might be virtues in using "userspace" package management solutions, those solutions shouldn't openly conflict with the default go ecosystem.

that said, glide init && glide install -v did the trick

The vendor directories allow having reproducible builds, and allow auditing the exact code that's used to build. In addition, they prevent problems in situations where upstream go AWOL (think "leftpad"), or even situations where upstreams did an (accidental) force-push or re-tag (we did encounter situations this happened).

is there a solution to this?

Yes, strip the vendor dir.

: cannot use "github.com/xxx/vendor/github.com/docker/go-connections/nat".PortSet literal (type "github.com/xxx/vendor/github.com/docker/go-connections/nat".PortSet) as type "github.com/xxx/vendor/github.com/docker/docker/vendor/github.com/docker/go-connections/nat".PortSet in field value

: cannot use pMap (type "github.com/xxx/vendor/github.com/docker/go-connections/nat".PortMap) as type "github.com/xxx/vendor/github.com/docker/docker/vendor/github.com/docker/go-connections/nat".PortMap in field value

Currently using glide option "--strip-vendor" to avoid this.

commented

It isn't a viable solution just pointing in the direction and saying, to delete vendor/, should be fixed so that the official client API is actually usable.

Hello guys. I was able to solve this problem by deleting the folder: /src/github.com/docker/docker/vendor/github.com/docker/go-connections

And you need to install github.com/pkg/errors.git

Have a happy new year

Thank you, I have solved it. Delete the directory and go get github.com/pkg/errors. The problem is solved.

commented

Hello guys. I was able to solve this problem by deleting the folder: /src/github.com/docker/docker/vendor/github.com/docker/go-connections

And you need to install github.com/pkg/errors.git

Have a happy new year

it's 2020 now, we still have to solve the issue manually...

We vendor code here. You must strip the vendor dirs if you are also vendoring.
Every vendoring tool should support this.

Closing #wontfix b/c there is nothing for us to do here.

Also just as a note, this vendoring issue is not a problem with go modules.

Thanks!😇

commented

We vendor code here. You must strip the vendor dirs if you are also vendoring.

If we are also vendoring? To clarify, you do not need to vendor yourself, as stated in the first reply.
Basically you cannot use the official client without deleting the vendors/ dir, which isn't really that nice a solution.

If you however say that it works with modules, it would be nice with a example of how to do e.g. this fsouza/go-dockerclient#784 :)

Again, we vendor code. There is more in this repo than just the client.
All vendoring tools provide a flag to strip the vendor dir.

It works with go modules naturally, just like every other go package. You do need to specify the version you want since the versioning scheme in this repo is CalVer and modules expect SemVer for automatic version selection.