23

Drone 自定义 UI

 3 years ago
source link: https://75.team/post/drone-custom-ui.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

7bQZZb2.png!mobile

Drone 是一款开源的 CI/CD 工具,基于容器提供了强大的插件系统。多年前我有写过 《基于Docker的CI工具——Drone》 中有详细的介绍它的优点。Drone 采用的是 Server/Agent 架构,Server 端用来处理请求派发任务给 Agent,最终在 Agent 上执行任务。

Drone 整体是使用 Golang 写的, drone/drone-ui 是它的前端页面仓库,采用 Vue.js 进行开发(很早之前是使用 React 进行开发的)。前后端分离的项目,比较正常的中间会使用 NGINX 之类的 Web Server 进行桥接,用户通过 Web Server 访问前端页面,然后页面在访问 Web Server 反代后的接口。不过 Drone Server 端直接是使用的 Golang 自己起的服务,而 Golang 又是一种需要编译的语言。为了能让 Server 编译后还是单文件,作者特地写了一款工具 bradrydzewski/togo 用来将静态资源编译成 Golang 代码。编译出来的结果本质就是文件路由和内容的哈希表,可以在 官方仓库 中一窥究竟。

将编译后生成的 Golang 文件提交到仓库之后,就可以在 Server 中使用模块的形式将其加载进来,剩下的就是在 Server 中根据路由获取内容返回了。这种做法在开发上会比较麻烦,不过对使用的人来说倒是方便很多了。不过由于静态资源被编译进了执行文件中,所以我们如果要自定义前端界面的话,就需要按照这个流程重新构建编译 Server 执行文件了。

构建前端模块

首先我们需要针对 drone/drone-ui 原始仓库进行 Fork,在新的仓库中根据你们的需求进行前端代码的修改。在 RADME 中介绍了如何在开发环境中进行开发。如果改动不大的话,可以在每次 Drone 官方发布版本的时候根据上游仓库提交 Pull Request 进行需求合并。执行 npm run build 会在 dist/files 目录生成最终需要的前端静态资源。

前端资源备好之后需要安装 bradrydzewski/togo 将静态资源嵌到 Golang 代码中。如果没有安装 Golang 的话需要先安装 Golang。另外 Golang 的全局 bin 目录需要配置到 PATH 环境变量中,否则编译时会提示找不到该命令。

go get github.com/bradrydzewski/togo
cd dist
go generate dist.go

注: go generate 是利用注释快速执行脚本的一种方式。本质上是执行了 dist.go 文件中的 togo http -package dist -output dist_gen.go 这条命令。

最后将编译生成的 dist_gen.go 文件添加到仓库中提交,完成前端模块的构建。接下来我们需要重新构建 Server 执行文件。

构建执行文件

Server 执行文件的仓库是在 drone/drone ,我们需要找到依赖了 github.com/drone/drone-ui 模块的文件,并将其替换成我们 Fork 的新仓库地址 xxx.com/xxx/drone-ui 。主要有 ./handler/web/{logout,pages,web}.go 三个文件需要被替换。

go get -v -insecure xxx.com/xxx/drone-ui
sed -i '' 's/github.com\/drone\/drone-ui/xxx.com\/xxx\/drone-ui/' ./handler/web/{logout,pages,web}.go

注:针对这种场景,Golang 官方的模块管理中其实是支持 replace 方式用来将 A 模块替换成 B 模块的,不过我当时没有实验成功,就还是使用了 sed 的方式。

go mod edit -replace=github.com/drone/drone-ui=xxx.com/xxx/drone-ui

之后我们就可以执行 go build 对其进行构建了。我们并没有对该项目进行修改,只是针对它依赖的前端模块进行处理。所以我的想法是当 drone-ui 仓库发生变更的之后,执行 CI 流水线将 Server 仓库克隆下来修改后执行镜像构建并上传到镜像仓库中。

CI 执行当然是选择 Drone 啦,用 Drone 去构建 Drone 听起来就很酷!默认 Drone 会把当前仓库克隆下来,但实际上我们不需要克隆当前仓库,当前仓库是被主仓库依赖的模块。我们真正需要下载的是 drone/drone 主仓库。

clone: 
  disable: true

steps:
- name: clone
  image: alpine/git
  commands:
  - git clone https://github.com/drone/drone.git .
  - git checkout ${DRONE_TAG}

trigger:
  event:
  -tag

在 Drone 的配置中,设置 disable: false 即可实现不克隆当前仓库。然后自己在单独增加 git clone 的步骤。我们将仓库克隆到当前目录中,并根据当前 git tag 的版本号切换 Server 仓库的版本。这样保证最后编译出来的镜像同版本号和上游不会有其它差异。

- name: build
  image: golang:1.14.4
  commands:
  - go get -v -insecure xxx.com/xxx/drone-ui
  - sed -i '' 's/github.com\\/drone\\/drone-ui/xxx.com\\/xxx\\/drone-ui/' ./handler/web/{logout,pages,web}.go
  - sh scripts/build.sh
  environment:
    GOARCH: amd64
    GOOS: linux

接下来这段构建命令除了增加前端模块依赖替换之外,其它的都是从上游 Server 仓库 中搬运过来的。上游构建中还有 ARM, ARM64 架构版本的构建,由于我这里并不需要,就不增加构建时间了。

之后我们再像官方一样,增加 Docker 镜像构建上传的步骤即可完成最终镜像的创建。使用的时候使用该镜像即可。

后记

同样是使用 Drone 搭建,官方针对 Github 搭建的 https://cloud.drone.io 在未登录的情况下还会自带一个登录页。原理是 Server 服务在 pages.go 中判断接入域名为 "cloud.drone.io" 的话会展示位于 handler/web/landingpage/index.html 的静态页。如果有门户页的需求的话可以针对这些文件进行对应的修改。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK