当尝试导入时,go get是否会添加文件夹?

huangapple go评论79阅读模式
英文:

go get is adding folders when attempting to import?

问题

我们有两个与这个问题相关的仓库:

gitlab.com/company/product/team/service
gitlab.com/company/product/team/api

它们都有 go.mod 文件。api 仓库非常简单。它包含了十几个 TypeScript 文件,通过一个过程生成镜像 Go 结构体。我们在集成和单元测试中使用这些结构体,类似于样式表,以便测试来自 service 的响应结构。Api 没有任何导入,没有 fmt、time,什么都没有。这是 api 的 go.mod 文件:

module gitlab.com/company/product/team/api/v2

go 1.16

其 master 分支上的最新标签是 v2.68.0。service 的 go.mod 文件中有以下对 api 的 require 行:

require (
  ...
  gitlab.com/company/product/team/api/v2 v2.68.0
  ...
)

在我的机器上工作正常。当我运行 go getgo mod tidygo mod downloadgo mod vendor 等命令时,会下载正确的版本。但在 Docker 中不是这样。为了与我们的 CI/CD 流水线配合工作,并最终在 k8 中部署,我们构建一个 Docker 镜像来存放代码。在 service 的 Dockerfile 中的 RUN go mod vendor 在尝试导入 api 时给我们报错(在此处添加 verbose 标志不会提供更多细节):

> go: gitlab.com/company/product/team/api/v2@v2.68.0: 读取 gitlab.com/company/product/team/api/team/api/go.mod 时的 revision team/api/v2.68.0: 未知的 revision team/api/v2.68.0

请注意 ../team/api/team/api/go.mod URL 中重复的文件夹。

我们的 Dockerfile 中加载了一个已在 gitlab 注册的 SSH 密钥,~/.ssh/known_hosts 中有必要的条目,~/.netrc 文件中有一个具有 read_api 权限的 gitlab 访问令牌,GOPRIVATE=gitlab.com/company/*GO111MODULE=on,当运行 go mod vendor 时,它对我们的其他 gitlab.com/company/product/team/* 导入没有问题。这与我的本地机器上的情况相同,其中 go get 是正常工作的。

为什么在尝试导入时,go mod vendor 会决定重复文件夹,而其他情况下却没有问题?

英文:

We have 2 repos relevant to this question:

gitlab.com/company/product/team/service
gitlab.com/company/product/team/api

They both have go.mod files. The api repo is dead simple. It contains a dozen or so typescript files that go through a process to generate mirror image Go structs. We use these in integration and unit tests sort of like a stylesheet so we can test the structure of responses from service. Api has 0 imports. No fmt, time, nothing. Here's api's go.mod file:

module gitlab.com/company/product/team/api/v2

go 1.16

The latest tag on its master branch is v2.68.0. Service's go.mod has this require line for api:

require (
  ...
  gitlab.com/company/product/team/api/v2 v2.68.0
  ...
)

And it Works on My Machine(TM). When I run go get, go mod tidy, go mod download, go mod vendor, etc, the correct version gets downloaded. Not so in docker. To work with our CI/CD pipeline and eventually get deployed in k8, we build a docker image to house the code. The RUN go mod vendor in service's Dockerfile is giving us an error when it tries to import the api (adding a verbose flag does not result in more details here):

> go: gitlab.com/company/product/team/api/v2@v2.68.0: reading gitlab.com/company/product/team/api/team/api/go.mod at revision team/api/v2.68.0: unknown revision team/api/v2.68.0

Note the repeated folders in the ../team/api/team/api/go.mod url.

Our Dockerfile is loaded with an SSH key that's registered with gitlab, the necessary entries into ~/.ssh/known_hosts are present, there's a ~/.netrc file with a gitlab access token that has the read_api permission, GOPRIVATE=gitlab.com/company/*, GO111MODULE=on, and when it runs go mod vendor it doesn't have issues with any of the rest of our gitlab.com/company/product/team/* imports. These mirror my local machine where go get works.

Why, for this one repo, would go mod vendor decide to repeat folders when attempting to import?

答案1

得分: 1

原来答案并不是SO用户能够深入了解的。我们在服务的Dockerfile中使用的.netrc令牌是一个只在服务项目中有效的访问令牌。它是通过打开服务存储库的设置并在那里创建访问令牌来创建的,而不是使用具有对所有必要存储库的访问权限的服务帐户。当go使用它来访问API时,它不再授予访问权限,并且go在询问gitlab时出现问题,因为gitlab错误地声称URL中的所有文件夹都是存储库的文件夹。如果你在gitlab中使用子组并运行go get,你就知道我在说什么。

它在我的机器上工作是因为我的.netrc文件中有我的令牌,并且我有足够的访问权限,所以这不是问题。

我们通过更新Dockerfile中的.netrc文件,使用一个由具有对所有相关存储库的API访问权限的服务帐户生成的令牌来解决了这个问题。

我本来要删除这个问题,但是很少有关于这个问题的资源。

英文:

Turns out the answer isn't anything that SO users would have had much insight into. The .netrc token we have in service's Dockerfile is an access token that only works in the service project. It was created by opening the settings of the service repo and creating the access token there instead of using a service account that has access to all the necessary repos. When go uses it to access the api it no longer grants access and go has issues asking gitlab which folder in the URL is the RepoRoot because gitlab erroneously claims all folders in the path are a repo. If you're using subgroups in gitlab and running go get, you know what I'm talking about.

It worked on my machine because my .netrc has my token and I have enough access to not be an issue.

We fixed it by updating the .netrc file in the dockerfile to use a token generated by a service account that has api access to all relevant repos.

I was about to delete the question, but finding resources talking about this problem are few and far between.

huangapple
  • 本文由 发表于 2021年7月31日 00:01:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/68593946.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定