Contents

5分钟爽文:如何使用用gitlab作为go的依赖仓库

一、前言

本来goproxy.cn是很好用的,但是公司目前只能使用goproxy.baidu.com,这个大部分用的时候都没有问题,但是发现偶尔有几个仓库死活拉不下来,但是换成goproxy.cn确实实在在能拉下来。所以想着为什么不搭建一个公司自己的goproxy呢?在解决这个问题的过程当中,却衍生出了另外一个想法:为什么不用公司自己的gitlab作为我们自己开发的包的仓库呢?本来以为这是个比较麻烦的工作,最后发现还挺简单的,该文就是用来记录整个过程。

二、内容

  1. 准备gitlab环境

    docker运行gitlab镜像,注意必须给docker``4G以上内存,cpu也设置高点,最好4c,这样能操作流畅些,不然可能遇到gitlab页面访问不进去:

    1
    
     docker run -d  -p 443:443 -p 80:80 -p 222:22 --name gitlab --restart always -v ~/config:/etc/gitlab  gitlab/gitlab-ce
    

    然后修改gitlab的配置文件,才能正常访问gitlab页面:

    • 先找到自己主机的ip地址,我这里就是192.168.2.5

    • 修改主机host,添加一条DNS记录:

      1
      
      192.168.2.5 gitlab.com 
      
    • 修改gitlab配置文件

      1
      
      vim ~/config/gitlab.rb
      

      然后修改

      1
      2
      3
      4
      5
      
      external_url 'http://gitlab.com'
      ...
      gitlab_rails['gitlab_shell_ssh_port'] = 222
      ...
      gitlab_rails['gitlab_ssh_host'] = '192.168.2.5'
      
    • 最终重启容器

      1
      
      docker restart gitlab
      
    • 浏览器访问: http://gitlab.com,如果机器性能不够的话,可能要等一会儿才行。当发现页面整个为空,可以换个浏览器访问看看,我就遇着google访问不行,换成safari可以。

    • 你可能进去的是这个页面,发现此时你并不知道密码,如果不是这个页面的话,就不用继续往下看准备gitlab环境了。下面要做的是重置gitlab用户名密码。

      • 首先进入容器:
      1
      
       docker exec -it gitlab /bin/bash
      
      • 然后重置root的密码,这里我设置为admin123
       1
       2
       3
       4
       5
       6
       7
       8
       9
      10
      11
      12
      13
      14
      15
      16
      
      # gitlab-rails console
        --------------------------------------------------------------------------------
         Ruby:         ruby 2.7.2p137 (2020-10-01 revision 5445e04352) [x86_64-linux]
         GitLab:       14.0.2 (bac4ee4a9e2) FOSS
         GitLab Shell: 13.19.0
         PostgreSQL:   12.6
         Loading production environment (Rails 6.1.3.2)
       --------------------------------------------------------------------------------
       irb(main):001:0>u= User.where(id: 1).first 
       => #<User id:1 @root>
       irb(main):001:0>u.password='admin123'
       => "admin123"
       irb(main):001:0>u.save!
       Enqueued ActionMailer::DeliveryJob (Job ID: 99118288-b58b-4d52-94c1-28979bcb63e8) to Sidekiq(mailers) with arguments: "DeviseMailer", "password_change", "deliver_now", gid://gitlab/User/1
       => true
       irb(main):001:0>quit
      
      • 此时管理员账号的密码已经重新设置了,登录即可。
  2. 然后准备一个在gitlab创建一个库gitlab.com/project_group/dependency_util供演示如何在代码里面获取这个仓库。

    . 首先创建一个group:project_group:

    ./new%20group.png

    权限选择public方便测试。

    . 创建示例仓库dependency_util

    ./new_project.png

    权限选择public方便测试。

    . 然后clone该仓库,先初始化仓库,使用mod:

    1
    2
    
    git clone http://gitlab.com/project_group/dependency_util.git && cd dependency_util
    go mod init gitlab.com/project_group/dependency_utils
    

    根据gomod的规则,包的地址必须是gitlab.com/project_group/dependency_utils,换成其他的都会在后面拉取包会出错。

    继续编辑go代码:

    • 拉取error仓库go get github.com/pkg/error
    • 然后新增文件util.go,编辑代码:
       1
       2
       3
       4
       5
       6
       7
       8
       9
      10
      11
      
      package dependency_utils
      
      import "github.com/pkg/errors"
      
      func IsString(i interface{}) error {
        if _, ok := i.(string); !ok {
          return errors.New("不是string!")
        } else {
          return nil
        }
      }
      
    • 提交代码并打上tag:v0.0.1
    • pushgitlab去。
    • 此时示例的包已经准备好。
  3. 然后测试gitlab仓库托管的go的包。

    如法炮制创建一个项目test-my-proxy,然后用mod初始化项目

    1
    
    go mod init project_group/test-my-proxy
    

    创建一个main.go文件,项目结构如下:

    1
    2
    3
    4
    
    .
    ├── go.mod
    ├── go.sum
    └── main.go
    

    编辑main.go文件如下:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    
    package main
    
    import (
      "encoding/json"
      "fmt"
      "github.com/gin-gonic/gin"
      "io/ioutil"
      "net/http"
      "strings"
      "time"
    )
    import du "gitlab.com/project_group/dependency_util"
    
    func main() {
    
      r := gin.Default()
      r.POST("/validaInt", func(c *gin.Context) {
        var param struct {
          Value interface{} `json:"value"`
        }
        c.BindJSON(&param)
    
        err := du.IsString(param.Value)
        if err != nil {
          c.JSON(500, gin.H{
            "message": err.Error(),
          })
          return
        }
    
        c.JSON(200, gin.H{
          "message": "成功",
        })
        return
      })
      go r.Run()
      timer := time.NewTimer(2 * time.Second)
      select {
      case <-timer.C:
        var params = map[string]interface{}{
          "value": "1",
        }
        bytes, _ := json.Marshal(params)
        response, err := http.Post("http://localhost:8080/validaInt", "application/json", strings.NewReader(string(bytes)))
        if err != nil {
          break
        }
        if err != nil {
          fmt.Println(err)
          break
        }
        bytes, err = ioutil.ReadAll(response.Body)
        if err != nil {
          fmt.Println(err)
          break
        }
        fmt.Println(string(bytes))
        break
      }
    }
    

    此段代码的逻辑就是,启动一个ginserver服务,等2秒后server服务监听了8080端口之后,发送请求到server,注意validaInt这个接口就使用了刚刚我们在gitlab上托管的第三方包gitlab.com/project_group/dependency_util

    此时还没有完成,需要做一下几个操作:

    • 设置https://goproxy.cn是为了在天朝拉取github.com/gin-gonic/gin,设置direct是为了拉取我们托管在自己gitlab的包。
      1
      
      go env -w GOPROXY=https://goproxy.cn,direct
      
    • 关闭GOSUMDB,不让校验我们gitlab的哈希值。
      1
      
      go env -w GOSUMDB=off
      
    • 最后拉取该项目依赖的包
      1
      
      go mod tidy
      
    • 最后执行代码测试是否成功:
      1
      
      go run main.go
      

      结果如下:

       1
       2
       3
       4
       5
       6
       7
       8
       9
      10
      11
      
      [GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
      
      [GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
      - using env:   export GIN_MODE=release
      - using code:  gin.SetMode(gin.ReleaseMode)
      
      [GIN-debug] POST   /validaInt                --> main.main.func1 (3 handlers)
      [GIN-debug] Environment variable PORT is undefined. Using port :8080 by default
      [GIN-debug] Listening and serving HTTP on :8080
      [GIN] 2021/07/07 - 22:21:16 | 200 |      306.48µs |             ::1 | POST     "/validaInt"
      {"message":"成功"}
      
    • 此时查看该项目的go.mod:
      1
      2
      3
      4
      5
      6
      7
      8
      
      module project_group/test-my-proxy
      
      go 1.16
      
      require (
        github.com/gin-gonic/gin v1.7.2
        gitlab.com/project_group/dependency_util v0.0.1
      )
      

      已经把包dependency_util@v0.0.1同步到go.mod中了。

三、总结

上面详细列出了用gitlab作为公司项目的托管,这个是非常有意义的。而且很多公司内网是访问不了外网,这个时候可以像搭建mavennpm代理一样,可以搭建goproxy代理,推荐用github项目https://github.com/goproxy/goproxy.cn

  • 欢迎关注我的微信公众号: https://img-blog.csdnimg.cn/20201213215616541.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTA5MjczNDA=,size_16,color_FFFFFF,t_70