本文将介绍 Go mod 如何通过 SSH 协议使用私有 Git 仓库中的模块


1. 测试环境说明


2. 搭建用于测试的 Git 服务

说明:

  1. 如果有 Gitlab 等 Git 服务器,可以略过该步骤
  2. 务必将公钥添加到 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

3. 快速入门

说明:

  1. 该示例使用的私有化模块名称为 go.timd.cn/private-module-test

3.1. 设置环境变量

# 多个域名之间用“,”分割,域名中可以使用通配符,比如 *.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"

3.2. 处理 go-get=1 请求

go get 在下载模块前,先发送一个请求,URL 为模块带上协议头和参数(go-get=1),比如 https://k8s.io/client-go。GO 默认发送 HTTPS 请求,如果服务器想用 HTTP 协议,那么可以设置环境变量 GOINSECUREgo 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>

3.2.1. 安装 Nginx

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>

3.3. 创建测试模块

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

3.4. 创建测试项目

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

参考文档