将项目用作 Go 包
- Tier: Free, Premium, Ultimate
- Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated
先决条件:
- 联系管理员启用 GitLab Go 代理。
- 要将子组中的私有项目用作 Go 包,你必须认证 Go 请求。未经认证的 Go 请求会导致
go get失败。对于不在子组中的项目,你不需要认证 Go 请求。
如果你使用无效的 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."[email protected]:".insteadOf "https://gitlab.example.com/"
禁用私有项目的 Go 模块获取
要获取模块或包,Go 使用 以下环境变量:
GOPRIVATEGONOPROXYGONOSUMDB
要禁用获取:
- 禁用
GOPRIVATE:- 要禁用对单个项目的查询,禁用
GOPRIVATE=gitlab.example.com/my/private/project。 - 要禁用对 GitLab.com 上所有项目的查询,禁用
GOPRIVATE=gitlab.example.com。
- 要禁用对单个项目的查询,禁用
- 在
GONOPROXY中禁用代理查询。 - 在
GONOSUMDB中禁用校验和查询。
- 如果模块名称或其前缀在
GOPRIVATE或GONOPROXY中,Go 不会查询模块 代理。 - 如果模块名称或其前缀在
GOPRIVATE或GONOSUMDB中,Go 不会查询 校验和数据库。
为私有子组认证 Git 请求
如果 Go 模块位于私有子组下,例如
gitlab.com/namespace/subgroup/go-module,那么 Git 认证将不起作用。
这是因为 go get 会发起未经认证的请求来发现
仓库路径。
如果不使用 .netrc 文件进行 HTTP 认证,GitLab 会响应
gitlab.com/namespace/subgroup.git,以防止向未认证用户暴露
项目存在的安全风险。
结果,Go 模块无法被下载。
不幸的是,除了 .netrc 之外,Go 不提供任何请求认证方式。
在未来的版本中,Go 可能会添加对任意
认证头的支持。
有关详细信息,请关注 golang/go#26232。
解决方案:在模块名中使用 .git
有一种方法可以跳过 go get 请求并强制 Go 直接使用 Git 认证,
但这需要修改模块名称。来自 Go 文档:
如果模块路径在路径组件的末尾有 VCS 限定符(
.bzr、.fossil、.git、.hg、.svn之一), go 命令将使用该路径限定符之前的所有内容作为仓库 URL。例如,对于模块example.com/foo.git/bar,go 命令会使用 Git 下载example.com/foo.git上的仓库,期望在 bar 子目录中找到该模块。
- 转到私有子组中的 Go 模块的
go.mod。 - 在模块名称中添加
.git。 例如,将module gitlab.com/namespace/subgroup/go-module重命名为module gitlab.com/namespace/subgroup/go-module.git。 - 提交并推送此更改。
- 访问依赖于此模块的 Go 项目并调整它们的
import调用。 例如,import gitlab.com/namespace/subgroup/go-module.git。
进行此更改后,Go 模块应该能被正确获取。
例如,GOPRIVATE=gitlab.com/namespace/* go mod tidy。
从 Geo 从站获取 Go 模块
使用 Geo 来访问包含 Go 模块的 Geo 从站上的 Git 仓库。
你可以使用 SSH 或 HTTP 来访问 Geo 从站服务器。
使用 SSH 访问 Geo 从站服务器
要通过 SSH 访问 Geo 从站服务器:
-
在客户端重新配置 Git,将主站的流量发送到从站:
git config --global url."[email protected]".insteadOf "https://gitlab.example.com" git config --global url."[email protected]".insteadOf "http://gitlab.example.com"- 对于
gitlab.example.com,使用主站域名。 - 对于
gitlab-secondary.example.com,使用从站域名。
- 对于
-
确保客户端已设置为通过 SSH 访问 GitLab 仓库。你可以在主站上测试, GitLab 会将公钥复制到从站。
go get 请求会生成到主 Geo 服务器的 HTTP 流量。当模块
下载开始时,insteadOf 配置会将流量发送到从 Geo 服务器。
使用 HTTP 访问 Geo 从站
你必须使用复制到从站服务器的持久访问令牌。你不能使用 CI/CD 作业令牌通过 HTTP 获取 Go 模块。
要通过 HTTP 访问 Geo 从站服务器:
-
在客户端添加一个 Git
insteadOf重定向:git config --global url."https://gitlab-secondary.example.com".insteadOf "https://gitlab.example.com"- 对于
gitlab.example.com,使用主站域名。 - 对于
gitlab-secondary.example.com,使用从站域名。
- 对于
-
生成一个个人访问令牌并 在客户端的
~/.netrc文件中添加凭据:machine gitlab.example.com login USERNAME password TOKEN machine gitlab-secondary.example.com login USERNAME password TOKEN
go get 请求会生成到主 Geo 服务器的 HTTP 流量。当模块
下载开始时,insteadOf 配置会将流量发送到从 Geo 服务器。