controller-tools: controller-gen doesn't accept -mod=vendor, downloads source if it can't find the module cache
I’ve been trying to vendor a project using kube-builder and controller-gen and build it in our CI system.
However I noticed a pretty significant increase in build-time and when I investigated I discovered that each time I exec controller-gen in a container, if it can’t find a populated go package source cache it fetches every dependency from the go.mod / go.sum.
There doesn’t appear to be any way to tell controller-gen to use the vendor folder, unless I’ve missed something?
This seems to hold true for:
controller-gen object:headerFile=./hack/boilerplate.go.txt paths=./api/...
and
controller-gen rbac:roleName=manager-role webhook paths="./..." output:crd:artifacts:config=config/crd/bases
Which correspond to the generate and manifests targets in the kube-builder Makefile respectively.
For example, inside a docker container:
# du -h /go/pkg/
4.0K /go/pkg
# controller-gen object:headerFile=./hack/boilerplate.go.txt paths=./api/...
# du -sh /go/pkg/
196M /go/pkg/
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Reactions: 2
- Comments: 18 (4 by maintainers)
I can confirm that this is still an issue. We used kubebuilder to seed our controller as well, and we use vendored builds, too. Running controller-gen inside an environment without internet access fails because it cannot gather information about dependencies.
As deep as we were able to dig in, the
LoadRoots
andLoadRootsWithConfig
functions in thepkg/loader
package (specifically this tools API call here are responsible for the failure to obtain information without internet access. We’re on controller-gen v0.2.5, but the code in question has not changed much since that tag.Possible Fix
We posit that controller-gen should have a way of specifying vendor mode (and any other build options that need to be passed on to go tools by the controller-gen user).
That could be in the form of a separate command-line argument (e.g.
+buildArgs:=[]string
) or as an option on the+paths
arg (e.g.+paths="-mod=vendor; ./..."
), and if present, can be passed to thepackages.Load
(and any other tools API calls) as(*pacakges.Config).BuildFlags
field. But more discussion needs to take place on if/how exactly to handle that.Workaround
However, if and until that happens, there is an easy workaround. There is currently an environment variable
GOFLAGS
that can contain anything extra that needs to be passed to all go tools. The current go/x/tools APIs honor that variable. (Someone else may be able to comment on compatibility with past versions).We worked around our issue like:
but it can also be set in the Makefile, or anything else that would make that environment variable available to controller-gen when it executes.
We are running our Go builds in airtight build environment which has vendored dependencies and
controller-gen
fails as it tries to retrieve dependencies from the network which is locked down.controller-gen
should have an option to rungo list
and other Go commands with-mod=vendor