将项目用作 Go 软件包

  • 在极狐GitLab 17.3 中针对未授权的 go get 请求返回 404 错误。

先决条件:

  • 与您的管理员联系,以启用极狐GitLab Go 代理
  • 要将子群组中的私有项目用作 Go 软件包,您必须认证 Go 请求。未进行身份验证的 Go 请求会导致 go get 失败。您不需要对不在子群组中的项目进行身份验证。

要将项目用作 Go 软件包,请使用 go getgodoc.org 发现请求。您可以使用元标签:

note 如果您使用无效的 HTTP 凭据进行 go get 请求,您将收到 404 错误。您可以在 ~/.netrc(MacOS 和 Linux)或 ~/_netrc(Windows)中找到 HTTP 凭据。

为私有项目认证 Go 请求

先决条件:

  • 您的极狐GitLab 实例必须可以通过 HTTPS 访问。
  • 您必须拥有一个个人访问令牌,其范围为 read_api

要认证 Go 请求,请创建一个包含以下信息的 .netrc 文件:

machine gitlab.example.com
login <gitlab_user_name>
password <personal_access_token>

在 Windows 上,Go 读取 ~/_netrc 而不是 ~/.netrc

go 命令不会通过不安全的连接传输凭据。它对 Go 发出的 HTTPS 请求进行身份验证,但不会对通过 Git 发出的请求进行身份验证。

认证 Git 请求

如果 Go 无法从代理获取模块,它会使用 Git。Git 使用 .netrc 文件对请求进行身份验证,但您可以配置其他身份验证方法。

配置 Git 使用以下身份验证方法之一:

  • 在请求 URL 中嵌入凭据:

    git config --global url."https://${user}:${personal_access_token}@gitlab.example.com".insteadOf "https://gitlab.example.com"
    
  • 使用 SSH 而不是 HTTPS:

    git config --global url."git@gitlab.example.com:".insteadOf "https://gitlab.example.com/"
    

禁用私有项目的 Go 模块获取

获取模块或软件包,Go 使用以下环境变量

  • GOPRIVATE
  • GONOPROXY
  • GONOSUMDB

要禁用拉取:

  1. 禁用 GOPRIVATE
    • 要禁用一个项目的查询,请禁用 GOPRIVATE=gitlab.example.com/my/private/project
    • 要禁用 GitLab.com 上所有项目的查询,请禁用 GOPRIVATE=gitlab.example.com
  2. GONOPROXY 中禁用代理查询。
  3. GONOSUMDB 中禁用校验和查询。
  • 如果模块名称或其前缀在 GOPRIVATEGONOPROXY 中,Go 不会查询模块代理。
  • 如果模块名称或其前缀在 GONOPRIVATEGONOSUMDB 中,Go 不会查询校验和数据库。

为私有子群组认证 Git 请求

如果 Go 模块位于私有子群组中,例如 gitlab.com/namespace/subgroup/go-module,则 Git 身份验证不起作用。如果发生,go get 会发出未经身份验证的请求以发现存储库路径。如果没有使用 .netrc 文件进行 HTTP 身份验证,GitLab 将响应 gitlab.com/namespace/subgroup.git,以防止对未经身份验证的用户公开项目的存在。因此,Go 模块无法下载。

不幸的是,Go 不提供任何请求身份验证方法,除了 .netrc。在将来的版本中,Go 可能会添加对任意身份验证标头的支持。请关注 golang/go#26232 以获取详细信息。

解决方案:在模块名称中使用 .git

有一种方法可以跳过 go get 请求,并强制 Go 直接使用 Git 身份验证,但它需要对模块名称进行修改。

If the module path has a VCS qualifier (one of .bzr, .fossil, .git, .hg, .svn) at the end of a path component, the go command will use everything up to that path qualifier as the repository URL. For example, for the module example.com/foo.git/bar, the go command downloads the repository at example.com/foo.git using git, expecting to find the module in the bar subdirectory.

From Go documentation

  1. 前往私有子群组 Go 模块中的 go.mod
  2. 在模块名称中添加 .git。比如,将 module gitlab.com/namespace/subgroup/go-module 重命名为 module gitlab.com/namespace/subgroup/go-module.git
  3. 提交并推送此更改。
  4. 访问依赖于此模块的 Go 项目,并调整其 import 调用。例如,import gitlab.com/namespace/subgroup/go-module.git

在进行此更改后,Go 模块应正确获取。例如,GOPRIVATE=gitlab.com/namespace/* go mod tidy

从 Geo 次节点站点拉取 Geo 模块

使用 Geo 访问包含 Go 模块的 Git 存储库的 Geo 次节点服务器。

您可以使用 SSH 或 HTTP 访问 Geo 次节点。

使用 SSH 访问 Geo 次节点

要用 SSH 访问 Geo 次节点:

  1. 在客户端上重新配置 Git,以便将流量从主节点发送到次节点:

    git config --global url."git@gitlab-secondary.example.com".insteadOf "https://gitlab.example.com"
    git config --global url."git@gitlab-secondary.example.com".insteadOf "http://gitlab.example.com"
    
    • 对于 gitlab.example.com,使用主站点域名。
    • 对于 gitlab-secondary.example.com,使用次站点域名。
  2. 确保客户端已设置为通过 SSH 访问极狐GitLab 存储库。您可以在主节点上进行测试,GitLab 会将公共密钥复制到次节点。

go get 请求生成到主 Geo 服务器的 HTTP 流量。当模块下载开始时,insteadOf 配置将流量发送到次要 Geo 服务器。

使用 HTTP 访问 Geo 次节点

您必须使用复制到次要节点的持久访问令牌。您不能使用 CI/CD 作业令牌来获取使用 HTTP 的 Go 模块。

要用 HTTP 访问 Geo 次节点:

  1. 在客户端上添加一个 Git insteadOf 重定向:

    git config --global url."https://gitlab-secondary.example.com".insteadOf "https://gitlab.example.com"
    
    • 对于 gitlab.example.com,使用主站点域名。
    • 对于 gitlab-secondary.example.com,使用次要站点域名。
  2. 生成个人访问令牌并在客户端的 ~/.netrc 文件中添加凭据:

    machine gitlab.example.com login USERNAME password TOKEN
    machine gitlab-secondary.example.com login USERNAME password TOKEN
    

go get 请求生成到主 Geo 服务器的 HTTP 流量。当模块下载开始时,insteadOf 配置将流量发送到次要 Geo 服务器。