本文将介绍 Go mod 如何通过 SSH 协议使用私有 Git 仓库中的模块
说明:
- 如果有 Gitlab 等 Git 服务器,可以略过该步骤
- 务必将公钥添加到 Git 服务器
参考 http://timd.cn/git/#git-server-1 搭建用于测试的 Git 服务。
对于 Ubuntu 操作系统,将第 1 步中的 yum
命令,替换为:
sudo apt update
sudo apt install expat libexpat1 libexpat1-dev libcurl4 curl zlib1g zlib1g-dev perl gettext openssl libssl-dev
说明:
- 该示例使用的私有化模块名称为
go.timd.cn/private-module-test
# 多个域名之间用“,”分割,域名中可以使用通配符,比如 *.timd.cn
go env -w GONOPROXY="*.timd.cn"
go env -w GONOSUMDB="*.timd.cn"
# 相当于同时设置前面两个环境变量
go env -w GOPRIVATE="*.timd.cn"
go env -w GOINSECURE="*.timd.cn"
go-get=1
请求go get
在下载模块前,先发送一个请求,URL 为模块带上协议头和参数(go-get=1
),比如 https://k8s.io/client-go
。GO 默认发送 HTTPS 请求,如果服务器想用 HTTP 协议,那么可以设置环境变量 GOINSECURE
。go get
期望服务端返回模块的相应信息,帮助 go get
进一步操作。比如下面是 https://k8s.io/client-go?go-get=1
的响应:
<html><head>
<meta name="go-import"
content="k8s.io/client-go
git https://github.com/kubernetes/client-go">
<meta name="go-source"
content="k8s.io/client-go
https://github.com/kubernetes/client-go
https://github.com/kubernetes/client-go/tree/master{/dir}
https://github.com/kubernetes/client-go/blob/master{/dir}/{file}#L{line}">
</head></html>
apt install -y nginx
修改 Nginx 配置文件,在其中添加:
server {
listen 80;
server_name *.timd.cn;
if ($args ~* "^go-get=1") {
set $condition goget;
}
if ($uri ~ "/([^/]+)") {
set $condition "${condition}path";
}
if ($condition = "gogetpath") {
return 200 "<html><head><meta name=\"go-import\" content=\"go.timd.cn/$1 git ssh://git@192.168.56.203:/home/git/git-repository/$1.git\"></head></html>";
}
return 403 "forbidden";
}
修改 hosts 文件:
127.0.0.1 go.timd.cn
测试:
# curl -w '\n' go.timd.cn/test?go-get=1
<html><head><meta name="go-import" content="go.timd.cn/dao git ssh://git@192.168.56.203:/home/git/git-repository/test.git"></head></html>
sudo git init --bare ~git/git-repository/private-module-test.git
sudo chown -R git:git ~git/git-repository/
git clone git@127.0.0.1:/home/git/git-repository/private-module-test.git
cd private-module-test/
go mod init go.timd.cn/private-module-test
cat >test.go <<EOF
package private_module_test
func Callme() {
println("private_module_test called")
}
EOF
git add .
git commit -a -m "init"
git push
git tag v1.0.0 master
git push origin v1.0.0
mkdir test
cd test/
go mod init test
go get go.timd.cn/private-module-test@v1.0.0
# 如果遇到错误 Host key verification failed,那么可以 git clone 仓库,将密钥添加到 known_hosts
cat >main.go <<EOF
package main
import test "go.timd.cn/private-module-test"
func main() {
test.Callme()
}
EOF
go run main.go